aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2/super.c')
-rw-r--r--fs/ext2/super.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 51b4c43b97e4..77bd5f9262f9 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -149,6 +149,7 @@ static struct inode *ext2_alloc_inode(struct super_block *sb)
149 ei->i_acl = EXT2_ACL_NOT_CACHED; 149 ei->i_acl = EXT2_ACL_NOT_CACHED;
150 ei->i_default_acl = EXT2_ACL_NOT_CACHED; 150 ei->i_default_acl = EXT2_ACL_NOT_CACHED;
151#endif 151#endif
152 ei->i_block_alloc_info = NULL;
152 ei->vfs_inode.i_version = 1; 153 ei->vfs_inode.i_version = 1;
153 return &ei->vfs_inode; 154 return &ei->vfs_inode;
154} 155}
@@ -166,6 +167,7 @@ static void init_once(struct kmem_cache * cachep, void *foo)
166#ifdef CONFIG_EXT2_FS_XATTR 167#ifdef CONFIG_EXT2_FS_XATTR
167 init_rwsem(&ei->xattr_sem); 168 init_rwsem(&ei->xattr_sem);
168#endif 169#endif
170 mutex_init(&ei->truncate_mutex);
169 inode_init_once(&ei->vfs_inode); 171 inode_init_once(&ei->vfs_inode);
170} 172}
171 173
@@ -188,6 +190,7 @@ static void destroy_inodecache(void)
188 190
189static void ext2_clear_inode(struct inode *inode) 191static void ext2_clear_inode(struct inode *inode)
190{ 192{
193 struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info;
191#ifdef CONFIG_EXT2_FS_POSIX_ACL 194#ifdef CONFIG_EXT2_FS_POSIX_ACL
192 struct ext2_inode_info *ei = EXT2_I(inode); 195 struct ext2_inode_info *ei = EXT2_I(inode);
193 196
@@ -200,6 +203,10 @@ static void ext2_clear_inode(struct inode *inode)
200 ei->i_default_acl = EXT2_ACL_NOT_CACHED; 203 ei->i_default_acl = EXT2_ACL_NOT_CACHED;
201 } 204 }
202#endif 205#endif
206 ext2_discard_reservation(inode);
207 EXT2_I(inode)->i_block_alloc_info = NULL;
208 if (unlikely(rsv))
209 kfree(rsv);
203} 210}
204 211
205static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) 212static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
@@ -291,7 +298,6 @@ static const struct super_operations ext2_sops = {
291 .destroy_inode = ext2_destroy_inode, 298 .destroy_inode = ext2_destroy_inode,
292 .read_inode = ext2_read_inode, 299 .read_inode = ext2_read_inode,
293 .write_inode = ext2_write_inode, 300 .write_inode = ext2_write_inode,
294 .put_inode = ext2_put_inode,
295 .delete_inode = ext2_delete_inode, 301 .delete_inode = ext2_delete_inode,
296 .put_super = ext2_put_super, 302 .put_super = ext2_put_super,
297 .write_super = ext2_write_super, 303 .write_super = ext2_write_super,
@@ -379,7 +385,7 @@ enum {
379 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug, 385 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
380 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr, 386 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
381 Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota, 387 Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
382 Opt_usrquota, Opt_grpquota 388 Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
383}; 389};
384 390
385static match_table_t tokens = { 391static match_table_t tokens = {
@@ -411,6 +417,8 @@ static match_table_t tokens = {
411 {Opt_ignore, "noquota"}, 417 {Opt_ignore, "noquota"},
412 {Opt_quota, "quota"}, 418 {Opt_quota, "quota"},
413 {Opt_usrquota, "usrquota"}, 419 {Opt_usrquota, "usrquota"},
420 {Opt_reservation, "reservation"},
421 {Opt_noreservation, "noreservation"},
414 {Opt_err, NULL} 422 {Opt_err, NULL}
415}; 423};
416 424
@@ -543,6 +551,14 @@ static int parse_options (char * options,
543 break; 551 break;
544#endif 552#endif
545 553
554 case Opt_reservation:
555 set_opt(sbi->s_mount_opt, RESERVATION);
556 printk("reservations ON\n");
557 break;
558 case Opt_noreservation:
559 clear_opt(sbi->s_mount_opt, RESERVATION);
560 printk("reservations OFF\n");
561 break;
546 case Opt_ignore: 562 case Opt_ignore:
547 break; 563 break;
548 default: 564 default:
@@ -784,6 +800,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
784 sbi->s_resuid = le16_to_cpu(es->s_def_resuid); 800 sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
785 sbi->s_resgid = le16_to_cpu(es->s_def_resgid); 801 sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
786 802
803 set_opt(sbi->s_mount_opt, RESERVATION);
804
787 if (!parse_options ((char *) data, sbi)) 805 if (!parse_options ((char *) data, sbi))
788 goto failed_mount; 806 goto failed_mount;
789 807
@@ -965,6 +983,21 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
965 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 983 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
966 spin_lock_init(&sbi->s_next_gen_lock); 984 spin_lock_init(&sbi->s_next_gen_lock);
967 985
986 /* per fileystem reservation list head & lock */
987 spin_lock_init(&sbi->s_rsv_window_lock);
988 sbi->s_rsv_window_root = RB_ROOT;
989 /*
990 * Add a single, static dummy reservation to the start of the
991 * reservation window list --- it gives us a placeholder for
992 * append-at-start-of-list which makes the allocation logic
993 * _much_ simpler.
994 */
995 sbi->s_rsv_window_head.rsv_start = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
996 sbi->s_rsv_window_head.rsv_end = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
997 sbi->s_rsv_window_head.rsv_alloc_hit = 0;
998 sbi->s_rsv_window_head.rsv_goal_size = 0;
999 ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
1000
968 err = percpu_counter_init(&sbi->s_freeblocks_counter, 1001 err = percpu_counter_init(&sbi->s_freeblocks_counter,
969 ext2_count_free_blocks(sb)); 1002 ext2_count_free_blocks(sb));
970 if (!err) { 1003 if (!err) {
@@ -1260,7 +1293,7 @@ static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data,
1260 1293
1261 tmp_bh.b_state = 0; 1294 tmp_bh.b_state = 0;
1262 err = ext2_get_block(inode, blk, &tmp_bh, 0); 1295 err = ext2_get_block(inode, blk, &tmp_bh, 0);
1263 if (err) 1296 if (err < 0)
1264 return err; 1297 return err;
1265 if (!buffer_mapped(&tmp_bh)) /* A hole? */ 1298 if (!buffer_mapped(&tmp_bh)) /* A hole? */
1266 memset(data, 0, tocopy); 1299 memset(data, 0, tocopy);
@@ -1299,7 +1332,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type,
1299 1332
1300 tmp_bh.b_state = 0; 1333 tmp_bh.b_state = 0;
1301 err = ext2_get_block(inode, blk, &tmp_bh, 1); 1334 err = ext2_get_block(inode, blk, &tmp_bh, 1);
1302 if (err) 1335 if (err < 0)
1303 goto out; 1336 goto out;
1304 if (offset || tocopy != EXT2_BLOCK_SIZE(sb)) 1337 if (offset || tocopy != EXT2_BLOCK_SIZE(sb))
1305 bh = sb_bread(sb, tmp_bh.b_blocknr); 1338 bh = sb_bread(sb, tmp_bh.b_blocknr);