Created
January 20, 2015 18:55
-
-
Save invisiblek/e6e5a55437314c9f3dfa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c | |
index 5b95e18..4296a6f 100644 | |
--- a/fs/ext4/extents.c | |
+++ b/fs/ext4/extents.c | |
@@ -2111,7 +2111,7 @@ static int | |
ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block, | |
struct ext4_extent *ex) | |
{ | |
- struct ext4_ext_cache cex = {0, 0, 0}; | |
+ struct ext4_ext_cache cex; | |
int ret = 0; | |
if (ext4_ext_check_cache(inode, block, &cex)) { | |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c | |
index 6eee255..9727522 100644 | |
--- a/fs/ext4/ioctl.c | |
+++ b/fs/ext4/ioctl.c | |
@@ -38,7 +38,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |
handle_t *handle = NULL; | |
int err, migrate = 0; | |
struct ext4_iloc iloc; | |
- unsigned int oldflags; | |
+ unsigned int oldflags, mask, i; | |
unsigned int jflag; | |
if (!inode_owner_or_capable(inode)) | |
@@ -115,9 +115,14 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |
if (err) | |
goto flags_err; | |
- flags = flags & EXT4_FL_USER_MODIFIABLE; | |
- flags |= oldflags & ~EXT4_FL_USER_MODIFIABLE; | |
- ei->i_flags = flags; | |
+ for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { | |
+ if (!(mask & EXT4_FL_USER_MODIFIABLE)) | |
+ continue; | |
+ if (mask & flags) | |
+ ext4_set_inode_flag(inode, i); | |
+ else | |
+ ext4_clear_inode_flag(inode, i); | |
+ } | |
ext4_set_inode_flags(inode); | |
inode->i_ctime = ext4_current_time(inode); | |
@@ -256,7 +261,6 @@ group_extend_out: | |
err = ext4_move_extents(filp, donor_filp, me.orig_start, | |
me.donor_start, me.len, &me.moved_len); | |
mnt_drop_write_file(filp); | |
- mnt_drop_write(filp->f_path.mnt); | |
if (copy_to_user((struct move_extent __user *)arg, | |
&me, sizeof(me))) | |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c | |
index 9898edc..cdfc763 100644 | |
--- a/fs/ext4/mballoc.c | |
+++ b/fs/ext4/mballoc.c | |
@@ -1980,7 +1980,11 @@ repeat: | |
group = ac->ac_g_ex.fe_group; | |
for (i = 0; i < ngroups; group++, i++) { | |
- if (group == ngroups) | |
+ /* | |
+ * Artificially restricted ngroups for non-extent | |
+ * files makes group > ngroups possible on first loop. | |
+ */ | |
+ if (group >= ngroups) | |
group = 0; | |
/* This now checks without needing the buddy page */ | |
@@ -2517,6 +2521,9 @@ int ext4_mb_release(struct super_block *sb) | |
struct ext4_sb_info *sbi = EXT4_SB(sb); | |
struct kmem_cache *cachep = get_groupinfo_cache(sb->s_blocksize_bits); | |
+ if (sbi->s_proc) | |
+ remove_proc_entry("mb_groups", sbi->s_proc); | |
+ | |
if (sbi->s_group_info) { | |
for (i = 0; i < ngroups; i++) { | |
grinfo = ext4_get_group_info(sb, i); | |
@@ -2564,8 +2571,6 @@ int ext4_mb_release(struct super_block *sb) | |
} | |
free_percpu(sbi->s_locality_groups); | |
- if (sbi->s_proc) | |
- remove_proc_entry("mb_groups", sbi->s_proc); | |
return 0; | |
} | |
@@ -4130,7 +4135,7 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac) | |
/* The max size of hash table is PREALLOC_TB_SIZE */ | |
order = PREALLOC_TB_SIZE - 1; | |
/* Add the prealloc space to lg */ | |
- rcu_read_lock(); | |
+ spin_lock(&lg->lg_prealloc_lock); | |
list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order], | |
pa_inode_list) { | |
spin_lock(&tmp_pa->pa_lock); | |
@@ -4154,12 +4159,12 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac) | |
if (!added) | |
list_add_tail_rcu(&pa->pa_inode_list, | |
&lg->lg_prealloc_list[order]); | |
- rcu_read_unlock(); | |
+ spin_unlock(&lg->lg_prealloc_lock); | |
/* Now trim the list to be not more than 8 elements */ | |
if (lg_prealloc_count > 8) { | |
ext4_mb_discard_lg_preallocations(sb, lg, | |
- order, lg_prealloc_count); | |
+ order, lg_prealloc_count); | |
return; | |
} | |
return ; | |
@@ -4639,10 +4644,16 @@ do_more: | |
* blocks being freed are metadata. these blocks shouldn't | |
* be used until this transaction is committed | |
*/ | |
+ retry: | |
new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS); | |
if (!new_entry) { | |
- err = -ENOMEM; | |
- goto error_return; | |
+ /* | |
+ * We use a retry loop because | |
+ * ext4_free_blocks() is not allowed to fail. | |
+ */ | |
+ cond_resched(); | |
+ congestion_wait(BLK_RW_ASYNC, HZ/50); | |
+ goto retry; | |
} | |
new_entry->efd_start_cluster = bit; | |
new_entry->efd_group = block_group; | |
@@ -4987,8 +4998,9 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) | |
end = start + (range->len >> sb->s_blocksize_bits) - 1; | |
minlen = range->minlen >> sb->s_blocksize_bits; | |
- if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)) || | |
- unlikely(start >= max_blks)) | |
+ if (minlen > EXT4_CLUSTERS_PER_GROUP(sb) || | |
+ start >= max_blks || | |
+ range->len < sb->s_blocksize) | |
return -EINVAL; | |
if (end >= max_blks) | |
end = max_blks - 1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment