pull-prototypes-to-head-20020821
[openafs.git] / src / afs / AIX / osi_vfsops.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  * osi_vfsops.c for AIX
12  */
13 #include <afsconfig.h>
14 #include "../afs/param.h"
15
16 RCSID("$Header$");
17
18 #include "../afs/sysincludes.h" /* Standard vendor system headers */
19 #include "../afs/afsincludes.h" /* Afs-based standard headers */
20 #include "../afs/afs_stats.h"   /* statistics stuff */
21
22
23 #ifdef AFS_AIX_IAUTH_ENV
24 #include "../afs/nfsclient.h"
25 #include "../afs/exporter.h"
26 extern struct afs_exporter      *afs_nfsexporter;
27 #endif
28
29 #define AFS_VFSLOCK_DECL register int glockOwner = ISAFS_GLOCK()
30 #define AFS_VFSLOCK()   if (!glockOwner) AFS_GLOCK()
31 #define AFS_VFSUNLOCK() if (!glockOwner) AFS_GUNLOCK()
32
33 struct vfs *afs_globalVFS = 0;
34 struct vcache *afs_globalVp = 0;
35
36
37 static int afs_root_nolock (struct vfs *afsp, struct vnode **avpp);
38
39 static int afs_mount(afsp, path, data)
40     char *path;
41     caddr_t data; 
42     struct vfs *afsp;
43 {
44     struct vnode *afsrootvp = NULL;
45     int error;
46     AFS_VFSLOCK_DECL;
47     AFS_VFSLOCK();
48     AFS_STATCNT(afs_mount);
49
50     if (afs_globalVFS) {
51         /* Don't allow remounts since some system (like AIX) don't handle
52          * it well.
53          */
54         AFS_VFSUNLOCK();
55         return (setuerror(EBUSY));
56     }
57
58
59     afs_globalVFS = afsp;
60     afsp->vfs_bsize = 8192;
61 #ifdef AFS_64BIT_CLIENT
62     afsp->vfs_flag |= VFS_DEVMOUNT;
63 #endif /* AFS_64BIT_CLIENT */
64
65     afsp->vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
66     afsp->vfs_fsid.val[1] = AFS_VFSFSID; 
67
68     /* For AFS, we don't allow file over file mounts. */
69        if (afsp->vfs_mntdover->v_type != VDIR)
70        return(ENOTDIR);
71        /* try to get the root vnode, but don't worry if you don't.  The actual
72         * setting of the root vnode (vfs_mntd) is done in afs_root, so that it
73         * get re-eval'd at the right time if things aren't working when we
74         * first try the mount.
75         */
76     afs_root_nolock(afsp, &afsrootvp);
77
78     afsp->vfs_mntdover->v_mvfsp = afsp;
79     afsp->vfs_mdata->vmt_flags |= MNT_REMOTE;
80
81 #ifdef AFS_AIX_IAUTH_ENV
82     if (afs_iauth_register()<0)
83         afs_warn("Can't register AFS iauth interface.\n");
84 #endif
85     AFS_VFSUNLOCK();
86     return 0;
87 }
88
89 static int afs_unmount (struct vfs *afsp, int flag)
90 {
91     AFS_VFSLOCK_DECL;
92     AFS_VFSLOCK();
93     AFS_STATCNT(afs_unmount);
94
95     afs_globalVFS = 0;
96     afs_shutdown();
97
98     AFS_VFSUNLOCK();
99     return 0;
100 }
101
102 static int afs_root_nolock (struct vfs *afsp, struct vnode **avpp)
103 {
104     register afs_int32 code = 0;
105     struct vrequest treq;
106     register struct vcache *tvp=0;
107
108     AFS_STATCNT(afs_root);
109     if (afs_globalVp && (afs_globalVp->states & CStatd)) {
110         tvp = afs_globalVp;
111     } else {
112         struct ucred *credp;
113         if (afs_globalVp) {
114             afs_PutVCache(afs_globalVp);
115             afs_globalVp = NULL;
116         }
117         credp = crref();
118         if (!(code = afs_InitReq(&treq, credp)) &&
119             !(code = afs_CheckInit())) {
120             tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
121             /* we really want this to stay around */
122             if (tvp) {
123                 afs_globalVp = tvp;
124             } else
125                 code = ENOENT;
126         }
127         crfree(credp);
128     }
129     if (tvp) {
130         VN_HOLD(AFSTOV(tvp));
131
132         VN_LOCK(AFSTOV(tvp));
133         AFSTOV(tvp)->v_flag |= VROOT;       /* No-op on Ultrix 2.2 */
134         VN_UNLOCK(AFSTOV(tvp));
135
136         afs_globalVFS = afsp;
137         *avpp = AFSTOV(tvp);
138         afsp->vfs_mntd = *avpp;   
139     }
140
141     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
142                ICL_TYPE_INT32, code);
143     return code;
144 }
145
146
147 static int afs_root (struct vfs *afsp, struct vnode **avpp)
148 {
149     int code;
150     AFS_VFSLOCK_DECL;
151     AFS_VFSLOCK();
152     code = afs_root_nolock(afsp, avpp);
153     AFS_VFSUNLOCK();
154     return code;
155 }
156
157 static int afs_statfs(struct vfs *afsp, struct statfs *abp,
158                       struct ucred *credp)
159 {
160     AFS_VFSLOCK_DECL;
161     AFS_VFSLOCK();
162     AFS_STATCNT(afs_statfs);
163
164     abp->f_version = 0;
165     abp->f_type = 0;
166     abp->f_bsize = afsp->vfs_bsize;
167     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
168         abp->f_ffree = 9000000;
169     abp->f_vfstype = AFS_VFSFSID;
170     abp->f_vfsnumber = afsp->vfs_number;
171     abp->f_vfsoff = abp->f_vfslen = abp->f_vfsvers = -1;
172     abp->f_fsize  = 4096;       /* fundamental filesystem block size */
173     abp->f_fsid = afsp->vfs_fsid;
174     (void) strcpy(abp->f_fname, "/afs");
175     (void) strcpy(abp->f_fpack, "AFS");
176     abp->f_name_max = 256;
177
178     AFS_VFSUNLOCK();
179     return 0;
180 }
181
182 static int afs_sync()
183 {
184     AFS_VFSLOCK_DECL;
185     AFS_VFSLOCK();
186     AFS_STATCNT(afs_sync);
187
188     AFS_VFSUNLOCK();
189     return 0;
190 }
191
192
193 /* Note that the cred is only for AIX 4.1.5+ and AIX 4.2+ */
194 static int afs_vget(struct vfs *vfsp, struct vnode **avcp, struct fileid *fidp,
195          struct ucred *credp)
196 {
197     int code;
198     struct vrequest treq;
199     AFS_VFSLOCK_DECL;
200     AFS_VFSLOCK();
201     AFS_STATCNT(afs_vget);
202     *avcp = NULL;
203
204 #ifdef AFS_AIX_IAUTH_ENV
205     /* If the exporter is off and this is an nfsd, fail immediately. */
206     if (AFS_NFSXLATORREQ(credp)
207         && !(afs_nfsexporter->exp_states & EXP_EXPORTED)) {
208         return EACCES;
209     }
210 #endif
211
212     if ((code = afs_InitReq(&treq, credp))==0) {
213         code = afs_osi_vget((struct vcache**)avcp, fidp, &treq);
214     }
215
216     afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
217                ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp);
218     code = afs_CheckCode(code, &treq, 42);
219
220     AFS_VFSUNLOCK();
221     return code;
222 }
223      
224 static int afs_badop()
225 {
226     return EOPNOTSUPP;
227 }
228
229
230 struct vfsops Afs_vfsops = {
231         afs_mount,
232         afs_unmount,
233         afs_root,
234         afs_statfs,
235         afs_sync,
236         afs_vget,
237         afs_badop,      /* vfs_cntl */
238         afs_badop       /* vfs_quotactl */
239 };
240
241 /*
242  * VFS is initialized in osi_config.c
243  */