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"
48 #include "afs/sysincludes.h" /* Standard vendor system headers */
49 #include "afsincludes.h" /* Afs-based standard headers */
50 #include "afs/osi_inode.h"
51 #include "afs/afs_stats.h" /* statistics stuff */
53 #define BAD_IGET -1000
56 * SGI dependent system calls
60 * `INODESPECIAL' type inodes are ones that describe volumes.
62 #define INODESPECIAL 0xffffffff /* ... from ../vol/viceinode.h */
65 * copy disk inode to incore inode and vice-versa
68 afsdptoip(struct efs_dinode *dp, struct inode *ip)
72 ip->i_afs = kmem_alloc(sizeof(struct afsparms), KM_SLEEP);
73 osi_Assert(ip->i_version == EFS_IVER_AFSSPEC
74 || ip->i_version == EFS_IVER_AFSINO);
75 ap = (struct afsparms *)ip->i_afs;
78 dmag(dp, 0) << 24 | dmag(dp, 1) << 16 | dmag(dp, 2) << 8 | dmag(dp,
82 if (ip->i_version == EFS_IVER_AFSSPEC) {
83 ap->vicep3 = dmag(dp, 8); /* Type */
85 dmag(dp, 4) << 24 | dmag(dp, 5) << 16 | dmag(dp,
92 ap->vicep2 = dmag(dp, 4) << 16 | dmag(dp, 5) << 8 | dmag(dp, 6) << 0;
94 ap->vicep3 = dmag(dp, 7) << 16 | dmag(dp, 8) << 8 | dmag(dp, 9) << 0;
96 ap->vicep4 = dmag(dp, 10) << 16 | dmag(dp, 11) << 8 | (dp)->di_spare;
101 afsiptodp(struct inode *ip, struct efs_dinode *dp)
105 if (ip->i_afs == NULL)
108 osi_Assert(ip->i_version == EFS_IVER_AFSSPEC
109 || ip->i_version == EFS_IVER_AFSINO);
110 ap = (struct afsparms *)ip->i_afs;
111 /* vicep1 is VOLid */
112 dmag(dp, 0) = ap->vicep1 >> 24;
113 dmag(dp, 1) = ap->vicep1 >> 16;
114 dmag(dp, 2) = ap->vicep1 >> 8;
115 dmag(dp, 3) = ap->vicep1 >> 0;
117 if (ip->i_version == EFS_IVER_AFSSPEC) {
119 dmag(dp, 8) = ap->vicep3;
121 dmag(dp, 4) = ap->vicep4 >> 24;
122 dmag(dp, 5) = ap->vicep4 >> 16;
123 dmag(dp, 6) = ap->vicep4 >> 8;
124 dmag(dp, 7) = ap->vicep4 >> 0;
127 dmag(dp, 4) = ap->vicep2 >> 16;
128 dmag(dp, 5) = ap->vicep2 >> 8;
129 dmag(dp, 6) = ap->vicep2 >> 0;
131 dmag(dp, 7) = ap->vicep3 >> 16;
132 dmag(dp, 8) = ap->vicep3 >> 8;
133 dmag(dp, 9) = ap->vicep3 >> 0;
135 dmag(dp, 10) = ap->vicep4 >> 16;
136 dmag(dp, 11) = ap->vicep4 >> 8;
137 dp->di_spare = ap->vicep4 >> 0;
142 afsidestroy(struct inode *ip)
145 kmem_free(ip->i_afs, sizeof(struct afsparms));
150 extern int efs_fstype;
151 #ifdef AFS_SGI_XFS_IOPS_ENV
152 extern int xfs_fstype;
156 getinode(struct vfs *vfsp, dev_t dev, ino_t inode, struct inode **ipp)
163 vfsp = vfs_devsearch(dev, efs_fstype);
165 vfsp = vfs_devsearch(dev);
171 #ifndef AFS_SGI65_ENV
172 if (vfsp->vfs_fstype != efs_fstype)
177 iget((((struct mount *)((vfsp)->vfs_bh.bh_first)->bd_pdata)),
178 (unsigned int)(inode & 0xffffffff), &ip)) {
186 igetinode(struct vfs *vfsp, dev_t dev, ino_t inode, struct inode **ipp)
191 AFS_STATCNT(igetinode);
192 if (error = getinode(vfsp, dev, inode, &ip))
201 #define SET_XFS_ERROR(POS, DEV, INO) \
202 XFS_IGET_EPOS = (POS), XFS_IGET_DEV = (DEV), XFS_IGET_INO = (INO)
205 xfs_getinode(struct vfs *vfsp, dev_t dev, ino_t inode, struct xfs_inode **ipp)
207 struct xfs_inode *ip;
212 vfsp = vfs_devsearch(dev, xfs_fstype);
214 vfsp = vfs_devsearch(dev);
217 SET_XFS_ERROR(1, dev, inode);
221 #ifndef AFS_SGI65_ENV
222 if (vfsp->vfs_fstype != xfs_fstype) {
223 SET_XFS_ERROR(2, vfsp->vfs_dev, inode);
228 if (error = xfs_iget((((struct mount *)
229 ((vfsp)->vfs_bh.bh_first)->bd_pdata)), (void *)0,
230 (xfs_ino_t) inode, XFS_ILOCK_SHARED, &ip,
232 SET_XFS_ERROR(3, vfsp->vfs_dev, inode);
240 /* xfs_igetinode now returns an unlocked inode. This is fine, since we
241 * have a refcount on the holding vnode.
244 xfs_igetinode(struct vfs *vfsp, dev_t dev, ino_t inode,
245 struct xfs_inode **ipp)
247 struct xfs_inode *ip;
252 AFS_STATCNT(igetinode);
255 if (error = xfs_getinode(vfsp, dev, inode, &ip)) {
259 xfs_iunlock(ip, XFS_ILOCK_SHARED);
261 vattr.va_mask = AT_STAT;
262 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), error);
264 SET_XFS_ERROR(4, vp->v_vfsp->vfs_dev, inode);
268 if (vattr.va_nlink == 0 || vattr.va_type != VREG) {
269 SET_XFS_ERROR(5, vp->v_vfsp->vfs_dev, inode);
278 /**************************************************************************
279 * inode creation routines.
281 ***************************************************************************/
291 /* EFS only fs suite uses this entry point - icreate in afssyscalls.c. */
293 icreate(struct icreateargs *uap, rval_t * rvp)
295 #ifdef AFS_SGI_EFS_IOPS_ENV
296 AFS_STATCNT(icreate);
297 return (afs_syscall_icreate
298 (uap->dev, uap->near_inode, uap->param1, uap->param2, uap->param3,
305 #ifdef AFS_SGI_EFS_IOPS_ENV
307 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp)
308 afs_uint32 dev, near_inode, param1, param2, param3, param4;
311 struct inode *ip, *newip;
316 AFS_STATCNT(afs_syscall_icreate);
317 if (!afs_suser(NULL))
320 if (error = getinode(0, (dev_t) dev, 2, &ip))
325 if (error = efs_ialloc(ip, IFREG, 1, NODEV, &newip, &cr)) {
331 newip->i_flags |= IACC | IUPD | ICHG;
333 osi_Assert(newip->i_afs == NULL);
334 newip->i_afs = kmem_alloc(sizeof(struct afsparms), KM_SLEEP);
335 if (param2 == INODESPECIAL)
336 newip->i_version = EFS_IVER_AFSSPEC;
338 newip->i_version = EFS_IVER_AFSINO;
339 ap = (struct afsparms *)newip->i_afs;
340 ap->vicep1 = param1; /* VOLid */
341 ap->vicep2 = param2; /* Vnode # */
342 ap->vicep3 = param3; /* SPEC:type INO:vnode uniq */
343 ap->vicep4 = param4; /* SPEC:parentId INO:data version */
344 rvp->r_val1 = newip->i_number;
348 #else /* !AFS_SGI_EFS_IOPS_ENV */
350 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp)
351 afs_uint32 dev, near_inode, param1, param2, param3, param4;
356 #endif /* AFS_SGI_EFS_IOPS_ENV */
358 #ifdef AFS_SGI_XFS_IOPS_ENV
359 /* inode creation routines for icreatename64 entry point. Use for EFS/XFS
360 * fileserver suite. For XFS, create a name in the namespace as well as the
361 * inode. For EFS, just call the original routine.
364 #include <afs/xfsattrs.h>
365 #include <sys/attributes.h>
367 extern char *int_to_base64(char *, int);
369 /* Lock against races creating/removing directory - vos zap RO, vos create RW*/
370 kmutex_t afs_vol_create_lock;
371 int afs_vol_create_lock_inited = 0;
372 #define AFS_LOCK_VOL_CREATE() { \
373 if (!afs_vol_create_lock_inited) { \
374 mutex_init(&afs_vol_create_lock, MUTEX_DEFAULT, \
375 "afs_vol_create_lock"); \
376 afs_vol_create_lock_inited = 1; \
378 mutex_enter(&afs_vol_create_lock); \
380 #define AFS_UNLOCK_VOL_CREATE() mutex_exit(&afs_vol_create_lock)
384 * Create an AFS inode in the XFS name space. If required create the proper
385 * containing directory. See sys/xfsattrs.h for the details on the naming
386 * conventions and the usage of file and directory attributes.
388 * The inode parameters are stored in an XFS attribute called "AFS". In
389 * addition gid is set to XFS_VICEMAGIC and uid is set to the low 31 bits
390 * of the RW volume id. This is so inode verification in iinc and idec
391 * don't need to get the attribute. Note that only the low 31 bits are set.
392 * This is because chmod only accepts up to MAX_UID and chmod is used
393 * to correct these values in xfs_ListViceInodes.
396 xfs_icreatename64(struct vfs *vfsp, int datap, int datalen,
397 afs_inode_params_t params, ino_t * inop)
399 #define AFS_PNAME_SIZE 16
402 b64_string_t stmp1, stmp2;
403 afs_xfs_attr_t attrs;
405 int name_version = AFS_XFS_NAME_VERS;
406 int code = 0, unused;
409 int rw_vno; /* volume ID of parent volume */
416 /* Get vnode for directory which will contain new inode. */
417 if (datalen >= AFS_PNAME_SIZE)
420 AFS_COPYINSTR((char *)datap, path, AFS_PNAME_SIZE - 1, &junk, unused);
425 rw_vno = (params[1] == INODESPECIAL) ? params[3] : params[0];
429 strcat(path, AFS_INODE_DIR_NAME);
430 strcat(path, int_to_base64(stmp1, rw_vno));
432 if (params[1] == INODESPECIAL)
433 AFS_LOCK_VOL_CREATE();
435 code = gop_lookupname(path, AFS_UIOSYS, FOLLOW, &dvp);
436 if (code == ENOENT) {
437 /* Maybe it's an old directory name format. */
438 AFS_COPYINSTR((char *)datap, name, AFS_PNAME_SIZE - 1, &junk, unused);
440 strcat(name, int_to_base64(stmp1, rw_vno));
441 code = gop_lookupname(name, AFS_UIOSYS, FOLLOW, &dvp);
443 /* Use old name format. */
445 name_version = AFS_XFS_NAME_VERS1;
449 if (code == ENOENT) {
450 afs_xfs_dattr_t dattr;
451 /* make directory. */
454 AFS_VN_OPEN(path, UIO_SYSSPACE, FCREAT | FEXCL, 0700, &dvp,
457 if (code == EEXIST) {
458 /* someone beat us to it? */
459 code = gop_lookupname(path, AFS_UIOSYS, NO_FOLLOW, &dvp);
462 AFS_UNLOCK_VOL_CREATE();
467 memset((char *)&dattr, 0, sizeof(dattr));
468 dattr.atd_version = AFS_XFS_ATD_VERS;
469 dattr.atd_volume = rw_vno;
470 AFS_VOP_ATTR_SET(dvp, AFS_XFS_DATTR, (char *)&dattr,
471 SIZEOF_XFS_DATTR_T, ATTR_ROOT | ATTR_CREATE,
472 OSI_GET_CURRENT_CRED(), code);
476 (void)vn_remove(path, UIO_SYSSPACE, RMDIRECTORY);
477 AFS_UNLOCK_VOL_CREATE();
482 vattr.va_mask = AT_FSID | AT_NODEID; /* gets a guick return using FSID */
483 AFS_VOP_GETATTR(dvp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
489 memset((char *)&attrs, 0, sizeof(attrs));
490 attrs.at_pino = vattr.va_nodeid;
493 /* Create the desired file. Use up to ten tries to create a unique name. */
494 (void)strcpy(name, path);
495 (void)strcat(name, "/.");
496 (void)strcat(name, int_to_base64(stmp2, params[2]));
497 s = &name[strlen(name)];
499 attrs.at_tag = 0; /* Initial guess at a unique tag. */
500 for (i = 0; i < 10; i++) {
503 strcat(s, int_to_base64(stmp1, attrs.at_tag));
505 AFS_VN_OPEN(name, UIO_SYSSPACE, FCREAT | FEXCL, 0600, &vp,
507 if (!code || code != EEXIST)
512 /* Unlock the creation process since the directory now has a file in it. */
513 if (params[1] == INODESPECIAL)
514 AFS_UNLOCK_VOL_CREATE();
517 /* Set attributes. */
518 memcpy((char *)attrs.at_param, (char *)params,
519 sizeof(afs_inode_params_t));
520 attrs.at_attr_version = AFS_XFS_ATTR_VERS;
521 attrs.at_name_version = name_version;
522 AFS_VOP_ATTR_SET(vp, AFS_XFS_ATTR, (char *)&attrs, SIZEOF_XFS_ATTR_T,
523 ATTR_ROOT | ATTR_CREATE, OSI_GET_CURRENT_CRED(),
527 vattr.va_uid = AFS_XFS_VNO_CLIP(params[0]);
528 vattr.va_gid = XFS_VICEMAGIC;
529 vattr.va_mask = AT_MODE | AT_UID | AT_GID;
530 AFS_VOP_SETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
533 vattr.va_mask = AT_NODEID;
534 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
537 *inop = vattr.va_nodeid;
542 /* remove partially created file. */
543 (void)vn_remove(name, UIO_SYSSPACE, RMFILE);
545 /* and directory if volume special file. */
547 AFS_LOCK_VOL_CREATE();
548 (void)vn_remove(path, UIO_SYSSPACE, RMDIRECTORY);
549 AFS_UNLOCK_VOL_CREATE();
555 /* afs_syscall_icreatename64
556 * This is the icreatename64 entry point used by the combined EFS/XFS
557 * fileserver suite. The datap and datalen do not need to be set for EFS.
560 afs_syscall_icreatename64(int dev, int datap, int datalen, int paramp,
564 afs_inode_params_t param;
570 if (!afs_suser(NULL))
574 vfsp = vfs_devsearch(dev, VFS_FSTYPE_ANY);
576 vfsp = vfs_devsearch(dev);
582 AFS_COPYIN((char *)paramp, (char *)param, sizeof(afs_inode_params_t),
584 if (vfsp->vfs_fstype == xfs_fstype) {
585 code = xfs_icreatename64(vfsp, datap, datalen, param, &ino);
589 AFS_COPYOUT((char *)&ino, (char *)inop, sizeof(ino_t), code);
592 } else if (vfsp->vfs_fstype == efs_fstype) {
594 afs_syscall_icreate(dev, 0, param[0], param[1], param[2],
599 ino = (ino_t) rval.r_val1;
600 AFS_COPYOUT((char *)&ino, (char *)inop, sizeof(ino_t), code);
606 #endif /* AFS_SGI_XFS_IOPS_ENV */
609 * iopen system calls -- open an inode for reading/writing
610 * Restricted to super user.
612 * The original EFS only system calls are still present in the kernel for
613 * in case a kernel upgrade is done for a fix, but the EFS fileserver is
622 #ifdef AFS_SGI_XFS_IOPS_ENV
632 afs_syscall_iopen(int dev, ino_t inode, int usrmod, rval_t * rvp)
640 AFS_STATCNT(afs_syscall_iopen);
641 if (!afs_suser(NULL))
643 vfsp = vfs_devsearch(dev, xfs_fstype);
645 vfsp = vfs_devsearch(dev, efs_fstype);
649 #ifdef AFS_SGI_EFS_IOPS_ENV
650 if (vfsp->vfs_fstype == efs_fstype) {
652 if (error = igetinode(vfsp, (dev_t) dev, inode, &ip))
655 if (error = vfile_alloc((usrmod + 1) & (FMASK), &fp, &fd)) {
661 #endif /* AFS_SGI_EFS_IOPS_ENV */
662 if (vfsp->vfs_fstype == xfs_fstype) {
663 struct xfs_inode *xip;
664 if (error = xfs_igetinode(vfsp, (dev_t) dev, inode, &xip))
667 if (error = vfile_alloc((usrmod + 1) & (FMASK), &fp, &fd)) {
672 osi_Panic("afs_syscall_iopen: bad fstype = %d\n", vfsp->vfs_fstype);
680 * EFS/XFS version vectors to correct code based vfs_fstype. Expects a
681 * 64 bit inode number.
684 afs_syscall_iopen(int dev, ino_t inode, int usrmod, rval_t * rvp)
691 AFS_STATCNT(afs_syscall_iopen);
692 if (!afs_suser(NULL))
694 vfsp = vfs_devsearch(dev);
699 if (vfsp->vfs_fstype == xfs_fstype) {
700 struct xfs_inode *xip;
702 if (error = xfs_igetinode(vfsp, (dev_t) dev, inode, &xip))
705 if (error = falloc(vp, (usrmod + 1) & (FMASK), &fp, &fd)) {
709 } else if (vfsp->vfs_fstype == efs_fstype) {
711 if (error = igetinode(vfsp, (dev_t) dev, inode, &ip))
713 if (error = falloc(EFS_ITOV(ip), (usrmod + 1) & (FMASK), &fp, &fd)) {
719 osi_Panic("afs_syscall_iopen: bad fstype = %d\n", vfsp->vfs_fstype);
725 #endif /* AFS_SGI65_ENV */
728 iopen(struct iopenargs *uap, rval_t * rvp)
731 return (afs_syscall_iopen
732 (uap->dev, (ino_t) uap->inode, uap->usrmod, rvp));
736 iopen64(struct iopenargs64 *uap, rval_t * rvp)
739 return (afs_syscall_iopen
740 (uap->dev, (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);
767 if (!afs_suser(NULL))
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.
797 efs_iincdec(vfsp, inode, inode_p1, amount)
799 int inode, inode_p1, amount;
804 if (error = igetinode(vfsp, NULL, inode, &ip))
807 if (!IS_VICEMAGIC(ip))
809 else if (((struct afsparms *)ip->i_afs)->vicep1 != inode_p1)
812 ip->i_nlink += amount;
813 osi_Assert(ip->i_nlink >= 0);
814 if (ip->i_nlink == 0) {
820 /* XXX sync write?? */
824 #endif /* AFS_SGI_EFS_IOPS_ENV */
828 * XFS/EFS iinc/idec code for EFS. Uses 64 bit inode numbers.
831 xfs_iincdec64(struct vfs *vfsp, ino_t inode, int inode_p1, int amount)
836 afs_xfs_attr_t attrs;
837 int length = SIZEOF_XFS_ATTR_T;
838 afs_xfs_dattr_t dattr;
844 xfs_iget((((struct mount *)((vfsp)->vfs_bh.bh_first)->bd_pdata)),
845 (void *)0, (xfs_ino_t) inode, XFS_ILOCK_SHARED, &ip,
851 xfs_iunlock(ip, XFS_ILOCK_SHARED);
853 vattr.va_mask = AT_GID | AT_UID | AT_MODE;
854 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
858 if (!code && (vattr.va_gid != XFS_VICEMAGIC))
861 if (!code && (AFS_XFS_VNO_CLIP(inode_p1) != vattr.va_uid))
869 nlink = vattr.va_mode & AFS_XFS_MODE_LINK_MASK;
875 vattr.va_mode &= ~AFS_XFS_MODE_LINK_MASK;
876 vattr.va_mode |= nlink;
877 vattr.va_mask = AT_MODE;
878 AFS_VOP_SETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
883 b64_string_t stmp1, stmp2;
887 length = SIZEOF_XFS_ATTR_T;
888 AFS_VOP_ATTR_GET(vp, AFS_XFS_ATTR, (char *)&attrs, &length, ATTR_ROOT,
889 OSI_GET_CURRENT_CRED(), code);
892 if (length != SIZEOF_XFS_ATTR_T
893 || attrs.at_attr_version != AFS_XFS_ATTR_VERS)
896 /* Get the vnode for the directory this file is in. */
900 code = xfs_getinode(vp->v_vfsp, NULL, attrs.at_pino, &ip);
905 xfs_iunlock(ip, XFS_ILOCK_SHARED);
907 /* Verify directory attributes. */
908 length = SIZEOF_XFS_DATTR_T;
909 AFS_VOP_ATTR_GET(dvp, AFS_XFS_DATTR, (char *)&dattr, &length,
910 ATTR_ROOT, OSI_GET_CURRENT_CRED(), code);
912 if (length != SIZEOF_XFS_DATTR_T
913 || dattr.atd_version != AFS_XFS_ATD_VERS)
922 strcat(path, int_to_base64(stmp1, attrs.at_param[2]));
924 strcat(path, int_to_base64(stmp1, attrs.at_tag));
926 AFS_VOP_REMOVE(dvp, path, OSI_GET_CURRENT_CRED(), code);
930 vattr.va_mask = AT_NLINK;
931 AFS_VOP_GETATTR(dvp, &vattr, 0, OSI_GET_CURRENT_CRED(), code2);
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, (struct pathname *)NULL,
939 0, OSI_GET_CURRENT_RDIR(),
940 OSI_GET_CURRENT_CRED(), code2);
945 if (attrs.at_name_version == AFS_XFS_NAME_VERS2)
946 strcpy(path, AFS_INODE_DIR_NAME);
950 (attrs.at_param[1] ==
951 INODESPECIAL) ? attrs.
952 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)
974 if (!afs_suser(NULL))
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
1023 iinc(struct iincargs *uap, rval_t * rvp)
1030 idec(struct iincargs *uap, rval_t * rvp)
1038 * XFS/EFS iinc/idec entry points for EFS only fileservers.
1042 iincdec(dev, inode, inode_p1, amount)
1043 int dev, inode, inode_p1, amount;
1047 if (!afs_suser(NULL))
1049 vfsp = vfs_devsearch(dev);
1053 if (vfsp->vfs_fstype != efs_fstype)
1056 return efs_iincdec(vfsp, inode, inode_p1, amount);
1060 iinc(struct iincargs *uap, rval_t * rvp)
1063 return (iincdec(uap->dev, uap->inode, uap->inode_p1, 1));
1067 idec(struct iincargs *uap, rval_t * rvp)
1070 return (iincdec(uap->dev, uap->inode, uap->inode_p1, -1));
1072 #endif /* AFS_SGI65_ENV */
1074 #else /* AFS_SGI_XFS_IOPS_ENV */
1075 /* afs_syscall_iincdec iinc idec
1077 * These are the original EFS only entry points.
1080 afs_syscall_iincdec(dev, inode, inode_p1, amount)
1081 int dev, inode, inode_p1, amount;
1086 if (!afs_suser(NULL))
1088 if (error = igetinode(0, (dev_t) dev, inode, &ip))
1091 if (!IS_VICEMAGIC(ip))
1093 else if (((struct afsparms *)ip->i_afs)->vicep1 != inode_p1)
1096 ip->i_nlink += amount;
1097 osi_Assert(ip->i_nlink >= 0);
1098 if (ip->i_nlink == 0) {
1099 CLEAR_VICEMAGIC(ip);
1102 ip->i_flags |= ICHG;
1104 /* XXX sync write?? */
1116 iinc(struct iincargs *uap, rval_t * rvp)
1119 return (afs_syscall_iincdec(uap->dev, uap->inode, uap->inode_p1, 1));
1123 idec(struct iincargs *uap, rval_t * rvp)
1126 return (afs_syscall_iincdec(uap->dev, uap->inode, uap->inode_p1, -1));
1128 #endif /* AFS_SGI_XFS_IOPS_ENV */
1130 #ifdef AFS_SGI_XFS_IOPS_ENV
1131 /* afs_syscall_ilistinode64
1132 * Gathers up all required info for ListViceInodes in one system call.
1135 afs_syscall_ilistinode64(int dev, int inode_hi, int inode_lo, int datap,
1144 afs_xfs_attr_t attrs;
1146 i_list_inode_t data;
1149 if (!afs_suser(NULL))
1151 #ifdef AFS_SGI65_ENV
1152 vfsp = vfs_devsearch(dev, xfs_fstype);
1154 vfsp = vfs_devsearch(dev);
1159 #ifndef AFS_SGI65_ENV
1160 if (vfsp->vfs_fstype != xfs_fstype)
1164 AFS_COPYIN((char *)datalenp, &idatalen, sizeof(int), code);
1165 if (idatalen < sizeof(i_list_inode_t)) {
1166 idatalen = sizeof(i_list_inode_t);
1167 AFS_COPYOUT((char *)datalenp, (char *)&idatalen, sizeof(int), code);
1170 idatalen = sizeof(i_list_inode_t);
1171 AFS_COPYOUT((char *)datalenp, (char *)&idatalen, sizeof(int), code);
1173 AFS_COPYIN((char *)datap, (char *)&data, sizeof(i_list_inode_t), code);
1174 if (data.ili_version != AFS_XFS_ILI_VERSION) {
1175 data.ili_version = AFS_XFS_ILI_VERSION;
1176 AFS_COPYOUT((char *)&data, (char *)datap, sizeof(i_list_inode_t),
1186 xfs_iget((((struct mount *)((vfsp)->vfs_bh.bh_first)->bd_pdata)),
1187 (void *)0, (xfs_ino_t) inode, XFS_ILOCK_SHARED, &ip,
1193 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1195 length = SIZEOF_XFS_ATTR_T;
1197 AFS_VOP_ATTR_GET(vp, AFS_XFS_ATTR, (char *)&attrs, &length, ATTR_ROOT,
1198 OSI_GET_CURRENT_CRED(), code);
1204 if (attrs.at_attr_version != AFS_XFS_ATTR_VERS)
1209 vattr.va_mask = AT_STAT;
1210 AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), code);
1214 memset((char *)&data, 0, sizeof(data));
1215 data.ili_info.inodeNumber = inode;
1216 data.ili_info.byteCount = vattr.va_size;
1217 data.ili_info.linkCount = (vattr.va_mode & AFS_XFS_MODE_LINK_MASK);
1218 memcpy((char *)data.ili_info.param, (char *)attrs.at_param,
1219 sizeof(data.ili_info.param));
1220 data.ili_attr_version = attrs.at_attr_version;
1221 data.ili_name_version = attrs.at_name_version;
1222 data.ili_tag = attrs.at_tag;
1223 data.ili_pino = attrs.at_pino;
1224 data.ili_vno = vattr.va_uid;
1225 data.ili_magic = vattr.va_gid;
1226 AFS_COPYOUT((char *)&data, (char *)datap, sizeof(data), code);
1231 #endif /* AFS_SGI_XFS_IOPS_ENV */