discon-allow-saving-vcaches-on-shutdown-20090126
[openafs.git] / src / afs / HPUX / 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 HPUX
12  */
13 #include <afsconfig.h>
14 #include "afs/param.h"
15
16 RCSID
17     ("$Header$");
18
19 #include "afs/sysincludes.h"    /* Standard vendor system headers */
20 #include "afsincludes.h"        /* Afs-based standard headers */
21 #include "afs/afs_stats.h"      /* statistics stuff */
22 #include <sys/scall_kernprivate.h>
23
24 #if defined(AFS_HPUX1123_ENV)
25 #include <sys/moddefs.h>
26 #endif /* AFS_HPUX1123_ENV */
27
28 #if defined(AFS_HPUX1123_ENV)
29 /* defind DLKM tables  so we can load dynamicly */
30 /* we still need an afs_unload to unload */
31 /* Note: There is to be a dependency on the
32  * the name of the struct <name>_wrapper, and the 
33  * name of the dynamicly loaded file <name>  
34  * We will define -DAFS_WRAPPER=<name>_wrapper
35  * and -DAFS_CONF_DATA=<name>_conf_data  and pass into
36  * this routine 
37  */ 
38
39 extern struct mod_operations mod_misc_ops;
40 extern struct mod_conf_data AFS_CONF_DATA;
41
42 static int afs_load(void *arg);
43 /* static int afs_unload(void *arg); */
44
45 struct mod_type_data afs_mod_link = {
46         "AFS kernel module", 
47         NULL
48 };
49
50 struct modlink afs_modlink[] = {
51         {&mod_misc_ops, &afs_mod_link},
52         { NULL, NULL }
53 };
54
55 struct modwrapper AFS_WRAPPER = {
56         MODREV, 
57         afs_load, 
58         NULL,      /* should be afs_unload if we had one */ 
59         NULL,
60         &AFS_CONF_DATA, 
61         afs_modlink 
62 }; 
63
64 #endif /* AFS_HPUX1123_ENV */
65
66 static char afs_mountpath[512];
67 struct vfs *afs_globalVFS = 0;
68 struct vcache *afs_globalVp = 0;
69
70 int
71 afs_mount(struct vfs *afsp, char *path, smountargs_t * data)
72 {
73     AFS_GLOCK();
74     AFS_STATCNT(afs_mount);
75
76     if (afs_globalVFS) {        /* Don't allow remounts. */
77         AFS_GUNLOCK();
78         return (setuerror(EBUSY));
79     }
80
81     afs_globalVFS = afsp;
82     afsp->vfs_bsize = 8192;
83     afsp->vfs_fsid[0] = AFS_VFSMAGIC;   /* magic */
84     afsp->vfs_fsid[1] = AFS_VFSFSID;
85     strcpy(afsp->vfs_name, "AFS");
86     afsp->vfs_name[3] = '\0';
87
88     strncpy(afs_mountpath, path, sizeof(afs_mountpath));
89     afs_mountpath[sizeof afs_mountpath - 1] = '\0';
90
91 #ifndef AFS_NONFSTRANS
92     /* Set up the xlator in case it wasn't done elsewhere */
93     afs_xlatorinit_v2();
94 #endif
95
96     AFS_GUNLOCK();
97     return 0;
98 }
99
100
101 int
102 afs_unmount(struct vfs *afsp)
103 {
104     AFS_GLOCK();
105     AFS_STATCNT(afs_unmount);
106
107     afs_globalVFS = 0;
108     afs_shutdown();
109
110     AFS_GUNLOCK();
111     return 0;
112 }
113
114 int
115 afs_root(struct vfs *afsp, struct vnode **avpp, char *unused1)
116 {
117     int code = 0;
118     struct vrequest treq;
119     register struct vcache *tvp = 0;
120     AFS_GLOCK();
121     AFS_STATCNT(afs_root);
122
123     if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
124         tvp = afs_globalVp;
125     } else {
126         if (afs_globalVp) {
127             afs_PutVCache(afs_globalVp);
128             afs_globalVp = NULL;
129         }
130
131         if (!(code = afs_InitReq(&treq, p_cred(u.u_procp)))
132             && !(code = afs_CheckInit())) {
133             tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
134             /* we really want this to stay around */
135             if (tvp) {
136                 afs_globalVp = tvp;
137             } else
138                 code = ENOENT;
139         }
140     }
141     if (tvp) {
142         VN_HOLD(AFSTOV(tvp));
143         SET_V_FLAG(AFSTOV(tvp), VROOT);
144
145         afs_globalVFS = afsp;
146         *avpp = AFSTOV(tvp);
147     }
148
149     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
150                ICL_TYPE_INT32, code);
151
152     AFS_GUNLOCK();
153     return code;
154 }
155
156 int
157 afs_statfs(register struct vfs *afsp, struct k_statvfs *abp)
158 {
159     AFS_GLOCK();
160     AFS_STATCNT(afs_statfs);
161
162     abp->f_type = 0;
163     abp->f_frsize = 1024;
164     abp->f_bsize = afsp->vfs_bsize;
165     /* Fake a high number below to satisfy programs that use the statfs
166      * call to make sure that there's enough space in the device partition
167      * before storing something there.
168      */
169     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
170         abp->f_ffree = abp->f_favail = 9000000;
171     abp->f_fsid = (AFS_VFSMAGIC << 16) || AFS_VFSFSID;
172
173     AFS_GUNLOCK();
174     return 0;
175 }
176
177 int
178 afs_sync(struct vfs *unused1, int unused2)
179 {
180     AFS_STATCNT(afs_sync);
181     return 0;
182 }
183
184 int
185 afs_vget(struct vfs *afsp, struct vnode **avcp, struct fid *fidp)
186 {
187     int code;
188     struct vrequest treq;
189     AFS_GLOCK();
190     AFS_STATCNT(afs_vget);
191
192     *avcp = NULL;
193
194     if ((code = afs_InitReq(&treq, p_cred(u.u_procp))) == 0) {
195         code = afs_osi_vget((struct vcache **)avcp, fidp, &treq);
196     }
197
198     afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
199                ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp);
200     code = afs_CheckCode(code, &treq, 42);
201
202     AFS_GUNLOCK();
203     return code;
204 }
205
206 int
207 afs_getmount(struct vfs *vfsp, char *fsmntdir, struct mount_data *mdp,
208              char *unused1)
209 {
210     int l;
211
212     mdp->md_msite = 0;
213     mdp->md_dev = 0;
214     mdp->md_rdev = 0;
215     return (copyoutstr
216             (afs_mountpath, fsmntdir, strlen(afs_mountpath) + 1, &l));
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_getmount,
228     (vfs_freeze_t *) 0,         /* vfs_freeze */
229     (vfs_thaw_t *) 0,           /* vfs_thaw */
230     (vfs_quota_t *) 0,          /* vfs_quota */
231     (vfs_mountroot_t *) 0,      /* vfs_mountroot. Note: afs_mountroot_nullop in this
232                                  *                position panicked HP 11.00+
233                                  */
234     (vfs_size_t *) 0            /* vfs_size */
235 };
236
237 static int afs_Starting = 0;
238
239 #pragma align 64
240 #if !defined(AFS_HPUX110_ENV)
241 sema_t afs_global_sema = {
242     NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0,       /* sa_type */
243     0, 0, 0, 0, 0, 0, 0, NULL,  /* sa_link */
244     NULL, NULL
245 #ifdef SEMA_COUNTING
246         , 0, 0, 0, NULL
247 #endif
248 };
249 #else
250 b_sema_t afs_global_sema = { 0 };
251 #endif
252
253 void
254 osi_InitGlock()
255 {
256     register ulong_t context;
257
258     SPINLOCK_USAV(sched_lock, context);
259     if (!afs_Starting) {
260         afs_Starting = 1;
261         SPINUNLOCK_USAV(sched_lock, context);
262 #if defined(AFS_HPUX110_ENV)
263         b_initsema(&afs_global_sema, 1, NFS_LOCK_ORDER2, "AFS GLOCK");
264         /* afsHash(64); *//* 64 buckets */
265 #else
266         initsema(&afs_global_sema, 1, FILESYS_SEMA_PRI, FILESYS_SEMA_ORDER);
267         afsHash(64);            /* 64 buckets */
268 #endif
269     } else {
270         SPINUNLOCK_USAV(sched_lock, context);
271     }
272     if (!afs_Starting) {
273         osi_Panic("osi_Init lost initialization race");
274     }
275 }
276
277 #if defined(AFS_HPUX1123_ENV)
278 /* DLKM routine called when loaded */
279 static int
280 afs_load(void *arg)
281 {
282         afsc_link();
283         return 0;
284 }
285 #endif /* AFS_HPUX1123_ENV */
286
287 /*
288  * afsc_link - Initialize VFS
289  */
290 int afs_vfs_slot = -1;
291
292
293 afsc_link()
294 {
295     extern int Afs_syscall(), afs_xioctl(), Afs_xsetgroups();
296
297     /* For now nothing special is required during AFS initialization. */
298     AFS_STATCNT(afsc_link);
299     osi_Init();
300     if ((afs_vfs_slot = add_vfs_type("afs", &Afs_vfsops)) < 0)
301         return;
302     sysent_assign_function(AFS_SYSCALL, 7, (void (*)())Afs_syscall,
303                            "Afs_syscall");
304     sysent_define_arg(AFS_SYSCALL, 0, longArg);
305     sysent_define_arg(AFS_SYSCALL, 1, longArg);
306     sysent_define_arg(AFS_SYSCALL, 2, longArg);
307     sysent_define_arg(AFS_SYSCALL, 3, longArg);
308     sysent_define_arg(AFS_SYSCALL, 4, longArg);
309     sysent_define_arg(AFS_SYSCALL, 5, longArg);
310     sysent_define_arg(AFS_SYSCALL, 6, longArg);
311     sysent_returns_long(AFS_SYSCALL);
312
313     sysent_delete(80);
314     sysent_assign_function(80, 2, (void (*)())Afs_xsetgroups, "setgroups");
315     sysent_define_arg(80, 0, longArg);
316     sysent_define_arg(80, 1, longArg);
317     sysent_returns_long(80);
318     return 0;
319 }