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