a0ed85e3f16297e7cf7eaec75d6cfb8087eb92cd
[openafs.git] / src / afs / LINUX / 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  * VFS operations for Linux
12  *
13  * super_block operations should return negated errno to Linux.
14  */
15 #include <afsconfig.h>
16 #include "afs/param.h"
17
18 RCSID
19     ("$Header$");
20
21 #define __NO_VERSION__          /* don't define kernel_version in module.h */
22 #include <linux/module.h> /* early to avoid printf->printk mapping */
23 #include "afs/sysincludes.h"
24 #include "afsincludes.h"
25 #include "afs/afs_stats.h"
26 #if !defined(AFS_LINUX26_ENV)
27 #include "h/locks.h"
28 #endif
29 #if defined(AFS_LINUX24_ENV)
30 #include "h/smp_lock.h"
31 #endif
32
33
34 struct vcache *afs_globalVp = 0;
35 struct vfs *afs_globalVFS = 0;
36 #if defined(AFS_LINUX24_ENV)
37 struct vfsmount *afs_cacheMnt;
38 #endif
39 int afs_was_mounted = 0;        /* Used to force reload if mount/unmount/mount */
40
41 extern struct super_operations afs_sops;
42 extern afs_rwlock_t afs_xvcache;
43 extern struct afs_q VLRU;
44
45 extern struct dentry_operations afs_dentry_operations;
46
47 /* Forward declarations */
48 static void iattr2vattr(struct vattr *vattrp, struct iattr *iattrp);
49 static void update_inode_cache(struct inode *ip, struct vattr *vp);
50 static int afs_root(struct super_block *afsp);
51 struct super_block *afs_read_super(struct super_block *sb, void *data, int silent);
52 int afs_fill_super(struct super_block *sb, void *data, int silent);
53 static struct super_block *afs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data);
54
55 /* afs_file_system
56  * VFS entry for Linux - installed in init_module
57  * Linux mounts file systems by:
58  * 1) register_filesystem(&afs_file_system) - done in init_module
59  * 2) Mount call comes to us via do_mount -> read_super -> afs_read_super.
60  *    We are expected to setup the super_block. See afs_read_super.
61  */
62 #if defined(AFS_LINUX26_ENV)
63 struct backing_dev_info afs_backing_dev_info = {
64         .ra_pages       = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE,
65         .state          = 0,
66 };
67
68 struct file_system_type afs_fs_type = {
69     .owner = THIS_MODULE,
70     .name = "afs",
71     .get_sb = afs_get_sb,
72     .kill_sb = kill_anon_super,
73     .fs_flags = FS_BINARY_MOUNTDATA,
74 };
75 #elif defined(AFS_LINUX24_ENV)
76 DECLARE_FSTYPE(afs_fs_type, "afs", afs_read_super, 0);
77 #else
78 struct file_system_type afs_fs_type = {
79     "afs",                      /* name - used by mount operation. */
80     0,                          /* requires_dev - no for network filesystems. mount() will 
81                                  * pass us an "unnamed" device. */
82     afs_read_super,             /* wrapper to afs_mount */
83     NULL                        /* pointer to next file_system_type once registered. */
84 };
85 #endif
86
87 /* afs_read_super
88  * read the "super block" for AFS - roughly eguivalent to struct vfs.
89  * dev, covered, s_rd_only, s_dirt, and s_type will be set by read_super.
90  */
91 #if defined(AFS_LINUX26_ENV)
92 static struct super_block *
93 afs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
94 {
95     return get_sb_nodev(fs_type, flags, data, afs_fill_super);
96 }
97
98 int
99 afs_fill_super(struct super_block *sb, void *data, int silent)
100 #else
101 struct super_block *
102 afs_read_super(struct super_block *sb, void *data, int silent)
103 #endif
104 {
105     int code = 0;
106
107     AFS_GLOCK();
108     if (afs_was_mounted) {
109         printf
110             ("You must reload the AFS kernel extensions before remounting AFS.\n");
111         AFS_GUNLOCK();
112 #if defined(AFS_LINUX26_ENV)
113         return -EINVAL;
114 #else
115         return NULL;
116 #endif
117     }
118     afs_was_mounted = 1;
119
120     /* Set basics of super_block */
121 #if !defined(AFS_LINUX24_ENV)
122     lock_super(sb);
123 #endif
124 #if defined(AFS_LINUX26_ENV)
125    __module_get(THIS_MODULE);
126 #else
127     MOD_INC_USE_COUNT;
128 #endif
129
130     afs_globalVFS = sb;
131     sb->s_blocksize = 1024;
132     sb->s_blocksize_bits = 10;
133     sb->s_magic = AFS_VFSMAGIC;
134     sb->s_op = &afs_sops;       /* Super block (vfs) ops */
135 #if defined(MAX_NON_LFS)
136     sb->s_maxbytes = MAX_NON_LFS;
137 #endif
138     code = afs_root(sb);
139     if (code) {
140         afs_globalVFS = NULL;
141 #if defined(AFS_LINUX26_ENV)
142         module_put(THIS_MODULE);
143 #else
144         MOD_DEC_USE_COUNT;
145 #endif
146     }
147
148 #if !defined(AFS_LINUX24_ENV)
149     unlock_super(sb);
150 #endif
151
152     AFS_GUNLOCK();
153 #if defined(AFS_LINUX26_ENV)
154     return code ? -EINVAL : 0;
155 #else
156     return code ? NULL : sb;
157 #endif
158 }
159
160
161 /* afs_root - stat the root of the file system. AFS global held on entry. */
162 static int
163 afs_root(struct super_block *afsp)
164 {
165     register afs_int32 code = 0;
166     struct vrequest treq;
167     register struct vcache *tvp = 0;
168
169     AFS_STATCNT(afs_root);
170     if (afs_globalVp && (afs_globalVp->states & CStatd)) {
171         tvp = afs_globalVp;
172     } else {
173         cred_t *credp = crref();
174
175         if (afs_globalVp) {
176             afs_PutVCache(afs_globalVp);
177             afs_globalVp = NULL;
178         }
179
180         if (!(code = afs_InitReq(&treq, credp)) && !(code = afs_CheckInit())) {
181             tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
182             if (tvp) {
183                 extern struct inode_operations afs_dir_iops;
184 #if defined(AFS_LINUX24_ENV)
185                 extern struct file_operations afs_dir_fops;
186 #endif
187
188                 /* "/afs" is a directory, reset inode ops accordingly. */
189                 AFSTOV(tvp)->v_op = &afs_dir_iops;
190 #if defined(AFS_LINUX24_ENV)
191                 AFSTOV(tvp)->v_fop = &afs_dir_fops;
192 #endif
193
194                 /* setup super_block and mount point inode. */
195                 afs_globalVp = tvp;
196 #if defined(AFS_LINUX24_ENV)
197                 afsp->s_root = d_alloc_root(AFSTOI(tvp));
198 #else
199                 afsp->s_root = d_alloc_root(AFSTOI(tvp), NULL);
200 #endif
201                 afsp->s_root->d_op = &afs_dentry_operations;
202             } else
203                 code = ENOENT;
204         }
205         crfree(credp);
206     }
207
208     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, afs_globalVp,
209                ICL_TYPE_INT32, code);
210     return code;
211 }
212
213 /* super_operations */
214
215 /* afs_notify_change
216  * Linux version of setattr call. What to change is in the iattr struct.
217  * We need to set bits in both the Linux inode as well as the vcache.
218  */
219 int
220 afs_notify_change(struct dentry *dp, struct iattr *iattrp)
221 {
222     struct vattr vattr;
223     int code;
224     cred_t *credp = crref();
225     struct inode *ip = dp->d_inode;
226
227     AFS_GLOCK();
228 #if defined(AFS_LINUX26_ENV)
229     lock_kernel();
230 #endif
231     VATTR_NULL(&vattr);
232     iattr2vattr(&vattr, iattrp);        /* Convert for AFS vnodeops call. */
233     update_inode_cache(ip, &vattr);
234     code = afs_setattr(ITOAFS(ip), &vattr, credp);
235     afs_CopyOutAttrs(ITOAFS(ip), &vattr);
236     /* Note that the inode may still not have all the correct info. But at
237      * least we've got the newest version of what was supposed to be set.
238      */
239
240 #if defined(AFS_LINUX26_ENV)
241     unlock_kernel();
242 #endif
243     AFS_GUNLOCK();
244     crfree(credp);
245     return -code;
246 }
247
248
249 /* This list is simply used to initialize the i_list member of the
250  * linux inode. This stops linux inode syncing code from choking on our
251  * inodes.
252  */
253 static LIST_HEAD(dummy_inode_list);
254
255
256 /* This is included for documentation only. */
257 /* afs_write_inode
258  * Used to flush in core inode to disk. We don't need to do this. Top level
259  * write_inode() routine will clear i_dirt. If this routine is in the table,
260  * it's expected to do the cleaning and clear i_dirt.
261  * 
262  * 9/24/99: This is what we thought until we discovered msync() does end up calling
263  * this function to sync a single inode to disk. msync() only flushes selective
264  * pages to disk. So it needs an inode syncing function to update metadata when it
265  * has synced some pages of a file to disk.
266  */
267 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
268 #ifdef WRITE_INODE_NOT_VOID
269 static int
270 #else
271 static void
272 #endif
273 afs_write_inode(struct inode *ip, int unused)
274 #else
275 static void
276 afs_write_inode(struct inode *ip)
277 #endif
278 {
279     list_del(&ip->i_list);
280     /* and put it back on our dummy list. */
281     put_inode_on_dummy_list(ip);
282
283     /* for now we don't actually update the metadata during msync. This
284      * is just to keep linux happy.  */
285 #ifdef WRITE_INODE_NOT_VOID
286     return 0;
287 #endif
288 }
289
290 static void
291 afs_destroy_inode(struct inode *ip)
292 {
293     cred_t *credp = crref();
294
295     /* locked by clear_inode() */
296     put_inode_on_dummy_list(ip);
297     ip->i_state = 0;
298     afs_InactiveVCache(ITOAFS(ip), credp); /* afs_FlushVCache()? */
299     AFS_GUNLOCK();
300     crfree(credp);
301 }
302
303
304 /* afs_put_inode
305  * called from iput when count goes to zero. Linux version of inactive.
306  * For Linux 2.2, this funcionality has moved to the delete inode super op.
307  * If we use the common inode pool, we'll need to set i_nlink to 0 here.
308  * That will trigger the call to delete routine.
309  */
310
311 #if defined(AFS_LINUX24_ENV)
312 static void
313 afs_clear_inode(struct inode *ip)
314 {
315     AFS_GLOCK();       /* unlocked by destroy_inode() */
316 }
317 #else
318 static void
319 afs_delete_inode(struct inode *ip)
320 {
321     AFS_GLOCK();                /* after spin_unlock(inode_lock) */
322     osi_clear_inode(ip);
323     AFS_GUNLOCK();
324 }
325 #endif
326
327 /* afs_put_super
328  * Called from unmount to release super_block. */
329 static void
330 afs_put_super(struct super_block *sbp)
331 {
332     int code = 0;
333
334     AFS_GLOCK();
335     AFS_STATCNT(afs_unmount);
336
337 #if !defined(AFS_LINUX26_ENV)
338     if (!suser()) {
339         AFS_GUNLOCK();
340         return;
341     }
342 #endif
343
344     afs_globalVFS = 0;
345     afs_globalVp = 0;
346     afs_shutdown();
347 #if defined(AFS_LINUX24_ENV)
348     mntput(afs_cacheMnt);
349 #endif
350
351     osi_linux_verify_alloced_memory();
352     AFS_GUNLOCK();
353
354     if (!code) {
355         sbp->s_dev = 0;
356 #if defined(AFS_LINUX26_ENV)
357         module_put(THIS_MODULE);
358 #else
359         MOD_DEC_USE_COUNT;
360 #endif
361     }
362 }
363
364
365 /* afs_statfs
366  * statp is in user space, so we need to cobble together a statfs, then
367  * copy it.
368  */
369 #if defined(AFS_LINUX26_ENV)
370 int
371 afs_statfs(struct super_block *sbp, struct kstatfs *statp)
372 #elif defined(AFS_LINUX24_ENV)
373 int
374 afs_statfs(struct super_block *sbp, struct statfs *statp)
375 #else
376 int
377 afs_statfs(struct super_block *sbp, struct statfs *__statp, int size)
378 #endif
379 {
380 #if !defined(AFS_LINUX24_ENV)
381     struct statfs stat, *statp;
382
383     if (size < sizeof(struct statfs))
384         return;
385
386     memset(&stat, 0, size);
387     statp = &stat;
388 #else
389     memset(statp, 0, sizeof(*statp));
390 #endif
391
392     AFS_STATCNT(afs_statfs);
393
394     statp->f_type = 0;          /* Can we get a real type sometime? */
395     statp->f_bsize = sbp->s_blocksize;
396     statp->f_blocks = statp->f_bfree = statp->f_bavail = statp->f_files =
397         statp->f_ffree = 9000000;
398     statp->f_fsid.val[0] = AFS_VFSMAGIC;
399     statp->f_fsid.val[1] = AFS_VFSFSID;
400     statp->f_namelen = 256;
401
402 #if !defined(AFS_LINUX24_ENV)
403     memcpy_tofs(__statp, &stat, size);
404 #endif
405     return 0;
406 }
407
408 void
409 afs_umount_begin(struct super_block *sbp)
410 {
411     afs_shuttingdown = 1;
412 }
413
414 struct super_operations afs_sops = {
415 #if defined(AFS_LINUX24_ENV)
416   .destroy_inode =      afs_destroy_inode,
417   .clear_inode =        afs_clear_inode,
418 #else
419   .delete_inode =       afs_delete_inode,
420 #endif
421   .write_inode =        afs_write_inode,
422   .put_super =          afs_put_super,
423   .statfs =             afs_statfs,
424   .umount_begin =       afs_umount_begin
425 #if !defined(AFS_LINUX24_ENV)
426   .notify_change =      afs_notify_change,
427 #endif
428 };
429
430 /************** Support routines ************************/
431
432 /* vattr_setattr
433  * Set iattr data into vattr. Assume vattr cleared before call.
434  */
435 static void
436 iattr2vattr(struct vattr *vattrp, struct iattr *iattrp)
437 {
438     vattrp->va_mask = iattrp->ia_valid;
439     if (iattrp->ia_valid & ATTR_MODE)
440         vattrp->va_mode = iattrp->ia_mode;
441     if (iattrp->ia_valid & ATTR_UID)
442         vattrp->va_uid = iattrp->ia_uid;
443     if (iattrp->ia_valid & ATTR_GID)
444         vattrp->va_gid = iattrp->ia_gid;
445     if (iattrp->ia_valid & ATTR_SIZE)
446         vattrp->va_size = iattrp->ia_size;
447     if (iattrp->ia_valid & ATTR_ATIME) {
448 #if defined(AFS_LINUX26_ENV)
449         vattrp->va_atime.tv_sec = iattrp->ia_atime.tv_sec;
450 #else
451         vattrp->va_atime.tv_sec = iattrp->ia_atime;
452 #endif
453         vattrp->va_atime.tv_usec = 0;
454     }
455     if (iattrp->ia_valid & ATTR_MTIME) {
456 #if defined(AFS_LINUX26_ENV)
457         vattrp->va_mtime.tv_sec = iattrp->ia_mtime.tv_sec;
458 #else
459         vattrp->va_mtime.tv_sec = iattrp->ia_mtime;
460 #endif
461         vattrp->va_mtime.tv_usec = 0;
462     }
463     if (iattrp->ia_valid & ATTR_CTIME) {
464 #if defined(AFS_LINUX26_ENV)
465         vattrp->va_ctime.tv_sec = iattrp->ia_ctime.tv_sec;
466 #else
467         vattrp->va_ctime.tv_sec = iattrp->ia_ctime;
468 #endif
469         vattrp->va_ctime.tv_usec = 0;
470     }
471 }
472
473 /* update_inode_cache
474  * Update inode with info from vattr struct. Use va_mask to determine what
475  * to update.
476  */
477 static void
478 update_inode_cache(struct inode *ip, struct vattr *vp)
479 {
480     if (vp->va_mask & ATTR_MODE)
481         ip->i_mode = vp->va_mode;
482     if (vp->va_mask & ATTR_UID)
483         ip->i_uid = vp->va_uid;
484     if (vp->va_mask & ATTR_GID)
485         ip->i_gid = vp->va_gid;
486     if (vp->va_mask & ATTR_SIZE)
487         ip->i_size = vp->va_size;
488     if (vp->va_mask & ATTR_ATIME)
489 #if defined(AFS_LINUX26_ENV)
490         ip->i_atime.tv_sec = vp->va_atime.tv_sec;
491 #else
492         ip->i_atime = vp->va_atime.tv_sec;
493 #endif
494     if (vp->va_mask & ATTR_MTIME)
495 #if defined(AFS_LINUX26_ENV)
496         ip->i_mtime.tv_sec = vp->va_mtime.tv_sec;
497 #else
498         ip->i_mtime = vp->va_mtime.tv_sec;
499 #endif
500     if (vp->va_mask & ATTR_CTIME)
501 #if defined(AFS_LINUX26_ENV)
502         ip->i_ctime.tv_sec = vp->va_ctime.tv_sec;
503 #else
504         ip->i_ctime = vp->va_ctime.tv_sec;
505 #endif
506 }
507
508 /* vattr2inode
509  * Rewrite the inode cache from the attr. Assumes all vattr fields are valid.
510  */
511 void
512 vattr2inode(struct inode *ip, struct vattr *vp)
513 {
514     ip->i_ino = vp->va_nodeid;
515     ip->i_nlink = vp->va_nlink;
516     ip->i_blocks = vp->va_blocks;
517     ip->i_blksize = vp->va_blocksize;
518     ip->i_rdev = vp->va_rdev;
519     ip->i_mode = vp->va_mode;
520     ip->i_uid = vp->va_uid;
521     ip->i_gid = vp->va_gid;
522     ip->i_size = vp->va_size;
523 #if defined(AFS_LINUX26_ENV)
524     ip->i_atime.tv_sec = vp->va_atime.tv_sec;
525     ip->i_mtime.tv_sec = vp->va_mtime.tv_sec;
526     ip->i_ctime.tv_sec = vp->va_ctime.tv_sec;
527 #else
528     ip->i_atime = vp->va_atime.tv_sec;
529     ip->i_mtime = vp->va_mtime.tv_sec;
530     ip->i_ctime = vp->va_ctime.tv_sec;
531 #endif
532 }
533
534 /* Put this afs inode on our own dummy list. Linux expects to see inodes
535  * nicely strung up in lists. Linux inode syncing code chokes on our inodes if
536  * they're not on any lists.
537  */
538 void
539 put_inode_on_dummy_list(struct inode *ip)
540 {
541     /* Initialize list. See explanation above. */
542     list_add(&ip->i_list, &dummy_inode_list);
543 }
544
545 /* And yet another routine to update the inode cache - called from ProcessFS */
546 void
547 vcache2inode(struct vcache *avc)
548 {
549     struct vattr vattr;
550
551     VATTR_NULL(&vattr);
552     afs_CopyOutAttrs(avc, &vattr);      /* calls vattr2inode */
553 }
554
555 /* Yet another one for fakestat'ed mountpoints */
556 void
557 vcache2fakeinode(struct vcache *rootvp, struct vcache *mpvp)
558 {
559     struct vattr vattr;
560
561     VATTR_NULL(&vattr);
562     afs_CopyOutAttrs(rootvp, &vattr);
563     vattr2inode(AFSTOI(mpvp), &vattr);
564 }