mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: jbd2: update transaction t_state to T_COMMIT fix ext4: Retry block allocation if new blocks are allocated from system zone. ext4: mballoc fix mb_normalize_request algorithm for 1KB block size filesystems ext4: fix typos in messages and comments (journalled -> journaled) ext4: fix synchronization of quota files in journal=data mode ext4: Fix mount messages when quota disabled ext4: correct mount option parsing to detect when quota options can be changed
This commit is contained in:
commit
ac0e9c30b1
@ -287,11 +287,11 @@ read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
|
|||||||
(int)block_group, (unsigned long long)bitmap_blk);
|
(int)block_group, (unsigned long long)bitmap_blk);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!ext4_valid_block_bitmap(sb, desc, block_group, bh)) {
|
ext4_valid_block_bitmap(sb, desc, block_group, bh);
|
||||||
put_bh(bh);
|
/*
|
||||||
return NULL;
|
* file system mounted not to panic on error,
|
||||||
}
|
* continue with corrupt bitmap
|
||||||
|
*/
|
||||||
return bh;
|
return bh;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -1770,7 +1770,12 @@ allocated:
|
|||||||
"Allocating block in system zone - "
|
"Allocating block in system zone - "
|
||||||
"blocks from %llu, length %lu",
|
"blocks from %llu, length %lu",
|
||||||
ret_block, num);
|
ret_block, num);
|
||||||
goto out;
|
/*
|
||||||
|
* claim_block marked the blocks we allocated
|
||||||
|
* as in use. So we may want to selectively
|
||||||
|
* mark some of the blocks as free
|
||||||
|
*/
|
||||||
|
goto retry_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
performed_allocation = 1;
|
performed_allocation = 1;
|
||||||
|
@ -2736,7 +2736,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
|
|||||||
struct ext4_sb_info *sbi;
|
struct ext4_sb_info *sbi;
|
||||||
struct super_block *sb;
|
struct super_block *sb;
|
||||||
ext4_fsblk_t block;
|
ext4_fsblk_t block;
|
||||||
int err;
|
int err, len;
|
||||||
|
|
||||||
BUG_ON(ac->ac_status != AC_STATUS_FOUND);
|
BUG_ON(ac->ac_status != AC_STATUS_FOUND);
|
||||||
BUG_ON(ac->ac_b_ex.fe_len <= 0);
|
BUG_ON(ac->ac_b_ex.fe_len <= 0);
|
||||||
@ -2770,14 +2770,27 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
|
|||||||
+ ac->ac_b_ex.fe_start
|
+ ac->ac_b_ex.fe_start
|
||||||
+ le32_to_cpu(es->s_first_data_block);
|
+ le32_to_cpu(es->s_first_data_block);
|
||||||
|
|
||||||
if (block == ext4_block_bitmap(sb, gdp) ||
|
len = ac->ac_b_ex.fe_len;
|
||||||
block == ext4_inode_bitmap(sb, gdp) ||
|
if (in_range(ext4_block_bitmap(sb, gdp), block, len) ||
|
||||||
in_range(block, ext4_inode_table(sb, gdp),
|
in_range(ext4_inode_bitmap(sb, gdp), block, len) ||
|
||||||
EXT4_SB(sb)->s_itb_per_group)) {
|
in_range(block, ext4_inode_table(sb, gdp),
|
||||||
|
EXT4_SB(sb)->s_itb_per_group) ||
|
||||||
|
in_range(block + len - 1, ext4_inode_table(sb, gdp),
|
||||||
|
EXT4_SB(sb)->s_itb_per_group)) {
|
||||||
ext4_error(sb, __func__,
|
ext4_error(sb, __func__,
|
||||||
"Allocating block in system zone - block = %llu",
|
"Allocating block in system zone - block = %llu",
|
||||||
block);
|
block);
|
||||||
|
/* File system mounted not to panic on error
|
||||||
|
* Fix the bitmap and repeat the block allocation
|
||||||
|
* We leak some of the blocks here.
|
||||||
|
*/
|
||||||
|
mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group),
|
||||||
|
bitmap_bh->b_data, ac->ac_b_ex.fe_start,
|
||||||
|
ac->ac_b_ex.fe_len);
|
||||||
|
err = ext4_journal_dirty_metadata(handle, bitmap_bh);
|
||||||
|
if (!err)
|
||||||
|
err = -EAGAIN;
|
||||||
|
goto out_err;
|
||||||
}
|
}
|
||||||
#ifdef AGGRESSIVE_CHECK
|
#ifdef AGGRESSIVE_CHECK
|
||||||
{
|
{
|
||||||
@ -2880,12 +2893,11 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
|
|||||||
if (size < i_size_read(ac->ac_inode))
|
if (size < i_size_read(ac->ac_inode))
|
||||||
size = i_size_read(ac->ac_inode);
|
size = i_size_read(ac->ac_inode);
|
||||||
|
|
||||||
/* max available blocks in a free group */
|
/* max size of free chunks */
|
||||||
max = EXT4_BLOCKS_PER_GROUP(ac->ac_sb) - 1 - 1 -
|
max = 2 << bsbits;
|
||||||
EXT4_SB(ac->ac_sb)->s_itb_per_group;
|
|
||||||
|
|
||||||
#define NRL_CHECK_SIZE(req, size, max,bits) \
|
#define NRL_CHECK_SIZE(req, size, max, chunk_size) \
|
||||||
(req <= (size) || max <= ((size) >> bits))
|
(req <= (size) || max <= (chunk_size))
|
||||||
|
|
||||||
/* first, try to predict filesize */
|
/* first, try to predict filesize */
|
||||||
/* XXX: should this table be tunable? */
|
/* XXX: should this table be tunable? */
|
||||||
@ -2904,16 +2916,16 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
|
|||||||
size = 512 * 1024;
|
size = 512 * 1024;
|
||||||
} else if (size <= 1024 * 1024) {
|
} else if (size <= 1024 * 1024) {
|
||||||
size = 1024 * 1024;
|
size = 1024 * 1024;
|
||||||
} else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, bsbits)) {
|
} else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, 2 * 1024)) {
|
||||||
start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
|
start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
|
||||||
(20 - bsbits)) << 20;
|
(21 - bsbits)) << 21;
|
||||||
size = 1024 * 1024;
|
size = 2 * 1024 * 1024;
|
||||||
} else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, bsbits)) {
|
} else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, 4 * 1024)) {
|
||||||
start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
|
start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
|
||||||
(22 - bsbits)) << 22;
|
(22 - bsbits)) << 22;
|
||||||
size = 4 * 1024 * 1024;
|
size = 4 * 1024 * 1024;
|
||||||
} else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len,
|
} else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len,
|
||||||
(8<<20)>>bsbits, max, bsbits)) {
|
(8<<20)>>bsbits, max, 8 * 1024)) {
|
||||||
start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
|
start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
|
||||||
(23 - bsbits)) << 23;
|
(23 - bsbits)) << 23;
|
||||||
size = 8 * 1024 * 1024;
|
size = 8 * 1024 * 1024;
|
||||||
@ -4033,7 +4045,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
|
|||||||
|
|
||||||
ac->ac_op = EXT4_MB_HISTORY_ALLOC;
|
ac->ac_op = EXT4_MB_HISTORY_ALLOC;
|
||||||
ext4_mb_normalize_request(ac, ar);
|
ext4_mb_normalize_request(ac, ar);
|
||||||
|
|
||||||
repeat:
|
repeat:
|
||||||
/* allocate space in core */
|
/* allocate space in core */
|
||||||
ext4_mb_regular_allocator(ac);
|
ext4_mb_regular_allocator(ac);
|
||||||
@ -4047,10 +4058,21 @@ repeat:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (likely(ac->ac_status == AC_STATUS_FOUND)) {
|
if (likely(ac->ac_status == AC_STATUS_FOUND)) {
|
||||||
ext4_mb_mark_diskspace_used(ac, handle);
|
*errp = ext4_mb_mark_diskspace_used(ac, handle);
|
||||||
*errp = 0;
|
if (*errp == -EAGAIN) {
|
||||||
block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
|
ac->ac_b_ex.fe_group = 0;
|
||||||
ar->len = ac->ac_b_ex.fe_len;
|
ac->ac_b_ex.fe_start = 0;
|
||||||
|
ac->ac_b_ex.fe_len = 0;
|
||||||
|
ac->ac_status = AC_STATUS_CONTINUE;
|
||||||
|
goto repeat;
|
||||||
|
} else if (*errp) {
|
||||||
|
ac->ac_b_ex.fe_len = 0;
|
||||||
|
ar->len = 0;
|
||||||
|
ext4_mb_show_ac(ac);
|
||||||
|
} else {
|
||||||
|
block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
|
||||||
|
ar->len = ac->ac_b_ex.fe_len;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
freed = ext4_mb_discard_preallocations(sb, ac->ac_o_ex.fe_len);
|
freed = ext4_mb_discard_preallocations(sb, ac->ac_o_ex.fe_len);
|
||||||
if (freed)
|
if (freed)
|
||||||
@ -4237,6 +4259,8 @@ do_more:
|
|||||||
ext4_error(sb, __func__,
|
ext4_error(sb, __func__,
|
||||||
"Freeing blocks in system zone - "
|
"Freeing blocks in system zone - "
|
||||||
"Block = %lu, count = %lu", block, count);
|
"Block = %lu, count = %lu", block, count);
|
||||||
|
/* err = 0. ext4_std_error should be a no op */
|
||||||
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUFFER_TRACE(bitmap_bh, "getting write access");
|
BUFFER_TRACE(bitmap_bh, "getting write access");
|
||||||
|
@ -979,7 +979,7 @@ static int parse_options (char *options, struct super_block *sb,
|
|||||||
int data_opt = 0;
|
int data_opt = 0;
|
||||||
int option;
|
int option;
|
||||||
#ifdef CONFIG_QUOTA
|
#ifdef CONFIG_QUOTA
|
||||||
int qtype;
|
int qtype, qfmt;
|
||||||
char *qname;
|
char *qname;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1162,9 +1162,11 @@ static int parse_options (char *options, struct super_block *sb,
|
|||||||
case Opt_grpjquota:
|
case Opt_grpjquota:
|
||||||
qtype = GRPQUOTA;
|
qtype = GRPQUOTA;
|
||||||
set_qf_name:
|
set_qf_name:
|
||||||
if (sb_any_quota_enabled(sb)) {
|
if ((sb_any_quota_enabled(sb) ||
|
||||||
|
sb_any_quota_suspended(sb)) &&
|
||||||
|
!sbi->s_qf_names[qtype]) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"EXT4-fs: Cannot change journalled "
|
"EXT4-fs: Cannot change journaled "
|
||||||
"quota options when quota turned on.\n");
|
"quota options when quota turned on.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1200,9 +1202,11 @@ set_qf_name:
|
|||||||
case Opt_offgrpjquota:
|
case Opt_offgrpjquota:
|
||||||
qtype = GRPQUOTA;
|
qtype = GRPQUOTA;
|
||||||
clear_qf_name:
|
clear_qf_name:
|
||||||
if (sb_any_quota_enabled(sb)) {
|
if ((sb_any_quota_enabled(sb) ||
|
||||||
|
sb_any_quota_suspended(sb)) &&
|
||||||
|
sbi->s_qf_names[qtype]) {
|
||||||
printk(KERN_ERR "EXT4-fs: Cannot change "
|
printk(KERN_ERR "EXT4-fs: Cannot change "
|
||||||
"journalled quota options when "
|
"journaled quota options when "
|
||||||
"quota turned on.\n");
|
"quota turned on.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1213,10 +1217,20 @@ clear_qf_name:
|
|||||||
sbi->s_qf_names[qtype] = NULL;
|
sbi->s_qf_names[qtype] = NULL;
|
||||||
break;
|
break;
|
||||||
case Opt_jqfmt_vfsold:
|
case Opt_jqfmt_vfsold:
|
||||||
sbi->s_jquota_fmt = QFMT_VFS_OLD;
|
qfmt = QFMT_VFS_OLD;
|
||||||
break;
|
goto set_qf_format;
|
||||||
case Opt_jqfmt_vfsv0:
|
case Opt_jqfmt_vfsv0:
|
||||||
sbi->s_jquota_fmt = QFMT_VFS_V0;
|
qfmt = QFMT_VFS_V0;
|
||||||
|
set_qf_format:
|
||||||
|
if ((sb_any_quota_enabled(sb) ||
|
||||||
|
sb_any_quota_suspended(sb)) &&
|
||||||
|
sbi->s_jquota_fmt != qfmt) {
|
||||||
|
printk(KERN_ERR "EXT4-fs: Cannot change "
|
||||||
|
"journaled quota options when "
|
||||||
|
"quota turned on.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sbi->s_jquota_fmt = qfmt;
|
||||||
break;
|
break;
|
||||||
case Opt_quota:
|
case Opt_quota:
|
||||||
case Opt_usrquota:
|
case Opt_usrquota:
|
||||||
@ -1241,6 +1255,9 @@ clear_qf_name:
|
|||||||
case Opt_quota:
|
case Opt_quota:
|
||||||
case Opt_usrquota:
|
case Opt_usrquota:
|
||||||
case Opt_grpquota:
|
case Opt_grpquota:
|
||||||
|
printk(KERN_ERR
|
||||||
|
"EXT4-fs: quota options not supported.\n");
|
||||||
|
break;
|
||||||
case Opt_usrjquota:
|
case Opt_usrjquota:
|
||||||
case Opt_grpjquota:
|
case Opt_grpjquota:
|
||||||
case Opt_offusrjquota:
|
case Opt_offusrjquota:
|
||||||
@ -1248,7 +1265,7 @@ clear_qf_name:
|
|||||||
case Opt_jqfmt_vfsold:
|
case Opt_jqfmt_vfsold:
|
||||||
case Opt_jqfmt_vfsv0:
|
case Opt_jqfmt_vfsv0:
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"EXT4-fs: journalled quota options not "
|
"EXT4-fs: journaled quota options not "
|
||||||
"supported.\n");
|
"supported.\n");
|
||||||
break;
|
break;
|
||||||
case Opt_noquota:
|
case Opt_noquota:
|
||||||
@ -1333,14 +1350,14 @@ clear_qf_name:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sbi->s_jquota_fmt) {
|
if (!sbi->s_jquota_fmt) {
|
||||||
printk(KERN_ERR "EXT4-fs: journalled quota format "
|
printk(KERN_ERR "EXT4-fs: journaled quota format "
|
||||||
"not specified.\n");
|
"not specified.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (sbi->s_jquota_fmt) {
|
if (sbi->s_jquota_fmt) {
|
||||||
printk(KERN_ERR "EXT4-fs: journalled quota format "
|
printk(KERN_ERR "EXT4-fs: journaled quota format "
|
||||||
"specified with no journalling "
|
"specified with no journaling "
|
||||||
"enabled.\n");
|
"enabled.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1581,7 +1598,7 @@ static void ext4_orphan_cleanup (struct super_block * sb,
|
|||||||
int ret = ext4_quota_on_mount(sb, i);
|
int ret = ext4_quota_on_mount(sb, i);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"EXT4-fs: Cannot turn on journalled "
|
"EXT4-fs: Cannot turn on journaled "
|
||||||
"quota: error %d\n", ret);
|
"quota: error %d\n", ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3106,7 +3123,7 @@ static int ext4_release_dquot(struct dquot *dquot)
|
|||||||
|
|
||||||
static int ext4_mark_dquot_dirty(struct dquot *dquot)
|
static int ext4_mark_dquot_dirty(struct dquot *dquot)
|
||||||
{
|
{
|
||||||
/* Are we journalling quotas? */
|
/* Are we journaling quotas? */
|
||||||
if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
|
if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
|
||||||
EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
|
EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
|
||||||
dquot_mark_dquot_dirty(dquot);
|
dquot_mark_dquot_dirty(dquot);
|
||||||
@ -3153,23 +3170,42 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
|
|||||||
|
|
||||||
if (!test_opt(sb, QUOTA))
|
if (!test_opt(sb, QUOTA))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
/* Not journalling quota? */
|
/* When remounting, no checks are needed and in fact, path is NULL */
|
||||||
if ((!EXT4_SB(sb)->s_qf_names[USRQUOTA] &&
|
if (remount)
|
||||||
!EXT4_SB(sb)->s_qf_names[GRPQUOTA]) || remount)
|
|
||||||
return vfs_quota_on(sb, type, format_id, path, remount);
|
return vfs_quota_on(sb, type, format_id, path, remount);
|
||||||
|
|
||||||
err = path_lookup(path, LOOKUP_FOLLOW, &nd);
|
err = path_lookup(path, LOOKUP_FOLLOW, &nd);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* Quotafile not on the same filesystem? */
|
/* Quotafile not on the same filesystem? */
|
||||||
if (nd.path.mnt->mnt_sb != sb) {
|
if (nd.path.mnt->mnt_sb != sb) {
|
||||||
path_put(&nd.path);
|
path_put(&nd.path);
|
||||||
return -EXDEV;
|
return -EXDEV;
|
||||||
}
|
}
|
||||||
/* Quotafile not of fs root? */
|
/* Journaling quota? */
|
||||||
if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
|
if (EXT4_SB(sb)->s_qf_names[type]) {
|
||||||
printk(KERN_WARNING
|
/* Quotafile not of fs root? */
|
||||||
"EXT4-fs: Quota file not on filesystem root. "
|
if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
|
||||||
"Journalled quota will not work.\n");
|
printk(KERN_WARNING
|
||||||
|
"EXT4-fs: Quota file not on filesystem root. "
|
||||||
|
"Journaled quota will not work.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When we journal data on quota file, we have to flush journal to see
|
||||||
|
* all updates to the file when we bypass pagecache...
|
||||||
|
*/
|
||||||
|
if (ext4_should_journal_data(nd.path.dentry->d_inode)) {
|
||||||
|
/*
|
||||||
|
* We don't need to lock updates but journal_flush() could
|
||||||
|
* otherwise be livelocked...
|
||||||
|
*/
|
||||||
|
jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
|
||||||
|
jbd2_journal_flush(EXT4_SB(sb)->s_journal);
|
||||||
|
jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
|
||||||
|
}
|
||||||
|
|
||||||
path_put(&nd.path);
|
path_put(&nd.path);
|
||||||
return vfs_quota_on(sb, type, format_id, path, remount);
|
return vfs_quota_on(sb, type, format_id, path, remount);
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
|
|||||||
* transaction! Now comes the tricky part: we need to write out
|
* transaction! Now comes the tricky part: we need to write out
|
||||||
* metadata. Loop over the transaction's entire buffer list:
|
* metadata. Loop over the transaction's entire buffer list:
|
||||||
*/
|
*/
|
||||||
|
spin_lock(&journal->j_state_lock);
|
||||||
commit_transaction->t_state = T_COMMIT;
|
commit_transaction->t_state = T_COMMIT;
|
||||||
|
spin_unlock(&journal->j_state_lock);
|
||||||
|
|
||||||
stats.u.run.rs_logging = jiffies;
|
stats.u.run.rs_logging = jiffies;
|
||||||
stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing,
|
stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user