aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hostfs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-06-06 17:53:01 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-09 16:48:07 -0400
commit601d2c38b93130d387091c28d13abea40924e518 (patch)
tree1a4565995cf6aa29109c12c0257e61c63920a1a1 /fs/hostfs
parente971a6d7b9daebfe2c11c590377d3933410ab929 (diff)
hostfs: don't keep a field in each inode when we are using it only in root
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/hostfs')
-rw-r--r--fs/hostfs/hostfs_kern.c39
1 files changed, 15 insertions, 24 deletions
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index fab5f5a1e6f0..7e6750499b8b 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -19,7 +19,6 @@
19#include "kern.h" 19#include "kern.h"
20 20
21struct hostfs_inode_info { 21struct hostfs_inode_info {
22 char *host_filename;
23 int fd; 22 int fd;
24 fmode_t mode; 23 fmode_t mode;
25 struct inode vfs_inode; 24 struct inode vfs_inode;
@@ -103,7 +102,7 @@ static char *dentry_name(struct dentry *dentry, int extra)
103 parent = parent->d_parent; 102 parent = parent->d_parent;
104 } 103 }
105 104
106 root = HOSTFS_I(parent->d_inode)->host_filename; 105 root = parent->d_sb->s_fs_info;
107 len += strlen(root); 106 len += strlen(root);
108 name = kmalloc(len + extra + 1, GFP_KERNEL); 107 name = kmalloc(len + extra + 1, GFP_KERNEL);
109 if (name == NULL) 108 if (name == NULL)
@@ -266,7 +265,7 @@ int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
266 long long f_files; 265 long long f_files;
267 long long f_ffree; 266 long long f_ffree;
268 267
269 err = do_statfs(HOSTFS_I(dentry->d_sb->s_root->d_inode)->host_filename, 268 err = do_statfs(dentry->d_sb->s_fs_info,
270 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, 269 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
271 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 270 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
272 &sf->f_namelen, sf->f_spare); 271 &sf->f_namelen, sf->f_spare);
@@ -285,13 +284,10 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
285{ 284{
286 struct hostfs_inode_info *hi; 285 struct hostfs_inode_info *hi;
287 286
288 hi = kmalloc(sizeof(*hi), GFP_KERNEL); 287 hi = kzalloc(sizeof(*hi), GFP_KERNEL);
289 if (hi == NULL) 288 if (hi == NULL)
290 return NULL; 289 return NULL;
291 290 hi->fd = -1;
292 *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
293 .fd = -1,
294 .mode = 0 });
295 inode_init_once(&hi->vfs_inode); 291 inode_init_once(&hi->vfs_inode);
296 return &hi->vfs_inode; 292 return &hi->vfs_inode;
297} 293}
@@ -308,14 +304,12 @@ static void hostfs_evict_inode(struct inode *inode)
308 304
309static void hostfs_destroy_inode(struct inode *inode) 305static void hostfs_destroy_inode(struct inode *inode)
310{ 306{
311 kfree(HOSTFS_I(inode)->host_filename);
312 kfree(HOSTFS_I(inode)); 307 kfree(HOSTFS_I(inode));
313} 308}
314 309
315static int hostfs_show_options(struct seq_file *seq, struct vfsmount *vfs) 310static int hostfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
316{ 311{
317 struct inode *root = vfs->mnt_sb->s_root->d_inode; 312 const char *root_path = vfs->mnt_sb->s_fs_info;
318 const char *root_path = HOSTFS_I(root)->host_filename;
319 size_t offset = strlen(root_ino) + 1; 313 size_t offset = strlen(root_ino) + 1;
320 314
321 if (strlen(root_path) > offset) 315 if (strlen(root_path) > offset)
@@ -978,8 +972,8 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
978 req_root = ""; 972 req_root = "";
979 973
980 err = -ENOMEM; 974 err = -ENOMEM;
981 host_root_path = kmalloc(strlen(root_ino) + 1 975 sb->s_fs_info = host_root_path =
982 + strlen(req_root) + 1, GFP_KERNEL); 976 kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
983 if (host_root_path == NULL) 977 if (host_root_path == NULL)
984 goto out; 978 goto out;
985 979
@@ -988,20 +982,13 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
988 root_inode = hostfs_iget(sb); 982 root_inode = hostfs_iget(sb);
989 if (IS_ERR(root_inode)) { 983 if (IS_ERR(root_inode)) {
990 err = PTR_ERR(root_inode); 984 err = PTR_ERR(root_inode);
991 goto out_free; 985 goto out;
992 } 986 }
993 987
994 err = init_inode(root_inode, NULL); 988 err = init_inode(root_inode, NULL);
995 if (err) 989 if (err)
996 goto out_put; 990 goto out_put;
997 991
998 HOSTFS_I(root_inode)->host_filename = host_root_path;
999 /*
1000 * Avoid that in the error path, iput(root_inode) frees again
1001 * host_root_path through hostfs_destroy_inode!
1002 */
1003 host_root_path = NULL;
1004
1005 err = -ENOMEM; 992 err = -ENOMEM;
1006 sb->s_root = d_alloc_root(root_inode); 993 sb->s_root = d_alloc_root(root_inode);
1007 if (sb->s_root == NULL) 994 if (sb->s_root == NULL)
@@ -1019,8 +1006,6 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
1019 1006
1020out_put: 1007out_put:
1021 iput(root_inode); 1008 iput(root_inode);
1022out_free:
1023 kfree(host_root_path);
1024out: 1009out:
1025 return err; 1010 return err;
1026} 1011}
@@ -1032,11 +1017,17 @@ static int hostfs_read_sb(struct file_system_type *type,
1032 return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt); 1017 return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt);
1033} 1018}
1034 1019
1020static void hostfs_kill_sb(struct super_block *s)
1021{
1022 kill_anon_super(s);
1023 kfree(s->s_fs_info);
1024}
1025
1035static struct file_system_type hostfs_type = { 1026static struct file_system_type hostfs_type = {
1036 .owner = THIS_MODULE, 1027 .owner = THIS_MODULE,
1037 .name = "hostfs", 1028 .name = "hostfs",
1038 .get_sb = hostfs_read_sb, 1029 .get_sb = hostfs_read_sb,
1039 .kill_sb = kill_anon_super, 1030 .kill_sb = hostfs_kill_sb,
1040 .fs_flags = 0, 1031 .fs_flags = 0,
1041}; 1032};
1042 1033