convert-from-bsd-to-posix-string-and-memory-functions-20010807
[openafs.git] / src / afs / VNOPS / afs_vnop_fid.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11  * Implements:
12  * afs_fid
13  *
14  * afs_vptofh (DUX) is now in DUX/osi_vfsops.c
15  */
16
17 #include <afsconfig.h>
18 #include "../afs/param.h"
19
20 RCSID("$Header$");
21
22 #if !defined(AFS_DUX40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV)
23 #include "../afs/sysincludes.h" /* Standard vendor system headers */
24 #include "../afs/afsincludes.h" /* Afs-based standard headers */
25 #include "../afs/afs_stats.h" /* statistics */
26 #include "../afs/afs_cbqueue.h"
27 #include "../afs/nfsclient.h"
28 #include "../afs/afs_osidnlc.h"
29
30
31
32 int afs_fid_vnodeoverflow=0, afs_fid_uniqueoverflow=0;
33
34 /*
35  *  afs_fid
36  * 
37  * afs_fid can return two flavors of NFS fid, depending on if submounts are
38  * allowed. The reason for this is that we can't guarantee that we found all 
39  * the entry points any OS might use to get the fid for the NFS mountd.
40  * Hence we return a "magic" fid for all but /afs. If it goes through the
41  * translator code, it will get transformed into a SmallFid that we recognize.
42  * So, if submounts are disallowed, and an NFS client tries a submount, it will
43  * get a fid which we don't recognize and the mount will either fail or we
44  * will ignore subsequent requests for that mount.
45  *
46  * The Alpha fid is organized differently than for other platforms. Their
47  * intention was to have the data portion of the fid aligned on a 4 byte
48  * boundary. To do so, the fid is organized as:
49  * u_short reserved
50  * u_short len
51  * char data[8]
52  * The len field is the length of the entire fid, from reserved through data.
53  * This length is used by fid_copy to include copying the reserved field. 
54  * Alpha's zero the reserved field before handing us the fid, but they use
55  * it in fid_cmp. We use the reserved field to store the 16 bits of the Vnode.
56  *
57  * Note that the SmallFid only allows for 8 bits of the cell index and
58  * 16 bits of the vnode. 
59  */
60
61 #ifdef AFS_AIX41_ENV
62 int afs_iauth_initd = 0;
63 #define USE_SMALLFID(C) (afs_iauth_initd && AFS_NFSXLATORREQ(C))
64 #endif
65
66
67 extern int afs_NFSRootOnly; /* 1 => only allow NFS mounts of /afs. */
68 #if !defined(AFS_DEC_ENV) && !defined(AFS_ATHENA_ENV)
69 #ifdef AFS_AIX41_ENV
70 afs_fid(OSI_VC_ARG(avc), fidpp, credp)
71     struct ucred *credp ;
72 #else
73 afs_fid(OSI_VC_ARG(avc), fidpp)
74 #endif /* AFS_AIX41_ENV */
75 OSI_VC_DECL(avc);
76 #if     defined(AFS_AIX_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN54_ENV)
77 struct fid *fidpp;
78 #else
79 struct fid **fidpp;
80 #endif
81 {
82     struct SmallFid Sfid;
83     long addr[2];
84     register struct cell *tcell;
85     extern struct vcache *afs_globalVp;
86     int SizeOfSmallFid = SIZEOF_SMALLFID;
87     int rootvp = 0;
88     OSI_VC_CONVERT(avc)
89
90     AFS_STATCNT(afs_fid);
91
92     if (afs_shuttingdown) return EIO;
93
94     if (afs_NFSRootOnly && (avc == afs_globalVp)) rootvp = 1;
95     if (!afs_NFSRootOnly || rootvp
96 #ifdef AFS_AIX41_ENV
97         || USE_SMALLFID(credp)
98 #endif
99         ) {
100         tcell = afs_GetCell(avc->fid.Cell, READ_LOCK);
101         Sfid.Volume = avc->fid.Fid.Volume;
102         Sfid.Vnode =  avc->fid.Fid.Vnode;
103         Sfid.CellAndUnique = ((tcell->cellIndex << 24) +
104                               (avc->fid.Fid.Unique & 0xffffff));
105         afs_PutCell(tcell, READ_LOCK);
106         if (avc->fid.Fid.Vnode > 0xffff)
107             afs_fid_vnodeoverflow++;
108         if (avc->fid.Fid.Unique > 0xffffff)
109             afs_fid_uniqueoverflow++;
110     } else {
111 #if defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_SGI61_ENV) && (_MIPS_SZPTR == 64))
112         addr[1] = (long)AFS_XLATOR_MAGIC << 48 ;
113 #else /* defined(AFS_SGI61_ENV) && (_MIPS_SZPTR == 64) */
114         addr[1] = AFS_XLATOR_MAGIC;
115         SizeOfSmallFid = sizeof(addr);
116 #endif /* defined(AFS_SGI61_ENV) && (_MIPS_SZPTR == 64) */
117         addr[0] = (long)avc;
118 #ifndef AFS_AIX41_ENV
119         /* No post processing, so don't hold ref count. */
120         VN_HOLD((struct vnode *)avc);
121 #endif
122     }
123 #if     defined(AFS_AIX_ENV) || defined(AFS_SUN54_ENV)
124     /* Use the fid pointer passed to us. */
125     fidpp->fid_len = SizeOfSmallFid;
126
127     if (afs_NFSRootOnly) {
128         if (rootvp
129 #ifdef AFS_AIX41_ENV
130             ||  USE_SMALLFID(credp)
131 #endif
132             ) {
133             memcpy(fidpp->fid_data, (caddr_t)&Sfid, SizeOfSmallFid);   
134         } else {
135             memcpy(fidpp->fid_data, (caddr_t)addr, SizeOfSmallFid);   
136         }
137     } else {
138         memcpy(fidpp->fid_data, (caddr_t)&Sfid, SizeOfSmallFid);   
139     }
140 #else
141     /* malloc a fid pointer ourselves. */
142     *fidpp = (struct fid *) AFS_KALLOC(SizeOfSmallFid+2);
143     (*fidpp)->fid_len = SizeOfSmallFid;
144     if (afs_NFSRootOnly) {
145         if (rootvp) {
146             memcpy((*fidpp)->fid_data, (char *)&Sfid, SizeOfSmallFid);
147         } else {
148             memcpy((*fidpp)->fid_data, (char *)addr, SizeOfSmallFid);   
149         }
150     } else {
151         memcpy((*fidpp)->fid_data, (char *)&Sfid, SizeOfSmallFid);
152     }
153 #endif
154     return (0);
155 }
156 #endif
157
158
159 #endif /* !AFS_DUX40_ENV && !AFS_LINUX20_ENV */