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