Re: [PATCH] ext4: fix performance issue of xattr when expanding inode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi JunChao,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tytso-ext4/dev]
[also build test WARNING on linus/master v6.3-rc4 next-20230331]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/JunChao-Sun/ext4-fix-performance-issue-of-xattr-when-expanding-inode/20230401-223339
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
patch link:    https://lore.kernel.org/r/20230401143244.70332-1-sunjunchao2870%40gmail.com
patch subject: [PATCH] ext4: fix performance issue of xattr when expanding inode
config: sparc-randconfig-s033-20230402 (https://download.01.org/0day-ci/archive/20230402/202304020546.k5RbPsBr-lkp@xxxxxxxxx/config)
compiler: sparc-linux-gcc (GCC) 12.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-39-gce1a6720-dirty
        # https://github.com/intel-lab-lkp/linux/commit/715c6d399c95e6914f37b3dfc08bb88a9d6b2120
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review JunChao-Sun/ext4-fix-performance-issue-of-xattr-when-expanding-inode/20230401-223339
        git checkout 715c6d399c95e6914f37b3dfc08bb88a9d6b2120
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sparc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sparc SHELL=/bin/bash fs/ext4/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Link: https://lore.kernel.org/oe-kbuild-all/202304020546.k5RbPsBr-lkp@xxxxxxxxx/

sparse warnings: (new ones prefixed by >>)
>> fs/ext4/xattr.c:2707:49: sparse: sparse: restricted __le16 degrades to integer
>> fs/ext4/xattr.c:2709:35: sparse: sparse: incorrect type in initializer (different base types) @@     expected unsigned int [usertype] offs @@     got restricted __le16 [usertype] e_value_offs @@
   fs/ext4/xattr.c:2709:35: sparse:     expected unsigned int [usertype] offs
   fs/ext4/xattr.c:2709:35: sparse:     got restricted __le16 [usertype] e_value_offs

vim +2707 fs/ext4/xattr.c

  2601	
  2602	/*
  2603	 * Move xattr pointed to by 'entry' from inode into external xattr block
  2604	 */
  2605	static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
  2606					    struct ext4_inode *raw_inode,
  2607					    struct ext4_xattr_entry *entry)
  2608	{
  2609		struct ext4_xattr_ibody_find *is = NULL;
  2610		struct ext4_xattr_block_find *bs = NULL;
  2611		char *buffer = NULL, *b_entry_name = NULL;
  2612		size_t value_size = le32_to_cpu(entry->e_value_size);
  2613		struct ext4_xattr_info i = {
  2614			.value = NULL,
  2615			.value_len = 0,
  2616			.name_index = entry->e_name_index,
  2617			.in_inode = !!entry->e_value_inum,
  2618		};
  2619		struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
  2620		struct ext4_xattr_entry *here = NULL, *last = NULL, *next = NULL;
  2621		struct inode *old_ea_inode = NULL;
  2622		size_t name_size = EXT4_XATTR_LEN(entry->e_name_len);
  2623		size_t min_offs;
  2624		int error;
  2625	
  2626		is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
  2627		bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
  2628		b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
  2629		if (!is || !bs || !b_entry_name) {
  2630			error = -ENOMEM;
  2631			goto out;
  2632		}
  2633	
  2634		is->s.not_found = -ENODATA;
  2635		bs->s.not_found = -ENODATA;
  2636		is->iloc.bh = NULL;
  2637		bs->bh = NULL;
  2638	
  2639		/* Save the entry name and the entry value */
  2640		if (entry->e_value_inum) {
  2641			buffer = kvmalloc(value_size, GFP_NOFS);
  2642			if (!buffer) {
  2643				error = -ENOMEM;
  2644				goto out;
  2645			}
  2646	
  2647			error = ext4_xattr_inode_get(inode, entry, buffer, value_size);
  2648			if (error)
  2649				goto out;
  2650		} else {
  2651			size_t value_offs = le16_to_cpu(entry->e_value_offs);
  2652			buffer = (void *)IFIRST(header) + value_offs;
  2653		}
  2654	
  2655		memcpy(b_entry_name, entry->e_name, entry->e_name_len);
  2656		b_entry_name[entry->e_name_len] = '\0';
  2657		i.name = b_entry_name;
  2658	
  2659		error = ext4_get_inode_loc(inode, &is->iloc);
  2660		if (error)
  2661			goto out;
  2662	
  2663		error = ext4_xattr_ibody_find(inode, &i, is);
  2664		if (error)
  2665			goto out;
  2666	
  2667		i.value = buffer;
  2668		i.value_len = value_size;
  2669		here = is->s.here;
  2670		last = is->s.first;
  2671		min_offs = is->s.end - is->s.base;
  2672		/* Compute min_offs and last entry */
  2673		for (; !IS_LAST_ENTRY(last); last = next) {
  2674			next = EXT4_XATTR_NEXT(last);
  2675			if ((void *)next >= is->s.end) {
  2676				EXT4_ERROR_INODE(inode, "corrupted xattr entries");
  2677				error = -EFSCORRUPTED;
  2678				goto out;
  2679			}
  2680			if (!last->e_value_inum && last->e_value_size) {
  2681				size_t offs = le16_to_cpu(last->e_value_offs);
  2682	
  2683				if (offs < min_offs)
  2684					min_offs = offs;
  2685			}
  2686		}
  2687	
  2688		/* Remove the name in ibody */
  2689		last = ENTRY((void *)last - name_size);
  2690		memmove(here, (void *)here + name_size,
  2691			(void *)last - (void *)here + sizeof(__u32));
  2692		memset(last, 0, name_size);
  2693	
  2694		/* Get the ea_inode which store the old value */
  2695		if (here->e_value_inum) {
  2696			error = ext4_xattr_inode_iget(inode,
  2697						    le32_to_cpu(here->e_value_inum),
  2698						    le32_to_cpu(here->e_hash),
  2699						    &old_ea_inode);
  2700			if (error) {
  2701				old_ea_inode = NULL;
  2702				goto out;
  2703			}
  2704		} else if (here->e_value_size) {
  2705			/* Remove the old value in ibody */
  2706			void *first_val = is->s.base + min_offs;
> 2707			void *rm_val = is->s.base + here->e_value_offs;
  2708			size_t rm_size = EXT4_XATTR_SIZE(le32_to_cpu(here->e_value_size));
> 2709			size_t offs = here->e_value_offs;
  2710	
  2711			memmove(first_val + rm_size, first_val, rm_val - first_val);
  2712			memset(first_val, 0, rm_size);
  2713			min_offs += rm_size;
  2714	
  2715			/* Adjust all value offsets */
  2716			last = is->s.first;
  2717			while (!IS_LAST_ENTRY(last)) {
  2718				size_t o = le16_to_cpu(last->e_value_offs);
  2719	
  2720				if (!last->e_value_inum &&
  2721				    last->e_value_size && o < offs)
  2722					last->e_value_offs = cpu_to_le16(o + rm_size);
  2723				last = EXT4_XATTR_NEXT(last);
  2724			}
  2725		}
  2726	
  2727		error = ext4_xattr_block_find(inode, &i, bs);
  2728		if (error)
  2729			goto out;
  2730	
  2731		/*
  2732		 * Move ea entry from the inode into the block, and do not need to
  2733		 * recreate an ea_inode that store the same value.
  2734		 */
  2735		error = ext4_xattr_block_set(handle, inode, &i, bs, old_ea_inode);
  2736		if (error)
  2737			goto out;
  2738	
  2739	out:
  2740		kfree(b_entry_name);
  2741		if (entry->e_value_inum && buffer)
  2742			kvfree(buffer);
  2743		if (is)
  2744			brelse(is->iloc.bh);
  2745		if (bs)
  2746			brelse(bs->bh);
  2747		kfree(is);
  2748		kfree(bs);
  2749		iput(old_ea_inode);
  2750	
  2751		return error;
  2752	}
  2753	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests



[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux