diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-11-23 18:14:10 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-01-04 04:56:57 +0100 |
commit | 7d6fec45a5131918b51dcd76da52f2ec86a85be6 (patch) | |
tree | 82af862264cfa176a37c7d9f915806346c8df0bc | |
parent | vfs: fix the rest of sget() races (diff) | |
download | linux-7d6fec45a5131918b51dcd76da52f2ec86a85be6.tar.xz linux-7d6fec45a5131918b51dcd76da52f2ec86a85be6.zip |
vfs: start hiding vfsmount guts series
Almost all fields of struct vfsmount are used only by core VFS (and
a fairly small part of it, at that). The plan: embed struct vfsmount
into struct mount, making the latter visible only to core parts of VFS.
Then move fields from vfsmount to mount, eventually leaving only
mnt_root/mnt_sb/mnt_flags in struct vfsmount. Filesystem code still
gets pointers to struct vfsmount and remains unchanged; all such
pointers go to struct vfsmount embedded into the instances of struct
mount allocated by fs/namespace.c. When fs/namespace.c et.al. get
a pointer to vfsmount, they turn it into pointer to mount (using
container_of) and work with that.
This is the first part of series; struct mount is introduced,
allocation switched to using it.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/mount.h | 9 | ||||
-rw-r--r-- | fs/namespace.c | 18 |
2 files changed, 19 insertions, 8 deletions
diff --git a/fs/mount.h b/fs/mount.h index 7890e49f74ef..47da8163e1f4 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -1,5 +1,14 @@ #include <linux/mount.h> +struct mount { + struct vfsmount mnt; +}; + +static inline struct mount *real_mount(struct vfsmount *mnt) +{ + return container_of(mnt, struct mount, mnt); +} + static inline int mnt_has_parent(struct vfsmount *mnt) { return mnt != mnt->mnt_parent; diff --git a/fs/namespace.c b/fs/namespace.c index 86b4f6406470..dda47fee6fdf 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -173,8 +173,9 @@ unsigned int mnt_get_count(struct vfsmount *mnt) static struct vfsmount *alloc_vfsmnt(const char *name) { - struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); - if (mnt) { + struct mount *p = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); + if (p) { + struct vfsmount *mnt = &p->mnt; int err; err = mnt_alloc_id(mnt); @@ -210,16 +211,16 @@ static struct vfsmount *alloc_vfsmnt(const char *name) INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); #endif } - return mnt; + return &p->mnt; #ifdef CONFIG_SMP out_free_devname: - kfree(mnt->mnt_devname); + kfree(p->mnt.mnt_devname); #endif out_free_id: - mnt_free_id(mnt); + mnt_free_id(&p->mnt); out_free_cache: - kmem_cache_free(mnt_cache, mnt); + kmem_cache_free(mnt_cache, p); return NULL; } @@ -449,12 +450,13 @@ static void __mnt_unmake_readonly(struct vfsmount *mnt) static void free_vfsmnt(struct vfsmount *mnt) { + struct mount *p = real_mount(mnt); kfree(mnt->mnt_devname); mnt_free_id(mnt); #ifdef CONFIG_SMP free_percpu(mnt->mnt_pcp); #endif - kmem_cache_free(mnt_cache, mnt); + kmem_cache_free(mnt_cache, p); } /* @@ -2698,7 +2700,7 @@ void __init mnt_init(void) init_rwsem(&namespace_sem); - mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount), + mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount), 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC); |