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