diff options
author | rogersb11 <brettrogers11@gmail.com> | 2015-11-10 11:19:31 -0600 |
---|---|---|
committer | rogersb11 <brettrogers11@gmail.com> | 2015-11-10 14:01:25 -0500 |
commit | b4d16f70c34ecb908c8a61e58ea51fecdd4a4b10 (patch) | |
tree | 973e9aeb97bb13497d17a43e6f3c070381bc5b87 /fs/ext4 | |
parent | d177fbc2f0c263b06c18bda2eb46200a31bcbebd (diff) | |
parent | 5dba9ddd98cbc7ad319d687887981a0ea0062c75 (diff) | |
download | kernel_samsung_smdk4412-b4d16f70c34ecb908c8a61e58ea51fecdd4a4b10.zip kernel_samsung_smdk4412-b4d16f70c34ecb908c8a61e58ea51fecdd4a4b10.tar.gz kernel_samsung_smdk4412-b4d16f70c34ecb908c8a61e58ea51fecdd4a4b10.tar.bz2 |
Merge remote-tracking branch 'korg/linux-3.0.y' into cm-13.0
Conflicts:
crypto/algapi.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/intel_display.c
drivers/video/fbmem.c
include/linux/nls.h
kernel/cgroup.c
kernel/signal.c
kernel/timeconst.pl
net/ipv4/ping.c
Change-Id: I1f532925d1743df74d66bcdd6fc92f05c72ee0dd
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/Kconfig | 3 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 6 | ||||
-rw-r--r-- | fs/ext4/extents.c | 10 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 23 | ||||
-rw-r--r-- | fs/ext4/inode.c | 4 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 22 | ||||
-rw-r--r-- | fs/ext4/namei.c | 10 | ||||
-rw-r--r-- | fs/ext4/resize.c | 5 | ||||
-rw-r--r-- | fs/ext4/super.c | 23 | ||||
-rw-r--r-- | fs/ext4/xattr.c | 2 |
10 files changed, 61 insertions, 47 deletions
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index 9ed1bb1..5459168 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -82,4 +82,5 @@ config EXT4_DEBUG Enables run-time debugging support for the ext4 filesystem. If you select Y here, then you will be able to turn on debugging - with a command such as "echo 1 > /sys/kernel/debug/ext4/mballoc-debug" + with a command such as: + echo 1 > /sys/module/ext4/parameters/mballoc_debug diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 194a8c8..e256a40 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -288,9 +288,9 @@ struct ext4_group_desc */ struct flex_groups { - atomic_t free_inodes; - atomic_t free_blocks; - atomic_t used_dirs; + atomic64_t free_blocks; + atomic_t free_inodes; + atomic_t used_dirs; }; #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 42038c2..3988b9b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2901,6 +2901,7 @@ static int ext4_split_extent(handle_t *handle, int err = 0; int uninitialized; int split_flag1, flags1; + int allocated = map->m_len; depth = ext_depth(inode); ex = path[depth].p_ext; @@ -2919,6 +2920,8 @@ static int ext4_split_extent(handle_t *handle, map->m_lblk + map->m_len, split_flag1, flags1); if (err) goto out; + } else { + allocated = ee_len - (map->m_lblk - ee_block); } ext4_ext_drop_refs(path); @@ -2941,7 +2944,7 @@ static int ext4_split_extent(handle_t *handle, ext4_ext_show_leaf(inode, path); out: - return err ? err : map->m_len; + return err ? err : allocated; } #define EXT4_EXT_ZERO_LEN 7 @@ -3309,6 +3312,7 @@ out: allocated - map->m_len); allocated = map->m_len; } + map->m_len = allocated; /* * If we have done fallocate with the offset that is already @@ -4151,7 +4155,7 @@ static int ext4_xattr_fiemap(struct inode *inode, error = ext4_get_inode_loc(inode, &iloc); if (error) return error; - physical = iloc.bh->b_blocknr << blockbits; + physical = (__u64)iloc.bh->b_blocknr << blockbits; offset = EXT4_GOOD_OLD_INODE_SIZE + EXT4_I(inode)->i_extra_isize; physical += offset; @@ -4159,7 +4163,7 @@ static int ext4_xattr_fiemap(struct inode *inode, flags |= FIEMAP_EXTENT_DATA_INLINE; brelse(iloc.bh); } else { /* external block */ - physical = EXT4_I(inode)->i_file_acl << blockbits; + physical = (__u64)EXT4_I(inode)->i_file_acl << blockbits; length = inode->i_sb->s_blocksize; } diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 1e548b1..03ca84d 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -22,6 +22,7 @@ #include <linux/random.h> #include <linux/bitops.h> #include <linux/blkdev.h> +#include <linux/math64.h> #include <asm/byteorder.h> #include "ext4.h" @@ -349,8 +350,8 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, ext4_group_t ngroups = ext4_get_groups_count(sb); int flex_size = ext4_flex_bg_size(sbi); ext4_group_t best_flex = parent_fbg_group; - int blocks_per_flex = sbi->s_blocks_per_group * flex_size; - int flexbg_free_blocks; + ext4_fsblk_t blocks_per_flex = sbi->s_blocks_per_group * flex_size; + ext4_fsblk_t flexbg_free_blocks; int flex_freeb_ratio; ext4_group_t n_fbg_groups; ext4_group_t i; @@ -359,8 +360,8 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, sbi->s_log_groups_per_flex; find_close_to_parent: - flexbg_free_blocks = atomic_read(&flex_group[best_flex].free_blocks); - flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; + flexbg_free_blocks = atomic64_read(&flex_group[best_flex].free_blocks); + flex_freeb_ratio = div64_u64(flexbg_free_blocks * 100, blocks_per_flex); if (atomic_read(&flex_group[best_flex].free_inodes) && flex_freeb_ratio > free_block_ratio) goto found_flexbg; @@ -374,8 +375,8 @@ find_close_to_parent: if (i == parent_fbg_group || i == parent_fbg_group - 1) continue; - flexbg_free_blocks = atomic_read(&flex_group[i].free_blocks); - flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; + flexbg_free_blocks = atomic64_read(&flex_group[i].free_blocks); + flex_freeb_ratio = div64_u64(flexbg_free_blocks * 100, blocks_per_flex); if (flex_freeb_ratio > free_block_ratio && (atomic_read(&flex_group[i].free_inodes))) { @@ -384,14 +385,14 @@ find_close_to_parent: } if ((atomic_read(&flex_group[best_flex].free_inodes) == 0) || - ((atomic_read(&flex_group[i].free_blocks) > - atomic_read(&flex_group[best_flex].free_blocks)) && + ((atomic64_read(&flex_group[i].free_blocks) > + atomic64_read(&flex_group[best_flex].free_blocks)) && atomic_read(&flex_group[i].free_inodes))) best_flex = i; } if (!atomic_read(&flex_group[best_flex].free_inodes) || - !atomic_read(&flex_group[best_flex].free_blocks)) + !atomic64_read(&flex_group[best_flex].free_blocks)) return -1; found_flexbg: @@ -410,8 +411,8 @@ out: } struct orlov_stats { + __u64 free_blocks; __u32 free_inodes; - __u32 free_blocks; __u32 used_dirs; }; @@ -428,7 +429,7 @@ static void get_orlov_stats(struct super_block *sb, ext4_group_t g, if (flex_size > 1) { stats->free_inodes = atomic_read(&flex_group[g].free_inodes); - stats->free_blocks = atomic_read(&flex_group[g].free_blocks); + stats->free_blocks = atomic64_read(&flex_group[g].free_blocks); stats->used_dirs = atomic_read(&flex_group[g].used_dirs); return; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index aae7190..0a0c404 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5496,7 +5496,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode; - unsigned long delalloc_blocks; + unsigned long long delalloc_blocks; inode = dentry->d_inode; generic_fillattr(inode, stat); @@ -5513,7 +5513,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, */ delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; - stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; + stat->blocks += delalloc_blocks << (inode->i_sb->s_blocksize_bits-9); return 0; } diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 711673d..9841382 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2033,7 +2033,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 */ @@ -2821,8 +2825,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi, ac->ac_b_ex.fe_group); - atomic_sub(ac->ac_b_ex.fe_len, - &sbi->s_flex_groups[flex_group].free_blocks); + atomic64_sub(ac->ac_b_ex.fe_len, + &sbi->s_flex_groups[flex_group].free_blocks); } err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); @@ -4118,7 +4122,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); @@ -4142,12 +4146,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 ; @@ -4621,7 +4625,7 @@ do_more: if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi, block_group); - atomic_add(count, &sbi->s_flex_groups[flex_group].free_blocks); + atomic64_add(count, &sbi->s_flex_groups[flex_group].free_blocks); } ext4_mb_unload_buddy(&e4b); @@ -4752,8 +4756,8 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi, block_group); - atomic_add(blocks_freed, - &sbi->s_flex_groups[flex_group].free_blocks); + atomic64_add(blocks_freed, + &sbi->s_flex_groups[flex_group].free_blocks); } ext4_mb_unload_buddy(&e4b); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index c03f07b..8b227a9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -585,11 +585,8 @@ static int htree_dirblock_to_tree(struct file *dir_file, if (ext4_check_dir_entry(dir, NULL, de, bh, (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) + ((char *)de - bh->b_data))) { - /* On error, skip the f_pos to the next block. */ - dir_file->f_pos = (dir_file->f_pos | - (dir->i_sb->s_blocksize - 1)) + 1; - brelse(bh); - return count; + /* silently ignore the rest of the block */ + break; } ext4fs_dirhash(de->name, de->name_len, hinfo); if ((hinfo->hash < start_hash) || @@ -2070,7 +2067,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) int err = 0; /* ext4_handle_valid() assumes a valid handle_t pointer */ - if (handle && !ext4_handle_valid(handle)) + if (handle && !ext4_handle_valid(handle) && + !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) return 0; mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 80bbc9c..d2661aac 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -499,6 +499,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, return err; exit_inode: + kfree(n_group_desc); /* ext4_handle_release_buffer(handle, iloc.bh); */ brelse(iloc.bh); exit_dindj: @@ -928,8 +929,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) sbi->s_log_groups_per_flex) { ext4_group_t flex_group; flex_group = ext4_flex_group(sbi, input->group); - atomic_add(input->free_blocks_count, - &sbi->s_flex_groups[flex_group].free_blocks); + atomic64_add(input->free_blocks_count, + &sbi->s_flex_groups[flex_group].free_blocks); atomic_add(EXT4_INODES_PER_GROUP(sb), &sbi->s_flex_groups[flex_group].free_inodes); } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8adf54e..630196f 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1992,8 +1992,8 @@ static int ext4_fill_flex_info(struct super_block *sb) flex_group = ext4_flex_group(sbi, i); atomic_add(ext4_free_inodes_count(sb, gdp), &sbi->s_flex_groups[flex_group].free_inodes); - atomic_add(ext4_free_blks_count(sb, gdp), - &sbi->s_flex_groups[flex_group].free_blocks); + atomic64_add(ext4_free_blks_count(sb, gdp), + &sbi->s_flex_groups[flex_group].free_blocks); atomic_add(ext4_used_dirs_count(sb, gdp), &sbi->s_flex_groups[flex_group].used_dirs); } @@ -3681,22 +3681,19 @@ no_journal: if (err) { ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", err); - goto failed_mount4; + goto failed_mount5; } err = ext4_register_li_request(sb, first_not_zeroed); if (err) - goto failed_mount4; + goto failed_mount6; sbi->s_kobj.kset = ext4_kset; init_completion(&sbi->s_kobj_unregister); err = kobject_init_and_add(&sbi->s_kobj, &ext4_ktype, NULL, "%s", sb->s_id); - if (err) { - ext4_mb_release(sb); - ext4_ext_release(sb); - goto failed_mount4; - }; + if (err) + goto failed_mount7; EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; ext4_orphan_cleanup(sb, es); @@ -3738,13 +3735,19 @@ cantfind_ext4: goto failed_mount; +failed_mount7: + ext4_unregister_li_request(sb); +failed_mount6: + ext4_ext_release(sb); +failed_mount5: + ext4_mb_release(sb); + ext4_release_system_zone(sb); failed_mount4: iput(root); sb->s_root = NULL; ext4_msg(sb, KERN_ERR, "mount failed"); destroy_workqueue(EXT4_SB(sb)->dio_unwritten_wq); failed_mount_wq: - ext4_release_system_zone(sb); if (sbi->s_journal) { jbd2_journal_destroy(sbi->s_journal); sbi->s_journal = NULL; diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index c2865cc..8f797ae 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1271,6 +1271,8 @@ retry: s_min_extra_isize) { tried_min_extra_isize++; new_extra_isize = s_min_extra_isize; + kfree(is); is = NULL; + kfree(bs); bs = NULL; goto retry; } error = -1; |