no-copy-libafs-builds-20021015
[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 "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     afsp->vfs_count = 0;
62 #ifdef AFS_64BIT_CLIENT
63     afsp->vfs_flag |= VFS_DEVMOUNT;
64 #endif /* AFS_64BIT_CLIENT */
65
66     afsp->vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
67     afsp->vfs_fsid.val[1] = AFS_VFSFSID; 
68
69     /* For AFS, we don't allow file over file mounts. */
70        if (afsp->vfs_mntdover->v_type != VDIR)
71        return(ENOTDIR);
72        /* try to get the root vnode, but don't worry if you don't.  The actual
73         * setting of the root vnode (vfs_mntd) is done in afs_root, so that it
74         * get re-eval'd at the right time if things aren't working when we
75         * first try the mount.
76         */
77     afs_root_nolock(afsp, &afsrootvp);
78
79     afsp->vfs_mntdover->v_mvfsp = afsp;
80     afsp->vfs_mdata->vmt_flags |= MNT_REMOTE;
81
82 #ifdef AFS_AIX_IAUTH_ENV
83     if (afs_iauth_register()<0)
84         afs_warn("Can't register AFS iauth interface.\n");
85 #endif
86     AFS_VFSUNLOCK();
87     return 0;
88 }
89
90 static int afs_unmount (struct vfs *afsp, int flag)
91 {
92     AFS_VFSLOCK_DECL;
93     AFS_VFSLOCK();
94     AFS_STATCNT(afs_unmount);
95
96     afs_globalVFS = 0;
97     afs_shutdown();
98
99     AFS_VFSUNLOCK();
100     return 0;
101 }
102
103 static int afs_root_nolock (struct vfs *afsp, struct vnode **avpp)
104 {
105     register afs_int32 code = 0;
106     struct vrequest treq;
107     register struct vcache *tvp=0;
108
109     AFS_STATCNT(afs_root);
110     if (afs_globalVp && (afs_globalVp->states & CStatd)) {
111         tvp = afs_globalVp;
112     } else {
113         struct ucred *credp;
114         if (afs_globalVp) {
115             afs_PutVCache(afs_globalVp);
116             afs_globalVp = NULL;
117         }
118         credp = crref();
119         if (!(code = afs_InitReq(&treq, credp)) &&
120             !(code = afs_CheckInit())) {
121             tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
122             /* we really want this to stay around */
123             if (tvp) {
124                 afs_globalVp = tvp;
125             } else
126                 code = ENOENT;
127         }
128         crfree(credp);
129     }
130     if (tvp) {
131         VN_HOLD(AFSTOV(tvp));
132
133         VN_LOCK(AFSTOV(tvp));
134         AFSTOV(tvp)->v_flag |= VROOT;       /* No-op on Ultrix 2.2 */
135         VN_UNLOCK(AFSTOV(tvp));
136
137         afs_globalVFS = afsp;
138         *avpp = AFSTOV(tvp);
139         afsp->vfs_mntd = *avpp;   
140     }
141
142     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
143                ICL_TYPE_INT32, code);
144     return code;
145 }
146
147
148 static int afs_root (struct vfs *afsp, struct vnode **avpp)
149 {
150     int code;
151     AFS_VFSLOCK_DECL;
152     AFS_VFSLOCK();
153     code = afs_root_nolock(afsp, avpp);
154     AFS_VFSUNLOCK();
155     return code;
156 }
157
158 static int afs_statfs(struct vfs *afsp, struct statfs *abp,
159                       struct ucred *credp)
160 {
161     AFS_VFSLOCK_DECL;
162     AFS_VFSLOCK();
163     AFS_STATCNT(afs_statfs);
164
165     abp->f_version = 0;
166     abp->f_type = 0;
167     abp->f_bsize = afsp->vfs_bsize;
168     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
169         abp->f_ffree = 9000000;
170     abp->f_vfstype = AFS_VFSFSID;
171     abp->f_vfsnumber = afsp->vfs_number;
172     abp->f_vfsoff = abp->f_vfslen = abp->f_vfsvers = -1;
173     abp->f_fsize  = 4096;       /* fundamental filesystem block size */
174     abp->f_fsid = afsp->vfs_fsid;
175     (void) strcpy(abp->f_fname, "/afs");
176     (void) strcpy(abp->f_fpack, "AFS");
177     abp->f_name_max = 256;
178
179     AFS_VFSUNLOCK();
180     return 0;
181 }
182
183 static int afs_sync()
184 {
185     AFS_VFSLOCK_DECL;
186     AFS_VFSLOCK();
187     AFS_STATCNT(afs_sync);
188
189     AFS_VFSUNLOCK();
190     return 0;
191 }
192
193
194 /* Note that the cred is only for AIX 4.1.5+ and AIX 4.2+ */
195 static int afs_vget(struct vfs *vfsp, struct vnode **avcp, struct fileid *fidp,
196          struct ucred *credp)
197 {
198     int code;
199     struct vrequest treq;
200     AFS_VFSLOCK_DECL;
201     AFS_VFSLOCK();
202     AFS_STATCNT(afs_vget);
203     *avcp = NULL;
204
205 #ifdef AFS_AIX_IAUTH_ENV
206     /* If the exporter is off and this is an nfsd, fail immediately. */
207     if (AFS_NFSXLATORREQ(credp)
208         && !(afs_nfsexporter->exp_states & EXP_EXPORTED)) {
209         return EACCES;
210     }
211 #endif
212
213     if ((code = afs_InitReq(&treq, credp))==0) {
214         code = afs_osi_vget((struct vcache**)avcp, fidp, &treq);
215     }
216
217     afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
218                ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp);
219     code = afs_CheckCode(code, &treq, 42);
220
221     AFS_VFSUNLOCK();
222     return code;
223 }
224      
225 static int afs_badop()
226 {
227     return EOPNOTSUPP;
228 }
229
230
231 struct vfsops Afs_vfsops = {
232         afs_mount,
233         afs_unmount,
234         afs_root,
235         afs_statfs,
236         afs_sync,
237         afs_vget,
238         afs_badop,      /* vfs_cntl */
239         afs_badop       /* vfs_quotactl */
240 #ifdef AFS_AIX51_ENV
241         ,afs_badop      /* vfs_syncvfs */
242 #endif
243 };
244
245 /*
246  * VFS is initialized in osi_config.c
247  */