2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * AIX inode operations
16 #include <afsconfig.h>
17 #include "../afs/param.h"
21 #include "../afs/sysincludes.h" /* Standard vendor system headers */
22 #include "../afs/afsincludes.h" /* Afs-based standard headers */
23 #include "../afs/osi_inode.h"
24 #include "../afs/afs_stats.h" /* statistics stuff */
25 #include "sys/syspest.h"
27 #if !defined(offsetof)
28 #include <stddef.h> /* for definition of offsetof() */
31 extern Simple_lock jfs_icache_lock;
32 #define ICACHE_LOCK() simple_lock(&jfs_icache_lock)
33 #define ICACHE_UNLOCK() simple_unlock(&jfs_icache_lock)
36 * In AIX 4.2.0, the inode member to lock is i_rdwrlock. The inode
37 * structure conditionally contains a member called i_nodelock which we
40 * In AIX 4.2.1 and later, the inode member to lock is i_nodelock, which
41 * was relocated to coincide with the AIX 4.2.0 position of i_rdwrlock.
42 * The AIX 4.2.1 and later inode structure does not contain a field
45 * We use an accident of the system header files to distinguish between
46 * AIX 4.2.0 and AIX 4.2.1 and later. This allows this part of the code
47 * to compile on AIX 4.2.1 and later without introducing a new system
50 * The macro IACTIVITY is 0x0020 on AIX 4.2.0, and 0x0010 on AIX 4.2.1
51 * and later (at least through AIX 4.3.3). If IACTIVITY is undefined,
52 * or has an unknown value, then the system header files are different
53 * than what we've seen and we'll need to take a look at them anyway to
56 * The osi_Assert() statement in igetinode() checks that the lock field
57 * is at an expected offset.
60 #if IACTIVITY == 0x0020 /* in <jfs/inode.h> on AIX 4.2.0 */
61 #define afs_inode_lock i_rdwrlock
64 #if IACTIVITY == 0x0010 /* in <jfs/inode.h> on AIX 4.2.1 and later */
65 #define afs_inode_lock i_nodelock
68 #define IREAD_LOCK(ip) simple_lock(&((ip)->afs_inode_lock))
69 #define IREAD_UNLOCK(ip) simple_unlock(&((ip)->afs_inode_lock))
70 #define IWRITE_LOCK(ip) simple_lock(&((ip)->afs_inode_lock))
71 #define IWRITE_UNLOCK(ip) simple_unlock(&((ip)->afs_inode_lock))
73 #define SYSENT(name, arglist, decls) \
84 if ((rc = setjmpx(&jmpbuf)) == 0) { \
85 rval1 = afs_syscall_ ## name arglist; \
95 return(getuerror() ? -1 : rval1); \
97 afs_syscall_ ## name arglist \
102 * This structure is used to pass information between devtovfs() and
103 * devtovfs_func() via vfs_search().
106 struct devtovfs_args {
112 * If the given vfs matches rock->dev, set rock->ans to vfsp and return
113 * nonzero. Otherwise return zero.
115 * (Returning nonzero causes vfs_search() to terminate the search.)
118 static int devtovfs_func(struct vfs *vfsp, struct devtovfs_args *rock)
120 if (vfsp->vfs_mntd != NULL && vfsp->vfs_type == MNT_JFS
121 && (vfsp->vfs_flag & VFS_DEVMOUNT)) {
122 struct inode *ip = VTOIP(vfsp->vfs_mntd);
123 if (brdev(ip->i_dev) == brdev(rock->dev)) {
133 * Return the vfs entry for the given device.
139 struct devtovfs_args a;
141 AFS_STATCNT(devtovfs);
144 a.ans = (struct vfs *)0;
145 vfs_search(devtovfs_func, &a);
149 /* Keep error values around in case iget fails. UFSOpen panics when
156 /* get an existing inode. Common code for iopen, iread/write, iinc/dec. */
157 /* Also used by rmt_remote to support passing of inode number from venus */
160 igetinode(dev, vfsp, inode, vpp,perror)
162 struct vnode **vpp; /* vnode associated with the inode */
169 struct vfs *nvfsp = NULL;
173 AFS_STATCNT(igetinode);
176 * Double check that the inode lock is at a known offset.
178 * If it isn't, then we need to reexamine our code to make
179 * sure that it is still okay.
181 osi_Assert(offsetof(struct inode, afs_inode_lock) == 128);
183 if (!vfsp && !(vfsp = devtovfs((dev_t)dev))) {
184 afs_warn("Dev=%d not mounted!!; quitting\n", dev);
189 if (vfsp->vfs_flag & VFS_DEVMOUNT)
192 /* Check if inode 0. This is the mount inode for the device
193 * and will panic the aix system if removed: defect 11434.
194 * No file should ever point to this inode.
197 afs_warn("Dev=%d zero inode.\n", dev);
204 if ((code = iget(dev, inode, &ip, 1, nvfsp))) {
209 setuerror(ENOENT); /* Well... */
215 if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) {
218 IGI_nlink = ip->i_nlink;
219 IGI_mode = ip->i_mode;
231 *vpp = ip->i_gnode.gn_vnode;
233 setuerror(iptovp(vfsp, ip, vpp));
242 * `INODESPECIAL' type inodes are ones that describe volumes. These are
243 * marked as journalled. We would also like to journal inodes corresponding
244 * to directory information...
246 #define INODESPECIAL 0xffffffff /* ... from ../vol/viceonode.h */
249 SYSENT(icreate, (dev, near_inode, param1, param2, param3, param4), ) {
250 struct inode *ip, *newip, *pip;
251 register int err, rval1, rc=0;
252 struct vnode *vp = (struct vnode *)0;
253 extern struct vfs *rootvfs;
254 register struct vfs *vfsp;
255 struct vfs *nvfsp = NULL;
257 ino_t ino = near_inode;
259 AFS_STATCNT(afs_syscall_icreate);
260 if (!suser(&error)) {
265 if ((vfsp = devtovfs((dev_t)dev)) == 0) {
266 afs_warn("Dev=%d not mounted!!; quitting\n", dev);
270 if (vfsp->vfs_flag & VFS_DEVMOUNT)
273 rc = iget(dev, 0, &pip, 1, nvfsp);
276 * this is the mount inode, and thus we should be
277 * safe putting it back.
288 if (setuerror(dev_ialloc(pip, ino, IFREG, nvfsp, &newip)))
290 newip->i_flag |= IACC|IUPD|ICHG;
291 newip->i_gid = -2; /* Put special gid flag */
292 newip->i_vicemagic = VICEMAGIC;
293 newip->i_vicep1 = param1;
294 newip->i_vicep2 = param2;
295 newip->i_vicep3 = param3;
296 newip->i_vicep4 = param4;
297 IWRITE_UNLOCK(newip);
299 vp = newip->i_gnode.gn_vnode;
301 rc = iptovp(vfsp, newip, &vp);
305 rval1 = newip->i_number;
309 return getuerror() ? -1 : rval1;
312 SYSENT(iopen, (dev, inode, usrmod), ) {
314 register struct inode *ip;
315 struct vnode *vp = (struct vnode *)0;
316 extern struct fileops vnodefops;
317 register struct vfs *vfsp;
323 AFS_STATCNT(afs_syscall_iopen);
324 if (!suser(&error)) {
329 if ((vfsp = devtovfs((dev_t)dev)) == 0) {
330 afs_warn("Dev=%d not mounted!!; quitting\n", dev);
334 ip = igetinode((dev_t)dev, vfsp, (ino_t)inode, &vp,&dummy);
339 if (setuerror(ufdcreate((usrmod-FOPEN)&FMASK, &vnodefops, vp
340 , DTYPE_VNODE, &fd, credp))) {
346 if (setuerror(VNOP_OPEN(vp, (usrmod-FOPEN)&FMASK, 0, 0, credp))) {
357 * Support for iinc() and idec() system calls--increment or decrement
359 * Restricted to super user.
360 * Only VICEMAGIC type inodes.
362 iinc(dev, inode, inode_p1) {
365 return iincdec(dev, inode, inode_p1, 1);
368 idec(dev, inode, inode_p1) {
371 return iincdec(dev, inode, inode_p1, -1);
375 SYSENT(iincdec, (dev, inode, inode_p1, amount), ) {
376 register struct inode *ip;
378 struct vnode *vp = (struct vnode *)0;
381 AFS_STATCNT(afs_syscall_iincdec);
382 if (!suser(&error)) {
387 ip = igetinode((dev_t)dev, 0, (ino_t)inode, &vp, &dummy);
392 if (ip->i_vicemagic != VICEMAGIC)
394 else if (ip->i_vicep1 != inode_p1)
397 ip->i_nlink += amount;
398 if (ip->i_nlink == 0) {
400 ip->i_cflag &= ~CMNEW;
403 commit(1, ip); /* always commit */
412 return getuerror() ? -1 : 0;