hpux11i-20030310
[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("$Header$");
17
18 #include "afs/sysincludes.h"    /* Standard vendor system headers */
19 #include "afsincludes.h"        /* Afs-based standard headers */
20 #include "afs/afs_stats.h"   /* statistics stuff */
21 #include <sys/scall_kernprivate.h>
22
23
24 static char afs_mountpath[512];
25 struct vfs *afs_globalVFS = 0;
26 struct vcache *afs_globalVp = 0;
27
28 int afs_mount(struct vfs *afsp, char *path, smountargs_t *data)
29 {
30     AFS_GLOCK();
31     AFS_STATCNT(afs_mount);
32
33     if (afs_globalVFS) { /* Don't allow remounts. */
34         AFS_GUNLOCK();
35         return (setuerror(EBUSY));
36     }
37
38     afs_globalVFS = afsp;
39     afsp->vfs_bsize = 8192;
40     afsp->vfs_fsid[0] = AFS_VFSMAGIC; /* magic */
41     afsp->vfs_fsid[1] = AFS_VFSFSID; 
42     strcpy(afsp->vfs_name, "AFS");
43     afsp->vfs_name[3] = '\0';
44
45     strncpy(afs_mountpath, path, sizeof(afs_mountpath));
46     afs_mountpath[sizeof afs_mountpath - 1] = '\0';
47
48 #ifndef AFS_NONFSTRANS
49     /* Set up the xlator in case it wasn't done elsewhere */
50     afs_xlatorinit_v2(); 
51 #endif
52
53     AFS_GUNLOCK();
54     return 0;
55 }
56
57
58 int afs_unmount(struct vfs *afsp)
59 {
60     AFS_GLOCK();
61     AFS_STATCNT(afs_unmount);
62
63     afs_globalVFS = 0;
64     afs_shutdown();
65
66     AFS_GUNLOCK();
67     return 0;
68 }       
69
70 int afs_root (struct vfs *afsp, struct vnode **avpp, char *unused1)
71 {
72     int code = 0;
73     struct vrequest treq;
74     register struct vcache *tvp=0;
75     AFS_GLOCK();
76     AFS_STATCNT(afs_root);
77
78     if (afs_globalVp && (afs_globalVp->states & CStatd)) {
79         tvp = afs_globalVp;
80     } else {
81         if (afs_globalVp) {
82             afs_PutVCache(afs_globalVp);
83             afs_globalVp = NULL;
84         }
85
86         if (!(code = afs_InitReq(&treq,  p_cred(u.u_procp))) &&
87             !(code = afs_CheckInit())) {
88             tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
89             /* we really want this to stay around */
90             if (tvp) {
91                 afs_globalVp = tvp;
92             } else
93                 code = ENOENT;
94         }
95     }
96     if (tvp) {
97         VN_HOLD(AFSTOV(tvp));
98         SET_V_FLAG(AFSTOV(tvp), VROOT);
99
100         afs_globalVFS = afsp;
101         *avpp = AFSTOV(tvp);
102     }
103
104     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
105                ICL_TYPE_INT32, code);
106
107     AFS_GUNLOCK();
108     return code;
109 }       
110
111 int afs_statfs(register struct vfs *afsp, struct k_statvfs *abp)
112 {
113     AFS_GLOCK();
114     AFS_STATCNT(afs_statfs);
115
116     abp->f_type = 0;
117     abp->f_frsize = 1024;
118     abp->f_bsize = afsp->vfs_bsize;
119     /* Fake a high number below to satisfy programs that use the statfs
120      * call to make sure that there's enough space in the device partition
121      * before storing something there.
122      */
123     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
124         abp->f_ffree = abp->f_favail = 9000000;
125     abp->f_fsid = (AFS_VFSMAGIC << 16) || AFS_VFSFSID;
126
127     AFS_GUNLOCK();
128     return 0;
129 }       
130
131 int afs_sync(struct vfs *unused1, int unused2)
132 {
133     AFS_STATCNT(afs_sync);
134     return 0;
135 }
136
137 int afs_vget(struct vfs *afsp, struct vnode **avcp, struct fid *fidp)
138 {
139     int code;
140     struct vrequest treq;
141     AFS_GLOCK();
142     AFS_STATCNT(afs_vget);
143
144     * avcp = NULL;
145
146     if ((code = afs_InitReq(&treq, p_cred(u.u_procp)))==0) {
147         code = afs_osi_vget((struct vcache**)avcp, fidp, &treq);
148     }
149
150     afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
151                ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp);
152     code = afs_CheckCode(code, &treq, 42);
153
154     AFS_GUNLOCK();
155     return code;
156 }       
157
158 int afs_getmount(struct vfs *vfsp, char *fsmntdir, struct mount_data *mdp, char *unused1)
159 {
160     int l;
161
162     mdp->md_msite = 0;
163     mdp->md_dev = 0;
164     mdp->md_rdev = 0;
165     return(copyoutstr(afs_mountpath, fsmntdir, strlen(afs_mountpath)+1, &l));
166 }
167
168
169 struct vfsops Afs_vfsops = {
170     afs_mount,
171     afs_unmount,
172     afs_root,
173     afs_statfs,
174     afs_sync,
175     afs_vget,
176     afs_getmount,
177     (vfs_freeze_t *)0,  /* vfs_freeze */
178     (vfs_thaw_t *)0,    /* vfs_thaw */
179     (vfs_quota_t *)0,   /* vfs_quota */
180     (vfs_mountroot_t *)0,               /* vfs_mountroot. Note: afs_mountroot_nullop in this
181                          *                position panicked HP 11.00+
182                          */
183     (vfs_size_t *)0     /* vfs_size */
184 };
185
186 static int afs_Starting = 0;
187
188 #pragma align 64
189 #if !defined(AFS_HPUX110_ENV)
190 sema_t afs_global_sema = {
191    NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, /* sa_type */
192    0, 0, 0, 0, 0, 0, 0, NULL, /* sa_link */
193    NULL, NULL
194 #ifdef SEMA_COUNTING
195    , 0, 0, 0, NULL
196 #endif
197   };
198 #else
199 b_sema_t afs_global_sema = {0}; 
200 #endif
201
202 void
203 osi_InitGlock()
204 {
205     register ulong_t context;
206
207     SPINLOCK_USAV(sched_lock, context);
208     if ( !afs_Starting ) {
209         afs_Starting = 1;
210         SPINUNLOCK_USAV(sched_lock, context);
211 #if defined(AFS_HPUX110_ENV)
212         b_initsema(&afs_global_sema, 1,  NFS_LOCK_ORDER2, "AFS GLOCK");
213         /* afsHash(64); */      /* 64 buckets */
214 #else
215     initsema(&afs_global_sema, 1, FILESYS_SEMA_PRI, FILESYS_SEMA_ORDER);
216           afsHash(64);  /* 64 buckets */
217 #endif
218     } else {
219         SPINUNLOCK_USAV(sched_lock, context);
220     }
221     if (!afs_Starting) {
222         osi_Panic("osi_Init lost initialization race");
223     }
224 }
225
226 /*
227  * afsc_link - Initialize VFS
228  */
229 int afs_vfs_slot=-1; 
230
231
232 afsc_link()
233 {
234     extern int Afs_syscall(), afs_xioctl(), Afs_xsetgroups();
235
236     /* For now nothing special is required during AFS initialization. */
237     AFS_STATCNT(afsc_link);
238     osi_Init();         
239     if ( (afs_vfs_slot=add_vfs_type("afs", &Afs_vfsops)) < 0 )
240         return;
241     sysent_assign_function(AFS_SYSCALL, 7, (void (*)())Afs_syscall, "Afs_syscall");
242     sysent_define_arg(AFS_SYSCALL, 0, longArg);
243     sysent_define_arg(AFS_SYSCALL, 1, longArg);
244     sysent_define_arg(AFS_SYSCALL, 2, longArg);
245     sysent_define_arg(AFS_SYSCALL, 3, longArg);
246     sysent_define_arg(AFS_SYSCALL, 4, longArg);
247     sysent_define_arg(AFS_SYSCALL, 5, longArg);
248     sysent_define_arg(AFS_SYSCALL, 6, longArg);
249     sysent_returns_long(AFS_SYSCALL);
250
251     sysent_delete(80);
252     sysent_assign_function(80, 2, (void (*)())Afs_xsetgroups, "setgroups");
253     sysent_define_arg(80, 0, longArg);
254     sysent_define_arg(80, 1, longArg);
255     sysent_returns_long(80);
256     return 0;
257 }
258