2 * Copyright 2000, International Business Machines Corporation and others.
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
11 * VFS operations for Linux
13 * super_block operations should return negated errno to Linux.
15 #include <afsconfig.h>
16 #include "afs/param.h"
19 #define __NO_VERSION__ /* don't define kernel_version in module.h */
20 #include <linux/module.h> /* early to avoid printf->printk mapping */
21 #include "afs/sysincludes.h"
22 #include "afsincludes.h"
23 #include "afs/afs_stats.h"
25 #include "osi_compat.h"
27 struct vcache
*afs_globalVp
= 0;
28 struct vfs
*afs_globalVFS
= 0;
29 struct vfsmount
*afs_cacheMnt
;
30 int afs_was_mounted
= 0; /* Used to force reload if mount/unmount/mount */
32 extern struct super_operations afs_sops
;
33 #if !defined(AFS_NONFSTRANS)
34 extern struct export_operations afs_export_ops
;
36 extern afs_rwlock_t afs_xvcache
;
37 extern struct afs_q VLRU
;
39 extern struct dentry_operations afs_dentry_operations
;
41 /* Forward declarations */
42 static int afs_root(struct super_block
*afsp
);
43 int afs_fill_super(struct super_block
*sb
, void *data
, int silent
);
47 * afs_mount (2.6.37+) and afs_get_sb (2.6.36-) are the entry
48 * points from the vfs when mounting afs. The super block
49 * structure is setup in the afs_fill_super callback function.
52 #if defined(STRUCT_FILE_SYSTEM_TYPE_HAS_MOUNT)
53 static struct dentry
*
54 afs_mount(struct file_system_type
*fs_type
, int flags
,
55 const char *dev_name
, void *data
) {
56 return mount_nodev(fs_type
, flags
, data
, afs_fill_super
);
58 #elif defined(GET_SB_HAS_STRUCT_VFSMOUNT)
60 afs_get_sb(struct file_system_type
*fs_type
, int flags
,
61 const char *dev_name
, void *data
, struct vfsmount
*mnt
) {
62 return get_sb_nodev(fs_type
, flags
, data
, afs_fill_super
, mnt
);
65 static struct super_block
*
66 afs_get_sb(struct file_system_type
*fs_type
, int flags
,
67 const char *dev_name
, void *data
) {
68 return get_sb_nodev(fs_type
, flags
, data
, afs_fill_super
);
72 struct file_system_type afs_fs_type
= {
75 #if defined(STRUCT_FILE_SYSTEM_TYPE_HAS_MOUNT)
80 .kill_sb
= kill_anon_super
,
81 .fs_flags
= FS_BINARY_MOUNTDATA
,
84 struct backing_dev_info
*afs_backing_dev_info
;
87 afs_fill_super(struct super_block
*sb
, void *data
, int silent
)
90 #if defined(HAVE_LINUX_BDI_INIT)
91 int bdi_init_done
= 0;
95 if (afs_was_mounted
) {
97 ("You must reload the AFS kernel extensions before remounting AFS.\n");
103 /* Set basics of super_block */
104 __module_get(THIS_MODULE
);
107 #if defined(SB_NOATIME)
108 sb
->s_flags
|= SB_NOATIME
;
110 sb
->s_flags
|= MS_NOATIME
;
112 sb
->s_blocksize
= 1024;
113 sb
->s_blocksize_bits
= 10;
114 sb
->s_magic
= AFS_VFSMAGIC
;
115 sb
->s_op
= &afs_sops
; /* Super block (vfs) ops */
117 #if defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP)
118 sb
->s_d_op
= &afs_dentry_operations
;
120 #if defined(HAVE_LINUX_SUPER_SETUP_BDI)
121 code
= super_setup_bdi(sb
);
124 sb
->s_bdi
->name
= "openafs";
125 sb
->s_bdi
->ra_pages
= 32;
127 /* used for inodes backing_dev_info field, also */
128 afs_backing_dev_info
= kzalloc(sizeof(struct backing_dev_info
), GFP_NOFS
);
129 #if defined(HAVE_LINUX_BDI_INIT)
130 code
= bdi_init(afs_backing_dev_info
);
135 #if defined(STRUCT_BACKING_DEV_INFO_HAS_NAME)
136 afs_backing_dev_info
->name
= "openafs";
138 afs_backing_dev_info
->ra_pages
= 32;
139 #if defined (STRUCT_SUPER_BLOCK_HAS_S_BDI)
140 sb
->s_bdi
= afs_backing_dev_info
;
141 /* The name specified here will appear in the flushing thread name - flush-afs */
142 bdi_register(afs_backing_dev_info
, NULL
, "afs");
144 #endif /* HAVE_LINUX_SUPER_SETUP_BDI */
145 #if !defined(AFS_NONFSTRANS)
146 sb
->s_export_op
= &afs_export_ops
;
148 #if defined(MAX_NON_LFS)
149 #ifdef AFS_64BIT_CLIENT
150 #if !defined(MAX_LFS_FILESIZE)
151 #if BITS_PER_LONG==32
152 #define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
153 #elif BITS_PER_LONG==64
154 #define MAX_LFS_FILESIZE 0x7fffffffffffffff
157 sb
->s_maxbytes
= MAX_LFS_FILESIZE
;
159 sb
->s_maxbytes
= MAX_NON_LFS
;
165 afs_globalVFS
= NULL
;
166 afs_FlushAllVCaches();
167 #if defined(HAVE_LINUX_BDI_INIT)
169 bdi_destroy(afs_backing_dev_info
);
171 #if !defined(HAVE_LINUX_SUPER_SETUP_BDI)
172 kfree(afs_backing_dev_info
);
174 module_put(THIS_MODULE
);
178 return code
? -EINVAL
: 0;
182 /* afs_root - stat the root of the file system. AFS global held on entry. */
184 afs_root(struct super_block
*afsp
)
187 struct vcache
*tvp
= 0;
189 AFS_STATCNT(afs_root
);
190 if (afs_globalVp
&& (afs_globalVp
->f
.states
& CStatd
)) {
193 struct vrequest
*treq
= NULL
;
194 cred_t
*credp
= crref();
197 afs_PutVCache(afs_globalVp
);
201 if (!(code
= afs_CreateReq(&treq
, credp
)) && !(code
= afs_CheckInit())) {
202 tvp
= afs_GetVCache(&afs_rootFid
, treq
, NULL
, NULL
);
204 struct inode
*ip
= AFSTOV(tvp
);
205 struct vattr
*vattr
= NULL
;
207 code
= afs_CreateAttr(&vattr
);
209 afs_getattr(tvp
, vattr
, credp
);
210 afs_fill_inode(ip
, vattr
);
212 /* setup super_block and mount point inode. */
214 #if defined(HAVE_LINUX_D_MAKE_ROOT)
215 afsp
->s_root
= d_make_root(ip
);
217 afsp
->s_root
= d_alloc_root(ip
);
219 #if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP)
220 afsp
->s_root
->d_op
= &afs_dentry_operations
;
222 afs_DestroyAttr(vattr
);
228 afs_DestroyReq(treq
);
231 afs_Trace2(afs_iclSetp
, CM_TRACE_VFSROOT
, ICL_TYPE_POINTER
, afs_globalVp
,
232 ICL_TYPE_INT32
, code
);
236 /* super_operations */
238 #if defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE)
239 static afs_kmem_cache_t
*afs_inode_cachep
;
241 static struct inode
*
242 afs_alloc_inode(struct super_block
*sb
)
246 vcp
= (struct vcache
*) kmem_cache_alloc(afs_inode_cachep
, KALLOC_TYPE
);
254 afs_destroy_inode(struct inode
*inode
)
256 kmem_cache_free(afs_inode_cachep
, inode
);
260 init_once(void * foo
)
262 struct vcache
*vcp
= (struct vcache
*) foo
;
264 inode_init_once(AFSTOV(vcp
));
268 afs_init_inodecache(void)
270 #if defined(KMEM_CACHE_TAKES_DTOR)
271 afs_inode_cachep
= kmem_cache_create("afs_inode_cache",
272 sizeof(struct vcache
), 0,
273 SLAB_HWCACHE_ALIGN
| SLAB_RECLAIM_ACCOUNT
, init_once_func
, NULL
);
275 afs_inode_cachep
= kmem_cache_create("afs_inode_cache",
276 sizeof(struct vcache
), 0,
277 SLAB_HWCACHE_ALIGN
| SLAB_RECLAIM_ACCOUNT
, init_once_func
);
279 if (afs_inode_cachep
== NULL
)
285 afs_destroy_inodecache(void)
287 if (afs_inode_cachep
)
288 (void) kmem_cache_destroy(afs_inode_cachep
);
292 afs_init_inodecache(void)
298 afs_destroy_inodecache(void)
304 #if defined(STRUCT_SUPER_OPERATIONS_HAS_EVICT_INODE)
306 afs_evict_inode(struct inode
*ip
)
308 struct vcache
*vcp
= VTOAFS(ip
);
310 if (vcp
->vlruq
.prev
|| vcp
->vlruq
.next
)
311 osi_Panic("inode freed while on LRU");
313 osi_Panic("inode freed while still hashed");
315 truncate_inode_pages(&ip
->i_data
, 0);
316 #if defined(HAVE_LINUX_CLEAR_INODE)
322 #if !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE)
323 afs_osi_Free(ip
->u
.generic_ip
, sizeof(struct vcache
));
328 afs_clear_inode(struct inode
*ip
)
330 struct vcache
*vcp
= VTOAFS(ip
);
332 if (vcp
->vlruq
.prev
|| vcp
->vlruq
.next
)
333 osi_Panic("inode freed while on LRU");
335 osi_Panic("inode freed while still hashed");
337 #if !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE)
338 afs_osi_Free(ip
->u
.generic_ip
, sizeof(struct vcache
));
344 * Called from unmount to release super_block. */
346 afs_put_super(struct super_block
*sbp
)
349 AFS_STATCNT(afs_unmount
);
355 mntput(afs_cacheMnt
);
357 osi_linux_verify_alloced_memory();
358 #if defined(HAVE_LINUX_BDI_INIT)
359 bdi_destroy(afs_backing_dev_info
);
361 kfree(afs_backing_dev_info
);
365 module_put(THIS_MODULE
);
370 * statp is in user space, so we need to cobble together a statfs, then
374 #if defined(STATFS_TAKES_DENTRY)
375 afs_statfs(struct dentry
*dentry
, struct kstatfs
*statp
)
377 afs_statfs(struct super_block
*sbp
, struct kstatfs
*statp
)
380 memset(statp
, 0, sizeof(*statp
));
382 AFS_STATCNT(afs_statfs
);
384 /* hardcode in case that which is giveth is taken away */
385 statp
->f_type
= 0x5346414F;
386 #if defined(STATFS_TAKES_DENTRY)
387 statp
->f_bsize
= dentry
->d_sb
->s_blocksize
;
389 statp
->f_bsize
= sbp
->s_blocksize
;
391 statp
->f_blocks
= statp
->f_bfree
= statp
->f_bavail
= statp
->f_files
=
392 statp
->f_ffree
= AFS_VFS_FAKEFREE
;
393 statp
->f_fsid
.val
[0] = AFS_VFSMAGIC
;
394 statp
->f_fsid
.val
[1] = AFS_VFSFSID
;
395 statp
->f_namelen
= 256;
400 struct super_operations afs_sops
= {
401 #if defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE)
402 .alloc_inode
= afs_alloc_inode
,
403 .destroy_inode
= afs_destroy_inode
,
405 #if defined(STRUCT_SUPER_OPERATIONS_HAS_EVICT_INODE)
406 .evict_inode
= afs_evict_inode
,
408 .clear_inode
= afs_clear_inode
,
410 .put_super
= afs_put_super
,
411 .statfs
= afs_statfs
,