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