Re: [PATCH 1/1] [RFC] 64-bit inode version

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

 



Hi Mingming,

Thanks for pointing out the problem and making the required changes. I
have tested the changes and it works properly for all cases. The only
downside being that if a filesystem was using EAs and now is compiled
without XATTR support, inode expansion will not work on some inodes. But
the "-E expand_extra_isize" option patch for e2fsck should solve this
problem.

Acked-by: Kalpak Shah <kalpak@xxxxxxxxxxxxx>

Thanks,
Kalpak.

P.S.: Maybe the "allow more than 32000 subdirectories" should also be
included in the 2.6.21-ext4 patchset (or 2.6.22-ext4 rather).

On Tue, 2007-05-15 at 18:15 -0700, Mingming Cao wrote:
> On Wed, 2007-04-11 at 18:47 +0530, Kalpak Shah wrote: 
> > Hi,
> > 
> > This patch is on top of the nanosecond timestamp and i_version_hi
> > patches. 
> > 
> > This patch adds 64-bit inode version support to ext4. The lower 32 bits
> > are stored in the osd1.linux1.l_i_version field while the high 32 bits
> > are stored in the i_version_hi field newly created in the ext4_inode.
> > 
> > We need to make sure that existing filesystems can also avail the new
> > fields that have been added to the inode.
> 
> Hi Kalpak,
> 
> Failed to build ext4 as module. It is because CONFIG_EXT4DEV_FS_XATTR is
> not configed but ext4_expand_extra_isize() assumes it's on.
> 
> > @@ -3173,10 +3186,32 @@ ext4_reserve_inode_write(handle_t *handl
> >  int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
> >  {
> >  	struct ext4_iloc iloc;
> > -	int err;
> > +	int err, ret;
> > +	static int expand_message;
> > 
> >  	might_sleep();
> >  	err = ext4_reserve_inode_write(handle, inode, &iloc);
> > +	if (EXT4_I(inode)->i_extra_isize <
> > +	    EXT4_SB(inode->i_sb)->s_want_extra_isize &&
> > +	    !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) {
> > +		/* We need extra buffer credits since we may write into EA block
> > +		 * with this same handle */
> > +		if ((jbd2_journal_extend(handle,
> > +			     EXT4_DATA_TRANS_BLOCKS(inode->i_sb))) == 0) {
> > +			ret = ext4_expand_extra_isize(inode,
> > +  					EXT4_SB(inode->i_sb)->s_want_extra_isize,
> > +					iloc, handle);
> 
> Here is the place where ext4_expand_extra_isize can be called without
> xattrs turned on.
> 
> > Index: linux-2.6.20/fs/ext4/xattr.c
> > ===================================================================
> > --- linux-2.6.20.orig/fs/ext4/xattr.c
> > +++ linux-2.6.20/fs/ext4/xattr.c
> > @@ -502,6 +502,20 @@ ext4_xattr_release_block(handle_t *handl
> >  	}
> >  }
> > 
> > +static inline size_t ext3_xattr_free_space(struct ext4_xattr_entry *last,
> > +				    size_t *min_offs, void *base, int *total)
> 
> should renamed to ext4_xattr_free_space()
> 
> > +static void ext3_xattr_shift_entries(struct ext4_xattr_entry *entry,
> > +				     int value_offs_shift, void *to,
> > +				     void *from, size_t n, int blocksize)
> 
> Should rename to ext4_xxx_xxx().
> 
> > +/* Expand an inode by new_extra_isize bytes.
> > + * Returns 0 on success or negative error number on failure.
> > + */
> > +int ext4_expand_extra_isize(struct inode *inode, int new_extra_isize,
> > +			    struct ext4_iloc iloc, handle_t *handle)
> > +{
> 
> ....
> 
> > Index: linux-2.6.20/fs/ext4/xattr.h
> > ===================================================================
> > --- linux-2.6.20.orig/fs/ext4/xattr.h
> > +++ linux-2.6.20/fs/ext4/xattr.h
> > @@ -74,6 +74,9 @@ extern int ext4_xattr_set_handle(handle_
> >  extern void ext4_xattr_delete_inode(handle_t *, struct inode *);
> >  extern void ext4_xattr_put_super(struct super_block *);
> > 
> > +int ext4_expand_extra_isize(struct inode *inode, int new_extra_isize,
> > +			    struct ext4_iloc iloc, handle_t *handle);
> > +
> >  extern int init_ext4_xattr(void);
> >  extern void exit_ext4_xattr(void);
> > 
> > 
> 
> The following patch moved the ext4_expand_extra_isize() function to
> inode.c and provide proper defines in xattr.h. Renamed the ext3
> functions to ext4_xxx_xxx().
> 
> Compile tested. Can you Ack the changes. Appreciate if you can let me
> know it passes your tests.
> 
> Signed-Off-By: Mingming Cao <cmm@xxxxxxxxxx>



> Index: linux-2.6.22-rc1/fs/ext4/inode.c
> ===================================================================
> --- linux-2.6.22-rc1.orig/fs/ext4/inode.c	2007-05-15 17:44:25.000000000 -0700
> +++ linux-2.6.22-rc1/fs/ext4/inode.c	2007-05-15 17:46:23.000000000 -0700
> @@ -3097,6 +3097,40 @@
>  }
>  
>  /*
> + * Expand an inode by new_extra_isize bytes.
> + * Returns 0 on success or negative error number on failure.
> + */
> +int ext4_expand_extra_isize(struct inode *inode, unsigned int new_extra_isize,
> +                        struct ext4_iloc iloc, handle_t *handle)
> +{
> +	struct ext4_inode *raw_inode;
> +	struct ext4_xattr_ibody_header *header;
> +	struct ext4_xattr_entry *entry;
> +
> +	if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
> +		return 0;
> +	}
> +
> +	raw_inode = ext4_raw_inode(&iloc);
> +
> +	header = IHDR(inode, raw_inode);
> +        entry = IFIRST(header);
> +
> +	/* No extended attributes present */
> +	if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR) ||
> +		header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
> +		memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0,
> +			new_extra_isize);
> +		EXT4_I(inode)->i_extra_isize = new_extra_isize;
> +		return 0;
> +	}
> +
> +	/* try to expand with EA present */
> +	return ext4_expand_extra_isize_ea(inode, new_extra_isize,
> +						raw_inode, handle);
> +}
> +
> +/*
>   * What we do here is to mark the in-core inode as clean with respect to inode
>   * dirtiness (it may still be data-dirty).
>   * This means that the in-core inode may be reaped by prune_icache
> Index: linux-2.6.22-rc1/fs/ext4/xattr.c
> ===================================================================
> --- linux-2.6.22-rc1.orig/fs/ext4/xattr.c	2007-05-15 17:44:25.000000000 -0700
> +++ linux-2.6.22-rc1/fs/ext4/xattr.c	2007-05-15 17:46:23.000000000 -0700
> @@ -66,13 +66,6 @@
>  #define BFIRST(bh) ENTRY(BHDR(bh)+1)
>  #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
>  
> -#define IHDR(inode, raw_inode) \
> -	((struct ext4_xattr_ibody_header *) \
> -		((void *)raw_inode + \
> -		 EXT4_GOOD_OLD_INODE_SIZE + \
> -		 EXT4_I(inode)->i_extra_isize))
> -#define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
> -
>  #ifdef EXT4_XATTR_DEBUG
>  # define ea_idebug(inode, f...) do { \
>  		printk(KERN_DEBUG "inode %s:%lu: ", \
> @@ -508,7 +501,7 @@
>  	return;
>  }
>  
> -static inline size_t ext3_xattr_free_space(struct ext4_xattr_entry *last,
> +static inline size_t ext4_xattr_free_space(struct ext4_xattr_entry *last,
>  				    size_t *min_offs, void *base, int *total)
>  {
>  	for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
> @@ -1083,7 +1076,7 @@
>  	return error;
>  }
>  
> -static void ext3_xattr_shift_entries(struct ext4_xattr_entry *entry,
> +static void ext4_xattr_shift_entries(struct ext4_xattr_entry *entry,
>  				     int value_offs_shift, void *to,
>  				     void *from, size_t n, int blocksize)
>  {
> @@ -1103,13 +1096,14 @@
>  	memmove(to, from, n);
>  }
>  
> -/* Expand an inode by new_extra_isize bytes.
> +/*
> + * Expand an inode by new_extra_isize bytes when EA presents.
>   * Returns 0 on success or negative error number on failure.
> + *
>   */
>  int ext4_expand_extra_isize(struct inode *inode, int new_extra_isize,
> -			    struct ext4_iloc iloc, handle_t *handle)
> +			    struct ext4_inode *raw_inode, handle_t *handle)
>  {
> -	struct ext4_inode *raw_inode;
>  	struct ext4_xattr_ibody_header *header;
>  	struct ext4_xattr_entry *entry, *last, *first;
>  	struct buffer_head *bh = NULL;
> @@ -1123,27 +1117,15 @@
>  	int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize;
>  
>  	down_write(&EXT4_I(inode)->xattr_sem);
> -
>  retry:
>  	if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
>  		up_write(&EXT4_I(inode)->xattr_sem);
>  		return 0;
>  	}
>  
> -	raw_inode = ext4_raw_inode(&iloc);
> -
>  	header = IHDR(inode, raw_inode);
>  	entry = IFIRST(header);
>  
> -	/* No extended attributes present */
> -	if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR) ||
> -	    header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
> -		memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0,
> -		       new_extra_isize);
> -		EXT4_I(inode)->i_extra_isize = new_extra_isize;
> -		goto cleanup;
> -	}
> -
>  	/*
>  	 * Check if enough free space is available in the inode to shift the
>  	 * entries ahead by new_extra_isize.
> @@ -1155,10 +1137,10 @@
>  	last = entry;
>  	total_ino = sizeof(struct ext4_xattr_ibody_header);
>  
> -	free = ext3_xattr_free_space(last, &min_offs, base, &total_ino);
> +	free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
>  	if (free >= new_extra_isize) {
>  		entry = IFIRST(header);
> -		ext3_xattr_shift_entries(entry,	EXT4_I(inode)->i_extra_isize
> +		ext4_xattr_shift_entries(entry,	EXT4_I(inode)->i_extra_isize
>  				- new_extra_isize, (void *)raw_inode +
>  				EXT4_GOOD_OLD_INODE_SIZE + new_extra_isize,
>  				(void *)header, total_ino,
> @@ -1188,7 +1170,7 @@
>  		first = BFIRST(bh);
>  		end = bh->b_data + bh->b_size;
>  		min_offs = end - base;
> -		free = ext3_xattr_free_space(first, &min_offs, base,
> +		free = ext4_xattr_free_space(first, &min_offs, base,
>  					     &total_blk);
>  		if (free < new_extra_isize) {
>  			if (!tried_min_extra_isize && s_min_extra_isize) {
> @@ -1287,7 +1269,7 @@
>  		else
>  			shift_bytes = entry_size + size;
>  		/* Adjust the offsets and shift the remaining entries ahead */
> -		ext3_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize -
> +		ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize -
>  			shift_bytes, (void *)raw_inode +
>  			EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes,
>  			(void *)header, total_ino - entry_size,
> Index: linux-2.6.22-rc1/fs/ext4/xattr.h
> ===================================================================
> --- linux-2.6.22-rc1.orig/fs/ext4/xattr.h	2007-05-15 17:44:25.000000000 -0700
> +++ linux-2.6.22-rc1/fs/ext4/xattr.h	2007-05-15 17:48:26.000000000 -0700
> @@ -56,6 +56,13 @@
>  #define EXT4_XATTR_SIZE(size) \
>  	(((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
>  
> +#define IHDR(inode, raw_inode) \
> +	((struct ext4_xattr_ibody_header *) \
> +		((void *)raw_inode + \
> +		EXT4_GOOD_OLD_INODE_SIZE + \
> +		EXT4_I(inode)->i_extra_isize))
> +#define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
> +
>  # ifdef CONFIG_EXT4DEV_FS_XATTR
>  
>  extern struct xattr_handler ext4_xattr_user_handler;
> @@ -74,8 +81,8 @@
>  extern void ext4_xattr_delete_inode(handle_t *, struct inode *);
>  extern void ext4_xattr_put_super(struct super_block *);
>  
> -int ext4_expand_extra_isize(struct inode *inode, int new_extra_isize,
> -			    struct ext4_iloc iloc, handle_t *handle);
> +extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
> +			    struct ext4_inode *raw_inode, handle_t *handle);
>  
>  extern int init_ext4_xattr(void);
>  extern void exit_ext4_xattr(void);
> @@ -132,6 +139,13 @@
>  {
>  }
>  
> +static int
> +ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
> +			    struct ext4_inode *raw_inode, handle_t *handle)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
>  #define ext4_xattr_handlers	NULL
>  
>  # endif  /* CONFIG_EXT4DEV_FS_XATTR */
> 
> 

-
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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