aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-03-16 23:12:23 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-03-16 23:12:23 -0400
commitafd4672dc7610b7feef5190168aa917cc2e417e4 (patch)
tree53a3aa709232b00473c8da70b792b350150956ff
parent7d39db14a42cbd719c7515b9da8f85a2eb6a0633 (diff)
ext4: Add auto_da_alloc mount option
Add a mount option which allows the user to disable automatic allocation of blocks whose allocation by delayed allocation when the file was originally truncated or when the file is renamed over an existing file. This feature is intended to save users from the effects of naive application writers, but it reduces the effectiveness of the delayed allocation code. This mount option disables this safety feature, which may be desirable for prodcutions systems where the risk of unclean shutdowns or unexpected system crashes is low. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/ext4.h2
-rw-r--r--fs/ext4/inode.c2
-rw-r--r--fs/ext4/namei.c3
-rw-r--r--fs/ext4/super.c25
4 files changed, 17 insertions, 15 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 46aaaa2ed4c5..a004699e7296 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -549,7 +549,7 @@ do { \
549#define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ 549#define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */
550#define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ 550#define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */
551#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ 551#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
552#define EXT4_MOUNT_RESERVATION 0x10000 /* Preallocation */ 552#define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */
553#define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ 553#define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */
554#define EXT4_MOUNT_NOBH 0x40000 /* No bufferheads */ 554#define EXT4_MOUNT_NOBH 0x40000 /* No bufferheads */
555#define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ 555#define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d3118d1acc39..bed4a0abd0d1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3908,7 +3908,7 @@ void ext4_truncate(struct inode *inode)
3908 if (!ext4_can_truncate(inode)) 3908 if (!ext4_can_truncate(inode))
3909 return; 3909 return;
3910 3910
3911 if (inode->i_size == 0) 3911 if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
3912 ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE; 3912 ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE;
3913 3913
3914 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 3914 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index eb20246c8965..22098e1cd085 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2497,7 +2497,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2497 ext4_mark_inode_dirty(handle, new_inode); 2497 ext4_mark_inode_dirty(handle, new_inode);
2498 if (!new_inode->i_nlink) 2498 if (!new_inode->i_nlink)
2499 ext4_orphan_add(handle, new_inode); 2499 ext4_orphan_add(handle, new_inode);
2500 force_da_alloc = 1; 2500 if (!test_opt(new_dir->i_sb, NO_AUTO_DA_ALLOC))
2501 force_da_alloc = 1;
2501 } 2502 }
2502 retval = 0; 2503 retval = 0;
2503 2504
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b9aefceb41e7..45d07cf9df34 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -816,8 +816,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
816 if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL)) 816 if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))
817 seq_puts(seq, ",noacl"); 817 seq_puts(seq, ",noacl");
818#endif 818#endif
819 if (!test_opt(sb, RESERVATION))
820 seq_puts(seq, ",noreservation");
821 if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) { 819 if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
822 seq_printf(seq, ",commit=%u", 820 seq_printf(seq, ",commit=%u",
823 (unsigned) (sbi->s_commit_interval / HZ)); 821 (unsigned) (sbi->s_commit_interval / HZ));
@@ -868,6 +866,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
868 if (test_opt(sb, DATA_ERR_ABORT)) 866 if (test_opt(sb, DATA_ERR_ABORT))
869 seq_puts(seq, ",data_err=abort"); 867 seq_puts(seq, ",data_err=abort");
870 868
869 if (test_opt(sb, NO_AUTO_DA_ALLOC))
870 seq_puts(seq, ",auto_da_alloc=0");
871
871 ext4_show_quota_options(seq, sb); 872 ext4_show_quota_options(seq, sb);
872 return 0; 873 return 0;
873} 874}
@@ -1017,7 +1018,7 @@ enum {
1017 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, 1018 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
1018 Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov, 1019 Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov,
1019 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, 1020 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
1020 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, 1021 Opt_auto_da_alloc, Opt_noload, Opt_nobh, Opt_bh,
1021 Opt_commit, Opt_min_batch_time, Opt_max_batch_time, 1022 Opt_commit, Opt_min_batch_time, Opt_max_batch_time,
1022 Opt_journal_update, Opt_journal_dev, 1023 Opt_journal_update, Opt_journal_dev,
1023 Opt_journal_checksum, Opt_journal_async_commit, 1024 Opt_journal_checksum, Opt_journal_async_commit,
@@ -1052,8 +1053,6 @@ static const match_table_t tokens = {
1052 {Opt_nouser_xattr, "nouser_xattr"}, 1053 {Opt_nouser_xattr, "nouser_xattr"},
1053 {Opt_acl, "acl"}, 1054 {Opt_acl, "acl"},
1054 {Opt_noacl, "noacl"}, 1055 {Opt_noacl, "noacl"},
1055 {Opt_reservation, "reservation"},
1056 {Opt_noreservation, "noreservation"},
1057 {Opt_noload, "noload"}, 1056 {Opt_noload, "noload"},
1058 {Opt_nobh, "nobh"}, 1057 {Opt_nobh, "nobh"},
1059 {Opt_bh, "bh"}, 1058 {Opt_bh, "bh"},
@@ -1088,6 +1087,7 @@ static const match_table_t tokens = {
1088 {Opt_nodelalloc, "nodelalloc"}, 1087 {Opt_nodelalloc, "nodelalloc"},
1089 {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, 1088 {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
1090 {Opt_journal_ioprio, "journal_ioprio=%u"}, 1089 {Opt_journal_ioprio, "journal_ioprio=%u"},
1090 {Opt_auto_da_alloc, "auto_da_alloc=%u"},
1091 {Opt_err, NULL}, 1091 {Opt_err, NULL},
1092}; 1092};
1093 1093
@@ -1220,12 +1220,6 @@ static int parse_options(char *options, struct super_block *sb,
1220 "not supported\n"); 1220 "not supported\n");
1221 break; 1221 break;
1222#endif 1222#endif
1223 case Opt_reservation:
1224 set_opt(sbi->s_mount_opt, RESERVATION);
1225 break;
1226 case Opt_noreservation:
1227 clear_opt(sbi->s_mount_opt, RESERVATION);
1228 break;
1229 case Opt_journal_update: 1223 case Opt_journal_update:
1230 /* @@@ FIXME */ 1224 /* @@@ FIXME */
1231 /* Eventually we will want to be able to create 1225 /* Eventually we will want to be able to create
@@ -1491,6 +1485,14 @@ set_qf_format:
1491 *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 1485 *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE,
1492 option); 1486 option);
1493 break; 1487 break;
1488 case Opt_auto_da_alloc:
1489 if (match_int(&args[0], &option))
1490 return 0;
1491 if (option)
1492 clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC);
1493 else
1494 set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
1495 break;
1494 default: 1496 default:
1495 printk(KERN_ERR 1497 printk(KERN_ERR
1496 "EXT4-fs: Unrecognized mount option \"%s\" " 1498 "EXT4-fs: Unrecognized mount option \"%s\" "
@@ -2306,7 +2308,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2306 sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; 2308 sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
2307 sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; 2309 sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
2308 2310
2309 set_opt(sbi->s_mount_opt, RESERVATION);
2310 set_opt(sbi->s_mount_opt, BARRIER); 2311 set_opt(sbi->s_mount_opt, BARRIER);
2311 2312
2312 /* 2313 /*