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 * IRIX inode operations
24 * afs_syscall_icreatename64
38 * afs_syscall_ilistinode64
42 #include <afsconfig.h>
43 #include "../afs/param.h"
47 #include "../afs/sysincludes.h" /* Standard vendor system headers */
48 #include "../afs/afsincludes.h" /* Afs-based standard headers */
49 #include "../afs/osi_inode.h"
50 #include "../afs/afs_stats.h" /* statistics stuff */
52 #define BAD_IGET -1000
55 * SGI dependent system calls
59 * `INODESPECIAL' type inodes are ones that describe volumes.
61 #define INODESPECIAL 0xffffffff /* ... from ../vol/viceinode.h */
64 * copy disk inode to incore inode and vice-versa
67 afsdptoip(struct efs_dinode *dp, struct inode *ip)
71 ip->i_afs = kmem_alloc(sizeof(struct afsparms), KM_SLEEP);
72 osi_Assert(ip->i_version == EFS_IVER_AFSSPEC
73 || ip->i_version == EFS_IVER_AFSINO);
74 ap = (struct afsparms *)ip->i_afs;
76 ap->vicep1 = dmag(dp, 0) << 24 | dmag(dp, 1) << 16 |
77 dmag(dp, 2) << 8 | dmag(dp, 3) << 0;
79 if (ip->i_version == EFS_IVER_AFSSPEC) {
80 ap->vicep3 = dmag(dp, 8); /* Type */
81 ap->vicep4 = dmag(dp, 4) << 24 | dmag(dp, 5) << 16 |
82 dmag(dp, 6) << 8 | dmag(dp, 7) << 0;
86 ap->vicep2 = dmag(dp, 4) << 16 |
87 dmag(dp, 5) << 8 | dmag(dp, 6) << 0;
89 ap->vicep3 = dmag(dp, 7) << 16 |
90 dmag(dp, 8) << 8 | dmag(dp, 9) << 0;
92 ap->vicep4 = dmag(dp, 10) << 16 |
93 dmag(dp, 11) << 8 | (dp)->di_spare;
98 afsiptodp(struct inode *ip, struct efs_dinode *dp)
102 if (ip->i_afs == NULL)
105 osi_Assert(ip->i_version == EFS_IVER_AFSSPEC
106 || ip->i_version == EFS_IVER_AFSINO);
107 ap = (struct afsparms *)ip->i_afs;
108 /* vicep1 is VOLid */
109 dmag(dp, 0) = ap->vicep1 >> 24;
110 dmag(dp, 1) = ap->vicep1 >> 16;
111 dmag(dp, 2) = ap->vicep1 >> 8;
112 dmag(dp, 3) = ap->vicep1 >> 0;
114 if (ip->i_version == EFS_IVER_AFSSPEC) {
116 dmag(dp, 8) = ap->vicep3;
118 dmag(dp, 4) = ap->vicep4 >> 24;
119 dmag(dp, 5) = ap->vicep4 >> 16;
120 dmag(dp, 6) = ap->vicep4 >> 8;
121 dmag(dp, 7) = ap->vicep4 >> 0;
124 dmag(dp, 4) = ap->vicep2 >> 16;
125 dmag(dp, 5) = ap->vicep2 >> 8;
126 dmag(dp, 6) = ap->vicep2 >> 0;
128 dmag(dp, 7) = ap->vicep3 >> 16;
129 dmag(dp, 8) = ap->vicep3 >> 8;
130 dmag(dp, 9) = ap->vicep3 >> 0;
132 dmag(dp, 10) = ap->vicep4 >> 16;
133 dmag(dp, 11) = ap->vicep4 >> 8;
134 dp->di_spare = ap->vicep4 >> 0;
139 afsidestroy(struct inode *ip)
142 kmem_free(ip->i_afs, sizeof(struct afsparms));
147 extern int efs_fstype;
148 #ifdef AFS_SGI_XFS_IOPS_ENV
149 extern int xfs_fstype;
153 getinode(struct vfs *vfsp, dev_t dev, ino_t inode, struct inode **ipp)
160 vfsp = vfs_devsearch(dev, efs_fstype);
162 vfsp = vfs_devsearch(dev);
168 #ifndef AFS_SGI65_ENV
169 if (vfsp->vfs_fstype != efs_fstype)
173 if (error = iget((((struct mount *)((vfsp)->vfs_bh.bh_first)->bd_pdata)),
174 (unsigned int)(inode&0xffffffff), &ip)) {
182 igetinode(struct vfs *vfsp, dev_t dev, ino_t inode, struct inode **ipp)
187 AFS_STATCNT(igetinode);
188 if (error = getinode(vfsp, dev, inode, &ip))
197 #define SET_XFS_ERROR(POS, DEV, INO) \
198 XFS_IGET_EPOS = (POS), XFS_IGET_DEV = (DEV), XFS_IGET_INO = (INO)
200 int xfs_getinode(struct vfs *vfsp, dev_t dev, ino_t inode,
201 struct xfs_inode **ipp)
203 struct xfs_inode *ip;
208 vfsp = vfs_devsearch(dev, xfs_fstype);
210 vfsp = vfs_devsearch(dev);
213 SET_XFS_ERROR(1, dev, inode);
217 #ifndef AFS_SGI65_ENV
218 if (vfsp->vfs_fstype != xfs_fstype) {
219 SET_XFS_ERROR(2, vfsp->vfs_dev, inode);
224 if (error = xfs_iget((((struct mount *)
225 ((vfsp)->vfs_bh.bh_first)->bd_pdata)),
226 (void*)0, (xfs_ino_t)inode,
227 XFS_ILOCK_SHARED, &ip, (daddr_t)0)) {
228 SET_XFS_ERROR(3, vfsp->vfs_dev, inode);
236 /* xfs_igetinode now returns an unlocked inode. This is fine, since we
237 * have a refcount on the holding vnode.
239 int xfs_igetinode(struct vfs *vfsp, dev_t dev, ino_t inode,
240 struct xfs_inode **ipp)
242 struct xfs_inode *ip;
247 AFS_STATCNT(igetinode);
250 if (error = xfs_getinode(vfsp, dev, inode, &ip)) {
254 xfs_iunlock(ip, XFS_ILOCK_SHARED);
256 vattr.va_mask = AT_STAT;
257 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), error);
259 SET_XFS_ERROR(4, vp->v_vfsp->vfs_dev, inode);
263 if (vattr.va_nlink == 0 || vattr.va_type != VREG) {
264 SET_XFS_ERROR(5, vp->v_vfsp->vfs_dev, inode);
273 /**************************************************************************
274 * inode creation routines.
276 ***************************************************************************/
286 /* EFS only fs suite uses this entry point - icreate in afssyscalls.c. */
288 icreate(struct icreateargs *uap, rval_t *rvp)
290 #ifdef AFS_SGI_EFS_IOPS_ENV
291 AFS_STATCNT(icreate);
292 return(afs_syscall_icreate(uap->dev, uap->near_inode, uap->param1,
293 uap->param2, uap->param3, uap->param4, rvp));
299 #ifdef AFS_SGI_EFS_IOPS_ENV
301 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp)
302 afs_uint32 dev, near_inode, param1, param2, param3, param4;
305 struct inode *ip, *newip;
310 AFS_STATCNT(afs_syscall_icreate);
314 if (error = getinode(0, (dev_t)dev, 2, &ip))
319 if (error = efs_ialloc(ip, IFREG, 1, NODEV, &newip, &cr)) {
325 newip->i_flags |= IACC|IUPD|ICHG;
327 osi_Assert(newip->i_afs == NULL);
328 newip->i_afs = kmem_alloc(sizeof(struct afsparms), KM_SLEEP);
329 if (param2 == INODESPECIAL)
330 newip->i_version = EFS_IVER_AFSSPEC;
332 newip->i_version = EFS_IVER_AFSINO;
333 ap = (struct afsparms *)newip->i_afs;
334 ap->vicep1 = param1; /* VOLid */
335 ap->vicep2 = param2; /* Vnode # */
336 ap->vicep3 = param3; /* SPEC:type INO:vnode uniq */
337 ap->vicep4 = param4; /* SPEC:parentId INO:data version */
338 rvp->r_val1 = newip->i_number;
342 #else /* !AFS_SGI_EFS_IOPS_ENV */
344 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp)
345 afs_uint32 dev, near_inode, param1, param2, param3, param4;
350 #endif /* AFS_SGI_EFS_IOPS_ENV */
352 #ifdef AFS_SGI_XFS_IOPS_ENV
353 /* inode creation routines for icreatename64 entry point. Use for EFS/XFS
354 * fileserver suite. For XFS, create a name in the namespace as well as the
355 * inode. For EFS, just call the original routine.
358 #include <afs/xfsattrs.h>
359 #include <sys/attributes.h>
361 extern char *int_to_base64(char *, int);
363 /* Lock against races creating/removing directory - vos zap RO, vos create RW*/
364 kmutex_t afs_vol_create_lock;
365 int afs_vol_create_lock_inited = 0;
366 #define AFS_LOCK_VOL_CREATE() { \
367 if (!afs_vol_create_lock_inited) { \
368 mutex_init(&afs_vol_create_lock, MUTEX_DEFAULT, \
369 "afs_vol_create_lock"); \
370 afs_vol_create_lock_inited = 1; \
372 mutex_enter(&afs_vol_create_lock); \
374 #define AFS_UNLOCK_VOL_CREATE() mutex_exit(&afs_vol_create_lock)
378 * Create an AFS inode in the XFS name space. If required create the proper
379 * containing directory. See sys/xfsattrs.h for the details on the naming
380 * conventions and the usage of file and directory attributes.
382 * The inode parameters are stored in an XFS attribute called "AFS". In
383 * addition gid is set to XFS_VICEMAGIC and uid is set to the low 31 bits
384 * of the RW volume id. This is so inode verification in iinc and idec
385 * don't need to get the attribute. Note that only the low 31 bits are set.
386 * This is because chmod only accepts up to MAX_UID and chmod is used
387 * to correct these values in xfs_ListViceInodes.
390 xfs_icreatename64(struct vfs *vfsp, int datap, int datalen,
391 afs_inode_params_t params, ino_t *inop)
393 #define AFS_PNAME_SIZE 16
396 b64_string_t stmp1, stmp2;
397 afs_xfs_attr_t attrs;
399 int name_version = AFS_XFS_NAME_VERS;
400 int code = 0, unused;
403 int rw_vno; /* volume ID of parent volume */
410 /* Get vnode for directory which will contain new inode. */
411 if (datalen >= AFS_PNAME_SIZE)
414 AFS_COPYINSTR((char*)datap, path, AFS_PNAME_SIZE-1, &junk, unused);
419 rw_vno = (params[1] == INODESPECIAL) ? params[3] : params[0];
423 strcat(path, AFS_INODE_DIR_NAME);
424 strcat(path, int_to_base64(stmp1, rw_vno));
426 if (params[1] == INODESPECIAL)
427 AFS_LOCK_VOL_CREATE();
429 code = gop_lookupname(path, AFS_UIOSYS, FOLLOW, NULL, &dvp);
430 if (code == ENOENT) {
431 /* Maybe it's an old directory name format. */
432 AFS_COPYINSTR((char*)datap, name, AFS_PNAME_SIZE-1, &junk, unused);
434 strcat(name, int_to_base64(stmp1, rw_vno));
435 code = gop_lookupname(name, AFS_UIOSYS, FOLLOW, NULL,
438 /* Use old name format. */
440 name_version = AFS_XFS_NAME_VERS1;
444 if (code == ENOENT) {
445 afs_xfs_dattr_t dattr;
446 /* make directory. */
448 code = AFS_VN_OPEN(path, UIO_SYSSPACE, FCREAT|FEXCL, 0700, &dvp,
451 if (code == EEXIST) {
452 /* someone beat us to it? */
453 code = gop_lookupname(path, AFS_UIOSYS, 0, NULL,
457 AFS_UNLOCK_VOL_CREATE();
463 memset((char*)&dattr, 0, sizeof(dattr));
464 dattr.atd_version = AFS_XFS_ATD_VERS;
465 dattr.atd_volume = rw_vno;
466 AFS_VOP_ATTR_SET(dvp, AFS_XFS_DATTR, (char*)&dattr,
468 ATTR_ROOT|ATTR_CREATE, OSI_GET_CURRENT_CRED(), code);
472 (void) vn_remove(path, UIO_SYSSPACE, RMDIRECTORY);
473 AFS_UNLOCK_VOL_CREATE();
478 vattr.va_mask = AT_FSID|AT_NODEID; /* gets a guick return using FSID*/
479 AFS_VOP_GETATTR(dvp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
485 memset((char*)&attrs, 0, sizeof(attrs));
486 attrs.at_pino = vattr.va_nodeid;
489 /* Create the desired file. Use up to ten tries to create a unique name. */
490 (void) strcpy(name, path);
491 (void) strcat(name, "/.");
492 (void) strcat(name, int_to_base64(stmp2, params[2]));
493 s = &name[strlen(name)];
495 attrs.at_tag = 0; /* Initial guess at a unique tag. */
496 for (i=0; i<10; i++) {
499 strcat(s, int_to_base64(stmp1, attrs.at_tag));
500 code = AFS_VN_OPEN(name, UIO_SYSSPACE, FCREAT|FEXCL, 0600, &vp,
502 if (!code || code != EEXIST)
507 /* Unlock the creation process since the directory now has a file in it.*/
508 if (params[1] == INODESPECIAL)
509 AFS_UNLOCK_VOL_CREATE();
512 /* Set attributes. */
513 memcpy((char*)attrs.at_param, (char*)params, sizeof(afs_inode_params_t));
514 attrs.at_attr_version = AFS_XFS_ATTR_VERS;
515 attrs.at_name_version = name_version;
516 AFS_VOP_ATTR_SET(vp, AFS_XFS_ATTR, (char*)&attrs,
518 ATTR_ROOT|ATTR_CREATE, OSI_GET_CURRENT_CRED(),
522 vattr.va_uid = AFS_XFS_VNO_CLIP(params[0]);
523 vattr.va_gid = XFS_VICEMAGIC;
524 vattr.va_mask = AT_MODE | AT_UID | AT_GID;
525 AFS_VOP_SETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
528 vattr.va_mask = AT_NODEID;
529 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
532 *inop = vattr.va_nodeid;
537 /* remove partially created file. */
538 (void) vn_remove(name, UIO_SYSSPACE, RMFILE);
540 /* and directory if volume special file. */
542 AFS_LOCK_VOL_CREATE();
543 (void) vn_remove(path, UIO_SYSSPACE, RMDIRECTORY);
544 AFS_UNLOCK_VOL_CREATE();
550 /* afs_syscall_icreatename64
551 * This is the icreatename64 entry point used by the combined EFS/XFS
552 * fileserver suite. The datap and datalen do not need to be set for EFS.
555 afs_syscall_icreatename64(int dev, int datap, int datalen, int paramp,
559 afs_inode_params_t param;
569 vfsp = vfs_devsearch(dev, VFS_FSTYPE_ANY);
571 vfsp = vfs_devsearch(dev);
577 AFS_COPYIN((char*)paramp, (char*)param, sizeof(afs_inode_params_t), code);
578 if (vfsp->vfs_fstype == xfs_fstype) {
579 code = xfs_icreatename64(vfsp, datap, datalen, param, &ino);
583 AFS_COPYOUT((char*)&ino, (char*)inop, sizeof(ino_t), code);
587 else if (vfsp->vfs_fstype == efs_fstype) {
588 code = afs_syscall_icreate(dev, 0, param[0], param[1], param[2],
593 ino = (ino_t)rval.r_val1;
594 AFS_COPYOUT((char*)&ino, (char*)inop, sizeof(ino_t), code);
600 #endif /* AFS_SGI_XFS_IOPS_ENV */
603 * iopen system calls -- open an inode for reading/writing
604 * Restricted to super user.
606 * The original EFS only system calls are still present in the kernel for
607 * in case a kernel upgrade is done for a fix, but the EFS fileserver is
616 #ifdef AFS_SGI_XFS_IOPS_ENV
626 afs_syscall_iopen(int dev, ino_t inode, int usrmod, rval_t *rvp)
634 AFS_STATCNT(afs_syscall_iopen);
637 vfsp = vfs_devsearch(dev, xfs_fstype);
639 vfsp = vfs_devsearch(dev, efs_fstype);
643 #ifdef AFS_SGI_EFS_IOPS_ENV
644 if (vfsp->vfs_fstype == efs_fstype) {
646 if (error = igetinode(vfsp, (dev_t)dev, inode, &ip))
649 if (error = vfile_alloc((usrmod+1) & (FMASK), &fp, &fd)) {
656 #endif /* AFS_SGI_EFS_IOPS_ENV */
657 if (vfsp->vfs_fstype == xfs_fstype) {
658 struct xfs_inode *xip;
659 if (error = xfs_igetinode(vfsp, (dev_t)dev, inode, &xip))
662 if (error = vfile_alloc((usrmod+1) & (FMASK), &fp, &fd)) {
668 osi_Panic("afs_syscall_iopen: bad fstype = %d\n",
677 * EFS/XFS version vectors to correct code based vfs_fstype. Expects a
678 * 64 bit inode number.
681 afs_syscall_iopen(int dev, ino_t inode, int usrmod, rval_t *rvp)
688 AFS_STATCNT(afs_syscall_iopen);
691 vfsp = vfs_devsearch(dev);
696 if (vfsp->vfs_fstype == xfs_fstype) {
697 struct xfs_inode *xip;
699 if (error = xfs_igetinode(vfsp, (dev_t)dev, inode, &xip))
702 if (error = falloc(vp, (usrmod+1) & (FMASK), &fp, &fd)) {
707 else if (vfsp->vfs_fstype == efs_fstype) {
709 if (error = igetinode(vfsp, (dev_t)dev, inode, &ip))
711 if (error = falloc(EFS_ITOV(ip), (usrmod+1) & (FMASK), &fp, &fd)) {
718 osi_Panic("afs_syscall_iopen: bad fstype = %d\n",
725 #endif /* AFS_SGI65_ENV */
728 iopen(struct iopenargs *uap, rval_t *rvp)
731 return (afs_syscall_iopen(uap->dev, (ino_t)uap->inode, uap->usrmod,
736 iopen64(struct iopenargs64 *uap, rval_t *rvp)
739 return (afs_syscall_iopen(uap->dev,
740 (ino_t)((uap->inode_hi<<32) | uap->inode_lo),
744 #else /* AFS_SGI_XFS_IOPS_ENV */
745 /* iopen/afs_syscall_iopen
747 * Original EFS only 32 bit iopen call.
750 iopen(struct iopenargs *uap, rval_t *rvp)
753 return (afs_syscall_iopen(uap->dev, uap->inode, uap->usrmod, rvp));
757 afs_syscall_iopen(dev, inode, usrmod, rvp)
758 int dev, inode, usrmod;
766 AFS_STATCNT(afs_syscall_iopen);
769 if (error = igetinode(0, (dev_t)dev, inode, &ip))
771 if (error = falloc(EFS_ITOV(ip), (usrmod+1) & (FMASK), &fp, &fd)) {
782 #endif /* AFS_SGI_XFS_IOPS_ENV */
785 * Support for iinc() and idec() system calls--increment or decrement
787 * Restricted to super user.
788 * Only VICEMAGIC type inodes.
790 #ifdef AFS_SGI_XFS_IOPS_ENV
791 #ifdef AFS_SGI_EFS_IOPS_ENV
794 * XFS/EFS iinc/idec code for EFS. Uses 32 bit inode numbers.
796 static int efs_iincdec(vfsp, inode, inode_p1, amount)
798 int inode, inode_p1, amount;
803 if (error = igetinode(vfsp, NULL, inode, &ip))
806 if (!IS_VICEMAGIC(ip))
808 else if (((struct afsparms *)ip->i_afs)->vicep1 != inode_p1)
811 ip->i_nlink += amount;
812 osi_Assert(ip->i_nlink >= 0);
813 if (ip->i_nlink == 0) {
819 /* XXX sync write?? */
823 #endif /* AFS_SGI_EFS_IOPS_ENV */
827 * XFS/EFS iinc/idec code for EFS. Uses 64 bit inode numbers.
829 static int xfs_iincdec64(struct vfs *vfsp, ino_t inode, int inode_p1,
835 afs_xfs_attr_t attrs;
836 int length = SIZEOF_XFS_ATTR_T;
837 afs_xfs_dattr_t dattr;
842 code = xfs_iget((((struct mount *)((vfsp)->vfs_bh.bh_first)->bd_pdata)),
843 (void*)0, (xfs_ino_t)inode, XFS_ILOCK_SHARED, &ip,
849 xfs_iunlock(ip, XFS_ILOCK_SHARED);
851 vattr.va_mask = AT_GID | AT_UID | AT_MODE;
852 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
856 if (!code && (vattr.va_gid != XFS_VICEMAGIC))
859 if (!code && (AFS_XFS_VNO_CLIP(inode_p1) != vattr.va_uid))
867 nlink = vattr.va_mode & AFS_XFS_MODE_LINK_MASK;
873 vattr.va_mode &= ~AFS_XFS_MODE_LINK_MASK;
874 vattr.va_mode |= nlink;
875 vattr.va_mask = AT_MODE;
876 AFS_VOP_SETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
882 b64_string_t stmp1, stmp2;
886 length = SIZEOF_XFS_ATTR_T;
887 AFS_VOP_ATTR_GET(vp, AFS_XFS_ATTR, (char*)&attrs, &length,
888 ATTR_ROOT, OSI_GET_CURRENT_CRED(), code);
891 if (length != SIZEOF_XFS_ATTR_T
892 || attrs.at_attr_version != AFS_XFS_ATTR_VERS)
895 /* Get the vnode for the directory this file is in. */
899 code = xfs_getinode(vp->v_vfsp, NULL, attrs.at_pino, &ip);
904 xfs_iunlock(ip, XFS_ILOCK_SHARED);
906 /* Verify directory attributes. */
907 length = SIZEOF_XFS_DATTR_T;
908 AFS_VOP_ATTR_GET(dvp, AFS_XFS_DATTR , (char*)&dattr, &length,
909 ATTR_ROOT, OSI_GET_CURRENT_CRED(), code);
911 if (length != SIZEOF_XFS_DATTR_T
912 || dattr.atd_version != AFS_XFS_ATD_VERS)
921 strcat(path, int_to_base64(stmp1, attrs.at_param[2]));
923 strcat(path, int_to_base64(stmp1, attrs.at_tag));
925 AFS_VOP_REMOVE(dvp, path, OSI_GET_CURRENT_CRED(), code);
929 vattr.va_mask = AT_NLINK;
930 AFS_VOP_GETATTR(dvp, &vattr, 0, OSI_GET_CURRENT_CRED(),
933 if (vattr.va_nlink == 2) {
934 vnode_t *ddvp; /* parent of volume directory. */
935 /* Try to remove the directory if this is a volume
936 * special file. It's ok to fail.
938 AFS_VOP_LOOKUP(dvp, "..", &ddvp,
939 (struct pathname *)NULL,
940 0, OSI_GET_CURRENT_RDIR(),
941 OSI_GET_CURRENT_CRED(), code2);
946 if (attrs.at_name_version == AFS_XFS_NAME_VERS2)
947 strcpy(path, AFS_INODE_DIR_NAME);
951 (attrs.at_param[1] == INODESPECIAL) ?
952 attrs.at_param[3] : attrs.at_param[0]);
954 AFS_LOCK_VOL_CREATE();
955 AFS_VOP_RMDIR(ddvp, path, OSI_GET_CURRENT_CDIR(),
956 OSI_GET_CURRENT_CRED(), code2);
957 AFS_UNLOCK_VOL_CREATE();
970 iincdec64(int dev, int inode_hi, int inode_lo, int inode_p1, int amount)
977 vfsp = vfs_devsearch(dev, VFS_FSTYPE_ANY);
979 vfsp = vfs_devsearch(dev);
985 if (vfsp->vfs_fstype == xfs_fstype) {
990 return xfs_iincdec64(vfsp, inode, inode_p1, amount);
992 #ifdef AFS_SGI_EFS_IOPS_ENV
993 else if (vfsp->vfs_fstype == efs_fstype) {
994 return efs_iincdec(vfsp, inode_lo, inode_p1, amount);
996 #endif /* AFS_SGI_EFS_IOPS_ENV */
1001 afs_syscall_idec64(int dev, int inode_hi, int inode_lo, int inode_p1)
1003 return iincdec64(dev, inode_hi, inode_lo, inode_p1, -1);
1007 afs_syscall_iinc64(int dev, int inode_hi, int inode_lo, int inode_p1)
1009 return iincdec64(dev, inode_hi, inode_lo, inode_p1, 1);
1021 #ifdef AFS_SGI65_ENV
1022 int iinc(struct iincargs *uap, rval_t *rvp) {
1026 int idec(struct iincargs *uap, rval_t *rvp) {
1033 * XFS/EFS iinc/idec entry points for EFS only fileservers.
1037 iincdec(dev, inode, inode_p1, amount)
1038 int dev, inode, inode_p1, amount;
1044 vfsp = vfs_devsearch(dev);
1048 if (vfsp->vfs_fstype != efs_fstype)
1051 return efs_iincdec(vfsp, inode, inode_p1, amount);
1054 iinc(struct iincargs *uap, rval_t *rvp) {
1056 return (iincdec(uap->dev, uap->inode, uap->inode_p1, 1));
1060 idec(struct iincargs *uap, rval_t *rvp) {
1062 return (iincdec(uap->dev, uap->inode, uap->inode_p1, -1));
1064 #endif /* AFS_SGI65_ENV */
1066 #else /* AFS_SGI_XFS_IOPS_ENV */
1067 /* afs_syscall_iincdec iinc idec
1069 * These are the original EFS only entry points.
1072 afs_syscall_iincdec(dev, inode, inode_p1, amount)
1073 int dev, inode, inode_p1, amount;
1080 if (error = igetinode(0, (dev_t)dev, inode, &ip))
1083 if (!IS_VICEMAGIC(ip))
1085 else if (((struct afsparms *)ip->i_afs)->vicep1 != inode_p1)
1088 ip->i_nlink += amount;
1089 osi_Assert(ip->i_nlink >= 0);
1090 if (ip->i_nlink == 0) {
1091 CLEAR_VICEMAGIC(ip);
1094 ip->i_flags |= ICHG;
1096 /* XXX sync write?? */
1108 iinc(struct iincargs *uap, rval_t *rvp) {
1110 return (afs_syscall_iincdec(uap->dev, uap->inode, uap->inode_p1, 1));
1114 idec(struct iincargs *uap, rval_t *rvp) {
1116 return (afs_syscall_iincdec(uap->dev, uap->inode, uap->inode_p1, -1));
1118 #endif /* AFS_SGI_XFS_IOPS_ENV */
1120 #ifdef AFS_SGI_XFS_IOPS_ENV
1121 /* afs_syscall_ilistinode64
1122 * Gathers up all required info for ListViceInodes in one system call.
1125 afs_syscall_ilistinode64(int dev, int inode_hi, int inode_lo,
1126 int datap, int datalenp)
1134 afs_xfs_attr_t attrs;
1136 i_list_inode_t data;
1141 #ifdef AFS_SGI65_ENV
1142 vfsp = vfs_devsearch(dev, xfs_fstype);
1144 vfsp = vfs_devsearch(dev);
1149 #ifndef AFS_SGI65_ENV
1150 if (vfsp->vfs_fstype != xfs_fstype)
1154 AFS_COPYIN((char*)datalenp, &idatalen, sizeof(int), code);
1155 if (idatalen < sizeof(i_list_inode_t)) {
1156 idatalen = sizeof(i_list_inode_t);
1157 AFS_COPYOUT((char*)datalenp, (char*)&idatalen, sizeof(int), code);
1160 idatalen = sizeof(i_list_inode_t);
1161 AFS_COPYOUT((char*)datalenp, (char*)&idatalen, sizeof(int), code);
1163 AFS_COPYIN((char*)datap, (char*)&data, sizeof(i_list_inode_t), code);
1164 if (data.ili_version != AFS_XFS_ILI_VERSION) {
1165 data.ili_version = AFS_XFS_ILI_VERSION;
1166 AFS_COPYOUT((char*)&data, (char*)datap, sizeof(i_list_inode_t), code);
1174 code = xfs_iget((((struct mount *)((vfsp)->vfs_bh.bh_first)->bd_pdata)),
1175 (void*)0, (xfs_ino_t)inode,
1176 XFS_ILOCK_SHARED, &ip, (daddr_t)0);
1181 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1183 length = SIZEOF_XFS_ATTR_T;
1185 AFS_VOP_ATTR_GET(vp, AFS_XFS_ATTR, (char*)&attrs, &length,
1186 ATTR_ROOT, OSI_GET_CURRENT_CRED(), code);
1192 if (attrs.at_attr_version != AFS_XFS_ATTR_VERS)
1197 vattr.va_mask = AT_STAT;
1198 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
1202 memset((char*)&data, 0, sizeof(data));
1203 data.ili_info.inodeNumber = inode;
1204 data.ili_info.byteCount = vattr.va_size;
1205 data.ili_info.linkCount = (vattr.va_mode & AFS_XFS_MODE_LINK_MASK);
1206 memcpy((char*)data.ili_info.param, (char*)attrs.at_param, sizeof(data.ili_info.param));
1207 data.ili_attr_version = attrs.at_attr_version;
1208 data.ili_name_version = attrs.at_name_version;
1209 data.ili_tag = attrs.at_tag;
1210 data.ili_pino = attrs.at_pino;
1211 data.ili_vno = vattr.va_uid;
1212 data.ili_magic = vattr.va_gid;
1213 AFS_COPYOUT((char*)&data, (char*)datap, sizeof(data), code);
1218 #endif /* AFS_SGI_XFS_IOPS_ENV */