diff options
Diffstat (limited to 'fs/ext2/super.c')
-rw-r--r-- | fs/ext2/super.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 1ec602673ea8..1dd62ed35b85 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -43,9 +43,10 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data); | |||
43 | static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); | 43 | static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); |
44 | static int ext2_sync_fs(struct super_block *sb, int wait); | 44 | static int ext2_sync_fs(struct super_block *sb, int wait); |
45 | 45 | ||
46 | void ext2_error (struct super_block * sb, const char * function, | 46 | void ext2_error(struct super_block *sb, const char *function, |
47 | const char * fmt, ...) | 47 | const char *fmt, ...) |
48 | { | 48 | { |
49 | struct va_format vaf; | ||
49 | va_list args; | 50 | va_list args; |
50 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 51 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
51 | struct ext2_super_block *es = sbi->s_es; | 52 | struct ext2_super_block *es = sbi->s_es; |
@@ -59,9 +60,13 @@ void ext2_error (struct super_block * sb, const char * function, | |||
59 | } | 60 | } |
60 | 61 | ||
61 | va_start(args, fmt); | 62 | va_start(args, fmt); |
62 | printk(KERN_CRIT "EXT2-fs (%s): error: %s: ", sb->s_id, function); | 63 | |
63 | vprintk(fmt, args); | 64 | vaf.fmt = fmt; |
64 | printk("\n"); | 65 | vaf.va = &args; |
66 | |||
67 | printk(KERN_CRIT "EXT2-fs (%s): error: %s: %pV\n", | ||
68 | sb->s_id, function, &vaf); | ||
69 | |||
65 | va_end(args); | 70 | va_end(args); |
66 | 71 | ||
67 | if (test_opt(sb, ERRORS_PANIC)) | 72 | if (test_opt(sb, ERRORS_PANIC)) |
@@ -76,12 +81,16 @@ void ext2_error (struct super_block * sb, const char * function, | |||
76 | void ext2_msg(struct super_block *sb, const char *prefix, | 81 | void ext2_msg(struct super_block *sb, const char *prefix, |
77 | const char *fmt, ...) | 82 | const char *fmt, ...) |
78 | { | 83 | { |
84 | struct va_format vaf; | ||
79 | va_list args; | 85 | va_list args; |
80 | 86 | ||
81 | va_start(args, fmt); | 87 | va_start(args, fmt); |
82 | printk("%sEXT2-fs (%s): ", prefix, sb->s_id); | 88 | |
83 | vprintk(fmt, args); | 89 | vaf.fmt = fmt; |
84 | printk("\n"); | 90 | vaf.va = &args; |
91 | |||
92 | printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf); | ||
93 | |||
85 | va_end(args); | 94 | va_end(args); |
86 | } | 95 | } |
87 | 96 | ||
@@ -161,11 +170,18 @@ static struct inode *ext2_alloc_inode(struct super_block *sb) | |||
161 | return &ei->vfs_inode; | 170 | return &ei->vfs_inode; |
162 | } | 171 | } |
163 | 172 | ||
164 | static void ext2_destroy_inode(struct inode *inode) | 173 | static void ext2_i_callback(struct rcu_head *head) |
165 | { | 174 | { |
175 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
176 | INIT_LIST_HEAD(&inode->i_dentry); | ||
166 | kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); | 177 | kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); |
167 | } | 178 | } |
168 | 179 | ||
180 | static void ext2_destroy_inode(struct inode *inode) | ||
181 | { | ||
182 | call_rcu(&inode->i_rcu, ext2_i_callback); | ||
183 | } | ||
184 | |||
169 | static void init_once(void *foo) | 185 | static void init_once(void *foo) |
170 | { | 186 | { |
171 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; | 187 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; |
@@ -747,15 +763,16 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
747 | __le32 features; | 763 | __le32 features; |
748 | int err; | 764 | int err; |
749 | 765 | ||
766 | err = -ENOMEM; | ||
750 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 767 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
751 | if (!sbi) | 768 | if (!sbi) |
752 | return -ENOMEM; | 769 | goto failed_unlock; |
753 | 770 | ||
754 | sbi->s_blockgroup_lock = | 771 | sbi->s_blockgroup_lock = |
755 | kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); | 772 | kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); |
756 | if (!sbi->s_blockgroup_lock) { | 773 | if (!sbi->s_blockgroup_lock) { |
757 | kfree(sbi); | 774 | kfree(sbi); |
758 | return -ENOMEM; | 775 | goto failed_unlock; |
759 | } | 776 | } |
760 | sb->s_fs_info = sbi; | 777 | sb->s_fs_info = sbi; |
761 | sbi->s_sb_block = sb_block; | 778 | sbi->s_sb_block = sb_block; |
@@ -881,7 +898,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
881 | brelse(bh); | 898 | brelse(bh); |
882 | 899 | ||
883 | if (!sb_set_blocksize(sb, blocksize)) { | 900 | if (!sb_set_blocksize(sb, blocksize)) { |
884 | ext2_msg(sb, KERN_ERR, "error: blocksize is too small"); | 901 | ext2_msg(sb, KERN_ERR, |
902 | "error: bad blocksize %d", blocksize); | ||
885 | goto failed_sbi; | 903 | goto failed_sbi; |
886 | } | 904 | } |
887 | 905 | ||
@@ -1107,6 +1125,7 @@ failed_sbi: | |||
1107 | sb->s_fs_info = NULL; | 1125 | sb->s_fs_info = NULL; |
1108 | kfree(sbi->s_blockgroup_lock); | 1126 | kfree(sbi->s_blockgroup_lock); |
1109 | kfree(sbi); | 1127 | kfree(sbi); |
1128 | failed_unlock: | ||
1110 | return ret; | 1129 | return ret; |
1111 | } | 1130 | } |
1112 | 1131 | ||
@@ -1219,9 +1238,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1219 | } | 1238 | } |
1220 | 1239 | ||
1221 | es = sbi->s_es; | 1240 | es = sbi->s_es; |
1222 | if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != | 1241 | if ((sbi->s_mount_opt ^ old_mount_opt) & EXT2_MOUNT_XIP) { |
1223 | (old_mount_opt & EXT2_MOUNT_XIP)) && | ||
1224 | invalidate_inodes(sb)) { | ||
1225 | ext2_msg(sb, KERN_WARNING, "warning: refusing change of " | 1242 | ext2_msg(sb, KERN_WARNING, "warning: refusing change of " |
1226 | "xip flag with busy inodes while remounting"); | 1243 | "xip flag with busy inodes while remounting"); |
1227 | sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; | 1244 | sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; |
@@ -1356,17 +1373,17 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1356 | return 0; | 1373 | return 0; |
1357 | } | 1374 | } |
1358 | 1375 | ||
1359 | static int ext2_get_sb(struct file_system_type *fs_type, | 1376 | static struct dentry *ext2_mount(struct file_system_type *fs_type, |
1360 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 1377 | int flags, const char *dev_name, void *data) |
1361 | { | 1378 | { |
1362 | return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super, mnt); | 1379 | return mount_bdev(fs_type, flags, dev_name, data, ext2_fill_super); |
1363 | } | 1380 | } |
1364 | 1381 | ||
1365 | #ifdef CONFIG_QUOTA | 1382 | #ifdef CONFIG_QUOTA |
1366 | 1383 | ||
1367 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | 1384 | /* Read data from quotafile - avoid pagecache and such because we cannot afford |
1368 | * acquiring the locks... As quota files are never truncated and quota code | 1385 | * acquiring the locks... As quota files are never truncated and quota code |
1369 | * itself serializes the operations (and noone else should touch the files) | 1386 | * itself serializes the operations (and no one else should touch the files) |
1370 | * we don't have to be afraid of races */ | 1387 | * we don't have to be afraid of races */ |
1371 | static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, | 1388 | static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, |
1372 | size_t len, loff_t off) | 1389 | size_t len, loff_t off) |
@@ -1473,7 +1490,7 @@ out: | |||
1473 | static struct file_system_type ext2_fs_type = { | 1490 | static struct file_system_type ext2_fs_type = { |
1474 | .owner = THIS_MODULE, | 1491 | .owner = THIS_MODULE, |
1475 | .name = "ext2", | 1492 | .name = "ext2", |
1476 | .get_sb = ext2_get_sb, | 1493 | .mount = ext2_mount, |
1477 | .kill_sb = kill_block_super, | 1494 | .kill_sb = kill_block_super, |
1478 | .fs_flags = FS_REQUIRES_DEV, | 1495 | .fs_flags = FS_REQUIRES_DEV, |
1479 | }; | 1496 | }; |