convert-vcache-casts-to-macros-20020325
[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         credp = crref();
114         if (!(code = afs_InitReq(&treq, credp)) &&
115             !(code = afs_CheckInit())) {
116             tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0,
117                                 (struct vcache*)0, WRITE_LOCK);
118             /* we really want this to stay around */
119             if (tvp) {
120                 afs_globalVp = tvp;
121             } else
122                 code = ENOENT;
123         }
124         crfree(credp);
125     }
126     if (tvp) {
127         VN_HOLD(AFSTOV(tvp));
128
129         VN_LOCK(AFSTOV(tvp));
130         AFSTOV(tvp)->v_flag |= VROOT;       /* No-op on Ultrix 2.2 */
131         VN_UNLOCK(AFSTOV(tvp));
132
133         afs_globalVFS = afsp;
134         *avpp = AFSTOV(tvp);
135         afsp->vfs_mntd = *avpp;   
136     }
137
138     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
139                ICL_TYPE_INT32, code);
140     return code;
141 }
142
143
144 static int afs_root (struct vfs *afsp, struct vnode **avpp)
145 {
146     int code;
147     AFS_VFSLOCK_DECL;
148     AFS_VFSLOCK();
149     code = afs_root_nolock(afsp, avpp);
150     AFS_VFSUNLOCK();
151     return code;
152 }
153
154 static int afs_statfs(struct vfs *afsp, struct statfs *abp,
155                       struct ucred *credp)
156 {
157     AFS_VFSLOCK_DECL;
158     AFS_VFSLOCK();
159     AFS_STATCNT(afs_statfs);
160
161     abp->f_version = 0;
162     abp->f_type = 0;
163     abp->f_bsize = afsp->vfs_bsize;
164     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
165         abp->f_ffree = 9000000;
166     abp->f_vfstype = AFS_VFSFSID;
167     abp->f_vfsnumber = afsp->vfs_number;
168     abp->f_vfsoff = abp->f_vfslen = abp->f_vfsvers = -1;
169     abp->f_fsize  = 4096;       /* fundamental filesystem block size */
170     abp->f_fsid = afsp->vfs_fsid;
171     (void) strcpy(abp->f_fname, "/afs");
172     (void) strcpy(abp->f_fpack, "AFS");
173     abp->f_name_max = 256;
174
175     AFS_VFSUNLOCK();
176     return 0;
177 }
178
179 static int afs_sync()
180 {
181     AFS_VFSLOCK_DECL;
182     AFS_VFSLOCK();
183     AFS_STATCNT(afs_sync);
184
185     AFS_VFSUNLOCK();
186     return 0;
187 }
188
189
190 /* Note that the cred is only for AIX 4.1.5+ and AIX 4.2+ */
191 static int afs_vget(struct vfs *vfsp, struct vnode **avcp, struct fileid *fidp,
192          struct ucred *credp)
193 {
194     int code;
195     struct vrequest treq;
196     AFS_VFSLOCK_DECL;
197     AFS_VFSLOCK();
198     AFS_STATCNT(afs_vget);
199     *avcp = NULL;
200
201 #ifdef AFS_AIX_IAUTH_ENV
202     /* If the exporter is off and this is an nfsd, fail immediately. */
203     if (AFS_NFSXLATORREQ(credp)
204         && !(afs_nfsexporter->exp_states & EXP_EXPORTED)) {
205         return EACCES;
206     }
207 #endif
208
209     if ((code = afs_InitReq(&treq, credp))==0) {
210         code = afs_osi_vget((struct vcache**)avcp, fidp, &treq);
211     }
212
213     afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
214                ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp);
215     code = afs_CheckCode(code, &treq, 42);
216
217     AFS_VFSUNLOCK();
218     return code;
219 }
220      
221 static int afs_badop()
222 {
223     return EOPNOTSUPP;
224 }
225
226
227 struct vfsops Afs_vfsops = {
228         afs_mount,
229         afs_unmount,
230         afs_root,
231         afs_statfs,
232         afs_sync,
233         afs_vget,
234         afs_badop,      /* vfs_cntl */
235         afs_badop       /* vfs_quotactl */
236 };
237
238 /*
239  * VFS is initialized in osi_config.c
240  */