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
16 #include <afsconfig.h>
17 #include "afs/param.h"
20 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_OBSD_ENV) && !defined(AFS_NBSD_ENV)
21 #include "afs/sysincludes.h" /* Standard vendor system headers */
22 #include "afsincludes.h" /* Afs-based standard headers */
23 #include "afs/afs_stats.h" /* statistics */
24 #include "afs/afs_cbqueue.h"
25 #include "afs/nfsclient.h"
26 #include "afs/afs_osidnlc.h"
30 int afs_fid_vnodeoverflow
= 0, afs_fid_uniqueoverflow
= 0;
35 * afs_fid can return two flavors of NFS fid, depending on if submounts are
36 * allowed. The reason for this is that we can't guarantee that we found all
37 * the entry points any OS might use to get the fid for the NFS mountd.
38 * Hence we return a "magic" fid for all but /afs. If it goes through the
39 * translator code, it will get transformed into a SmallFid that we recognize.
40 * So, if submounts are disallowed, and an NFS client tries a submount, it will
41 * get a fid which we don't recognize and the mount will either fail or we
42 * will ignore subsequent requests for that mount.
44 * The Alpha fid is organized differently than for other platforms. Their
45 * intention was to have the data portion of the fid aligned on a 4 byte
46 * boundary. To do so, the fid is organized as:
50 * The len field is the length of the entire fid, from reserved through data.
51 * This length is used by fid_copy to include copying the reserved field.
52 * Alpha's zero the reserved field before handing us the fid, but they use
53 * it in fid_cmp. We use the reserved field to store the 16 bits of the Vnode.
55 * Note that the SmallFid only allows for 8 bits of the cell index and
56 * 16 bits of the vnode.
60 int afs_iauth_initd
= 0;
61 #define USE_SMALLFID(C) (afs_iauth_initd && AFS_NFSXLATORREQ(C))
65 extern int afs_NFSRootOnly
; /* 1 => only allow NFS mounts of /afs. */
69 afs_fid(OSI_VC_DECL(avc
), struct fid
*fidpp
, struct ucred
*credp
)
70 #elif defined(AFS_SUN5_ENV)
71 afs_fid(OSI_VC_DECL(avc
), struct fid
*fidpp
)
73 afs_fid(OSI_VC_DECL(avc
), struct fid
**fidpp
)
74 #endif /* AFS_AIX41_ENV */
79 extern struct vcache
*afs_globalVp
;
80 int SizeOfSmallFid
= SIZEOF_SMALLFID
;
86 if (afs_shuttingdown
!= AFS_RUNNING
)
89 if (afs_NFSRootOnly
&& (avc
== afs_globalVp
))
91 if (!afs_NFSRootOnly
|| rootvp
93 || USE_SMALLFID(credp
)
96 tcell
= afs_GetCell(avc
->f
.fid
.Cell
, READ_LOCK
);
97 Sfid
.Volume
= avc
->f
.fid
.Fid
.Volume
;
98 Sfid
.Vnode
= avc
->f
.fid
.Fid
.Vnode
;
100 ((tcell
->cellIndex
<< 24) + (avc
->f
.fid
.Fid
.Unique
& 0xffffff));
101 afs_PutCell(tcell
, READ_LOCK
);
102 if (avc
->f
.fid
.Fid
.Vnode
> 0xffff)
103 afs_fid_vnodeoverflow
++;
104 if (avc
->f
.fid
.Fid
.Unique
> 0xffffff)
105 afs_fid_uniqueoverflow
++;
107 #if defined(AFS_SUN5_64BIT_ENV) || (defined(AFS_SGI61_ENV) && (_MIPS_SZPTR == 64))
108 addr
[1] = (long)AFS_XLATOR_MAGIC
<< 48;
109 #else /* defined(AFS_SGI61_ENV) && (_MIPS_SZPTR == 64) */
110 addr
[1] = AFS_XLATOR_MAGIC
;
111 SizeOfSmallFid
= sizeof(addr
);
112 #endif /* defined(AFS_SGI61_ENV) && (_MIPS_SZPTR == 64) */
114 #ifndef AFS_AIX41_ENV
115 /* No post processing, so don't hold ref count. */
119 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
120 /* Use the fid pointer passed to us. */
121 fidpp
->fid_len
= SizeOfSmallFid
;
123 if (afs_NFSRootOnly
) {
126 || USE_SMALLFID(credp
)
129 memcpy(fidpp
->fid_data
, (caddr_t
) & Sfid
, SizeOfSmallFid
);
131 memcpy(fidpp
->fid_data
, (caddr_t
) addr
, SizeOfSmallFid
);
134 memcpy(fidpp
->fid_data
, (caddr_t
) & Sfid
, SizeOfSmallFid
);
137 /* malloc a fid pointer ourselves. */
138 *fidpp
= (struct fid
*)AFS_KALLOC(SizeOfSmallFid
+ 2);
139 (*fidpp
)->fid_len
= SizeOfSmallFid
;
140 if (afs_NFSRootOnly
) {
142 memcpy((*fidpp
)->fid_data
, (char *)&Sfid
, SizeOfSmallFid
);
144 memcpy((*fidpp
)->fid_data
, (char *)addr
, SizeOfSmallFid
);
147 memcpy((*fidpp
)->fid_data
, (char *)&Sfid
, SizeOfSmallFid
);
154 #endif /* !AFS_LINUX20_ENV */