lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20131204045736.GF20409@gmail.com>
Date:	Wed, 4 Dec 2013 12:57:36 +0800
From:	Zheng Liu <gnehzuil.liu@...il.com>
To:	"Darrick J. Wong" <darrick.wong@...cle.com>
Cc:	linux-ext4@...r.kernel.org, Theodore Ts'o <tytso@....edu>,
	Zheng Liu <wenqing.lz@...bao.com>
Subject: Re: [PATCH v2 09/28] libext2fs: handle inline data in dir iterator
 function

On Tue, Dec 03, 2013 at 02:13:49PM -0800, Darrick J. Wong wrote:
> On Tue, Dec 03, 2013 at 08:11:36PM +0800, Zheng Liu wrote:
> > From: Zheng Liu <wenqing.lz@...bao.com>
> > 
> > Inline_data is handled in dir iterator because a lot of commands use
> > this function to traverse directory entries in debugfs.  We need to
> > handle inline_data individually because inline_data is saved in two
> > places.  One is in i_block, and another is in ibody extended attribute.
> > 
> > After applied this commit, the following commands in debugfs can
> > support the inline_data feature:
> > 	- cd
> > 	- chroot
> > 	- link*
> > 	- ls
> > 	- ncheck
> > 	- pwd
> > 	- unlink
> > 
> > * TODO: Inline_data doesn't expand to ibody extended attribute because
> >   link command doesn't handle DIR_NO_SPACE error until now.  But if we
> >   have already expanded inline data to ibody ea area, link command can
> >   occupy this space.
> 
> A patch for this TODO is coming, right?

TBH, I don't have a patch for this because I don't know why ext2fs_link
doesn't handle DIR_NO_SPACE error.  So I will try to fix it later.

> 
> > Signed-off-by: Theodore Ts'o <tytso@....edu>
> > Signed-off-by: Zheng Liu <wenqing.lz@...bao.com>
> > ---
> >  lib/ext2fs/Makefile.in    |    8 +++
> >  lib/ext2fs/Makefile.pq    |    1 +
> >  lib/ext2fs/dir_iterate.c  |   62 +++++++++++-----
> >  lib/ext2fs/ext2_err.et.in |    3 +
> >  lib/ext2fs/ext2_fs.h      |   10 +++
> >  lib/ext2fs/ext2fs.h       |    1 +
> >  lib/ext2fs/ext2fsP.h      |   11 +++
> >  lib/ext2fs/inline_data.c  |  175 +++++++++++++++++++++++++++++++++++++++++++++
> >  lib/ext2fs/swapfs.c       |   12 +++-
> >  9 files changed, 265 insertions(+), 18 deletions(-)
> >  create mode 100644 lib/ext2fs/inline_data.c
> > 
> > diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
> > index e1e6216..4d011c9 100644
> > --- a/lib/ext2fs/Makefile.in
> > +++ b/lib/ext2fs/Makefile.in
> > @@ -59,6 +59,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
> >  	ind_block.o \
> >  	initialize.o \
> >  	inline.o \
> > +	inline_data.o \
> >  	inode.o \
> >  	io_manager.o \
> >  	ismounted.o \
> > @@ -133,6 +134,7 @@ SRCS= ext2_err.c \
> >  	$(srcdir)/ind_block.c \
> >  	$(srcdir)/initialize.c \
> >  	$(srcdir)/inline.c \
> > +	$(srcdir)/inline_data.c	\
> >  	$(srcdir)/inode.c \
> >  	$(srcdir)/inode_io.c \
> >  	$(srcdir)/imager.c \
> > @@ -758,6 +760,12 @@ inline.o: $(srcdir)/inline.c $(top_builddir)/lib/config.h \
> >   $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
> >   $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
> >   $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
> > +inline_data.o: $(srcdir)/inline_data.c $(top_builddir)/lib/config.h \
> > + $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
> > + $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
> > + $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
> > + $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
> > + $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
> >  inode.o: $(srcdir)/inode.c $(top_builddir)/lib/config.h \
> >   $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
> >   $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
> > diff --git a/lib/ext2fs/Makefile.pq b/lib/ext2fs/Makefile.pq
> > index 2f7b654..89082a7 100644
> > --- a/lib/ext2fs/Makefile.pq
> > +++ b/lib/ext2fs/Makefile.pq
> > @@ -27,6 +27,7 @@ OBJS= 	alloc.obj \
> >  	icount.obj \
> >  	initialize.obj \
> >  	inline.obj \
> > +	inline_data.obj \
> >  	inode.obj \
> >  	ismounted.obj \
> >  	link.obj \
> > diff --git a/lib/ext2fs/dir_iterate.c b/lib/ext2fs/dir_iterate.c
> > index 8be0ac2..1624371 100644
> > --- a/lib/ext2fs/dir_iterate.c
> > +++ b/lib/ext2fs/dir_iterate.c
> > @@ -127,6 +127,12 @@ errcode_t ext2fs_dir_iterate2(ext2_filsys fs,
> >  				       ext2fs_process_dir_block, &ctx);
> >  	if (!block_buf)
> >  		ext2fs_free_mem(&ctx.buf);
> > +	if (retval == EXT2_ET_INLINE_DATA_CANT_ITERATE) {
> > +		ctx.flags |= DIRENT_FLAG_INCLUDE_INLINE_DATA;
> > +		retval = ext2fs_inline_data_dir_iterate(fs, dir,
> > +						ext2fs_process_dir_block,
> > +						&ctx);
> > +	}
> >  	if (retval)
> >  		return retval;
> >  	return ctx.errcode;
> > @@ -189,30 +195,40 @@ int ext2fs_process_dir_block(ext2_filsys fs,
> >  	int		ret = 0;
> >  	int		changed = 0;
> >  	int		do_abort = 0;
> > -	unsigned int	rec_len, size;
> > +	unsigned int	rec_len, size, buflen;
> >  	int		entry;
> >  	struct ext2_dir_entry *dirent;
> >  	int		csum_size = 0;
> > +	int		inline_data;
> > +	errcode_t	retval = 0;
> >  
> >  	if (blockcnt < 0)
> >  		return 0;
> >  
> >  	entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
> >  
> > -	ctx->errcode = ext2fs_read_dir_block4(fs, *blocknr, ctx->buf, 0,
> > -					      ctx->dir);
> > -	if (ctx->errcode)
> > -		return BLOCK_ABORT;
> > +	/* If a dir has inline data, we don't need to read block */
> > +	inline_data = !!(ctx->flags & DIRENT_FLAG_INCLUDE_INLINE_DATA);
> > +	if (!inline_data) {
> > +		ctx->errcode = ext2fs_read_dir_block4(fs, *blocknr, ctx->buf, 0,
> > +						      ctx->dir);
> > +		if (ctx->errcode)
> > +			return BLOCK_ABORT;
> > +		/* If we handle a normal dir, we traverse the entire block */
> > +		buflen = fs->blocksize;
> > +	} else {
> > +		buflen = ctx->buflen;
> 
> Since we don't swap i_block[] when we're reading in the inode, who calls
> ext2fs_dirent_swab_in()?

Good catch!  I will call this on ext2fs_inline_data_dir_iterate().

> 
> > +	}
> >  
> >  	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
> >  					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
> >  		csum_size = sizeof(struct ext2_dir_entry_tail);
> >  
> > -	while (offset < fs->blocksize) {
> > +	while (offset < buflen) {
> >  		dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
> >  		if (ext2fs_get_rec_len(fs, dirent, &rec_len))
> >  			return BLOCK_ABORT;
> > -		if (((offset + rec_len) > fs->blocksize) ||
> > +		if (((offset + rec_len) > buflen) ||
> >  		    (rec_len < 8) ||
> >  		    ((rec_len % 4) != 0) ||
> >  		    ((ext2fs_dirent_name_len(dirent)+8) > rec_len)) {
> > @@ -220,7 +236,13 @@ int ext2fs_process_dir_block(ext2_filsys fs,
> >  			return BLOCK_ABORT;
> >  		}
> >  		if (!dirent->inode) {
> > -			if ((offset == fs->blocksize - csum_size) &&
> > +			/*
> > +			 * We just need to check metadata_csum when this
> > +			 * dir hasn't inline data.  That means that 'buflen'
> > +			 * should be blocksize.
> > +			 */
> > +			if (!inline_data &&
> > +			    (offset == buflen - csum_size) &&
> >  			    (dirent->rec_len == csum_size) &&
> >  			    (dirent->name_len == EXT2_DIR_NAME_LEN_CSUM)) {
> >  				if (!(ctx->flags & DIRENT_FLAG_INCLUDE_CSUM))
> > @@ -234,7 +256,7 @@ int ext2fs_process_dir_block(ext2_filsys fs,
> >  				  (next_real_entry > offset) ?
> >  				  DIRENT_DELETED_FILE : entry,
> >  				  dirent, offset,
> > -				  fs->blocksize, ctx->buf,
> > +				  buflen, ctx->buf,
> >  				  ctx->priv_data);
> >  		if (entry < DIRENT_OTHER_FILE)
> >  			entry++;
> > @@ -272,13 +294,21 @@ next:
> >  	}
> >  
> >  	if (changed) {
> > -		ctx->errcode = ext2fs_write_dir_block4(fs, *blocknr, ctx->buf,
> > -						       0, ctx->dir);
> > -		if (ctx->errcode)
> > -			return BLOCK_ABORT;
> > +		if (!inline_data) {
> > +			ctx->errcode = ext2fs_write_dir_block4(fs, *blocknr,
> > +							       ctx->buf,
> > +							       0, ctx->dir);
> > +			if (ctx->errcode)
> > +				return BLOCK_ABORT;
> > +		} else {
> > +			/*
> > +			 * return BLOCK_CHANGED to notify caller that inline
> > +			 * data has been changed
> > +			 */
> 
> I don't think I like overloading the meaning of BLOCK_CHANGED here.  For a
> non-inlinedata file, the iterator function returning BLOCK_CHANGED means that
> the lblk->pblk mapping changed, whereas for an inline data file, it means that
> the block *contents* have changed.
> 
> At best, the two meanings ought to be documented wherever BLOCK_CHANGED is
> defined, though I think I'd prefer a new flag BLOCK_INLINE_DATA_CHANGED to
> handle this situation, because otherwise the meaning of the flag is
> context-dependent and therefore more difficult to reason about.
> 
> Separate flags also gives us the ability to check for programming errors, such
> as someone returning BLOCK_CHANGED on inlinedata files or returning
> BLOCK_INLINE_DATA_CHANGED on !inlinedata files.

Fair enough.

> 
> > +			retval = BLOCK_CHANGED;
> 
> Who calls ext2fs_dirent_swab_out()?

Ditto.

> 
> > +		}
> >  	}
> >  	if (do_abort)
> > -		return BLOCK_ABORT;
> > -	return 0;
> > +		return retval | BLOCK_ABORT;
> > +	return retval;
> >  }
> > -
> > diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
> > index b819a90..0781145 100644
> > --- a/lib/ext2fs/ext2_err.et.in
> > +++ b/lib/ext2fs/ext2_err.et.in
> > @@ -500,4 +500,7 @@ ec	EXT2_ET_EA_KEY_NOT_FOUND,
> >  ec	EXT2_ET_EA_NO_SPACE,
> >  	"Insufficient space to store extended attribute data"
> >  
> > +ec	EXT2_ET_NO_INLINE_DATA,
> > +	"Inode doesn't have inline data"
> > +
> >  	end
> > diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
> > index 6a28d55..5ab16ae 100644
> > --- a/lib/ext2fs/ext2_fs.h
> > +++ b/lib/ext2fs/ext2_fs.h
> > @@ -914,4 +914,14 @@ struct mmp_struct {
> >   */
> >  #define EXT4_MMP_MIN_CHECK_INTERVAL     5
> >  
> > +/*
> > + * Minimum size of inline data.
> > + */
> > +#define EXT4_MIN_INLINE_DATA_SIZE	((sizeof(__u32) * EXT2_N_BLOCKS))
> > +
> > +/*
> > + * Size of a parent inode in inline data directory.
> > + */
> > +#define EXT4_INLINE_DATA_DOTDOT_SIZE	(4)
> > +
> >  #endif	/* _LINUX_EXT2_FS_H */
> > diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
> > index e251435..c5b73fd 100644
> > --- a/lib/ext2fs/ext2fs.h
> > +++ b/lib/ext2fs/ext2fs.h
> > @@ -438,6 +438,7 @@ struct ext2_extent_info {
> >  #define DIRENT_FLAG_INCLUDE_EMPTY	1
> >  #define DIRENT_FLAG_INCLUDE_REMOVED	2
> >  #define DIRENT_FLAG_INCLUDE_CSUM	4
> > +#define DIRENT_FLAG_INCLUDE_INLINE_DATA 8
> >  
> >  #define DIRENT_DOT_FILE		1
> >  #define DIRENT_DOT_DOT_FILE	2
> > diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h
> > index 80d2d0a..5ab6084 100644
> > --- a/lib/ext2fs/ext2fsP.h
> > +++ b/lib/ext2fs/ext2fsP.h
> > @@ -50,6 +50,7 @@ struct dir_context {
> >  	ext2_ino_t		dir;
> >  	int		flags;
> >  	char		*buf;
> > +	unsigned int	buflen;
> >  	int (*func)(ext2_ino_t	dir,
> >  		    int	entry,
> >  		    struct ext2_dir_entry *dirent,
> > @@ -87,6 +88,16 @@ extern int ext2fs_process_dir_block(ext2_filsys  	fs,
> >  				    int			ref_offset,
> >  				    void		*priv_data);
> >  
> > +extern errcode_t ext2fs_inline_data_dir_iterate(ext2_filsys fs,
> > +				      ext2_ino_t ino,
> > +				      int (*func)(ext2_filsys fs,
> > +						  blk64_t     *blocknr,
> > +						  e2_blkcnt_t blockcnt,
> > +						  blk64_t     ref_blk,
> > +						  int	      ref_offset,
> > +						  void	      *priv_data),
> > +				      void *priv_data);
> > +
> >  /* Generic numeric progress meter */
> >  
> >  struct ext2fs_numeric_progress_struct {
> > diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
> > new file mode 100644
> > index 0000000..cc2954d
> > --- /dev/null
> > +++ b/lib/ext2fs/inline_data.c
> > @@ -0,0 +1,175 @@
> > +/*
> > + * inline_data.c --- data in inode
> > + *
> > + * Copyright (C) 2012 Zheng Liu <wenqing.lz@...bao.com>
> > + *
> > + * %Begin-Header%
> > + * This file may be redistributed under the terms of the GNU library
> > + * General Public License, version 2.
> > + * %End-Header%
> > + */
> > +
> > +#include "config.h"
> > +#include <stdio.h>
> > +#include <time.h>
> > +
> > +#include "ext2_fs.h"
> > +#include "ext2_ext_attr.h"
> > +
> > +#include "ext2fs.h"
> > +#include "ext2fsP.h"
> > +
> > +struct ext2_inline_data {
> > +	ext2_filsys fs;
> > +	ext2_ino_t ino;
> > +	size_t ea_size;	/* the size of inline data in ea area */
> > +	char *ea_data;
> 
> Should this be a void* since the file data type is opaque to the library?

I will fix it.

> 
> > +};
> > +
> > +static errcode_t ext2fs_inline_data_ea_set(struct ext2_inline_data *data)
> > +{
> > +	struct ext2_xattr_handle *handle;
> > +	errcode_t retval;
> > +
> > +	retval = ext2fs_xattrs_open(data->fs, data->ino, &handle);
> > +	if (retval)
> > +		return retval;
> > +
> > +	retval = ext2fs_xattrs_read(handle);
> > +	if (retval)
> > +		goto err;
> > +
> > +	retval = ext2fs_xattr_set(handle, "system.data",
> > +				  data->ea_data, data->ea_size);
> > +	if (retval)
> > +		goto err;
> > +
> > +	retval = ext2fs_xattrs_write(handle);
> > +
> > +err:
> > +	(void) ext2fs_xattrs_close(&handle);
> > +	return retval;
> > +}
> > +
> > +errcode_t ext2fs_inline_data_ea_get(struct ext2_inline_data *data)
> > +{
> > +	struct ext2_xattr_handle *handle;
> > +	errcode_t retval;
> > +
> > +	data->ea_size = 0;
> > +	data->ea_data = 0;
> > +
> > +	retval = ext2fs_xattrs_open(data->fs, data->ino, &handle);
> > +	if (retval)
> > +		return retval;
> > +
> > +	retval = ext2fs_xattrs_read(handle);
> > +	if (retval)
> > +		goto err;
> > +
> > +	retval = ext2fs_xattr_get(handle, "system.data",
> > +				  (void **)&data->ea_data, &data->ea_size);
> > +	if (retval)
> > +		goto err;
> > +
> > +err:
> > +	(void) ext2fs_xattrs_close(&handle);
> > +	return retval;
> > +}
> > +
> > +
> > +errcode_t ext2fs_inline_data_dir_iterate(ext2_filsys fs,
> > +			       ext2_ino_t ino,
> > +			       int (*func)(ext2_filsys fs,
> > +					   blk64_t     *blocknr,
> > +					   e2_blkcnt_t blockcnt,
> > +					   blk64_t     ref_blk,
> > +					   int         ref_offset,
> > +					   void        *priv_data),
> > +			       void *priv_data)
> > +{
> > +	struct dir_context *ctx;
> > +	struct ext2_inode inode;
> > +	struct ext2_dir_entry dirent;
> > +	struct ext2_inline_data data;
> > +	errcode_t retval = 0;
> > +	e2_blkcnt_t blockcnt = 0;
> > +
> > +	ctx = (struct dir_context *)priv_data;
> > +
> > +	retval = ext2fs_read_inode(fs, ino, &inode);
> > +	if (retval)
> > +		goto out;
> > +
> > +	if (!(inode.i_flags & EXT4_INLINE_DATA_FL))
> > +		return EXT2_ET_NO_INLINE_DATA;
> > +
> > +	if (!LINUX_S_ISDIR(inode.i_mode)) {
> > +		retval = EXT2_ET_NO_DIRECTORY;
> > +		goto out;
> > +	}
> > +
> > +	/* we first check '.' and '..' dir */
> > +	dirent.inode = ino;
> > +	dirent.name_len = 1;
> > +	ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(2), &dirent);
> > +	dirent.name[0] = '.';
> > +	dirent.name[1] = '\0';
> > +	ctx->buf = (char *)&dirent;
> > +	ext2fs_get_rec_len(fs, &dirent, &ctx->buflen);
> > +	retval |= (*func)(fs, 0, blockcnt++, 0, 0, priv_data);
> > +	if (retval & BLOCK_ABORT)
> > +		goto out;
> > +
> > +	dirent.inode = ext2fs_le32_to_cpu(inode.i_block[0]);
> > +	dirent.name_len = 2;
> > +	ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(3), &dirent);
> > +	dirent.name[0] = '.';
> > +	dirent.name[1] = '.';
> > +	dirent.name[2] = '\0';
> > +	ctx->buf = (char *)&dirent;
> > +	ext2fs_get_rec_len(fs, &dirent, &ctx->buflen);
> > +	retval |= (*func)(fs, 0, blockcnt++, 0, 0, priv_data);
> > +	if (retval & BLOCK_CHANGED) {
> > +		errcode_t err;
> > +
> > +		inode.i_block[0] = ext2fs_cpu_to_le32(dirent.inode);
> > +		err = ext2fs_write_inode(fs, ino, &inode);
> > +		if (err)
> > +			goto out;
> > +	}
> > +	if (retval & BLOCK_ABORT)
> > +		goto out;
> > +
> > +	ctx->buf = (char *)inode.i_block + EXT4_INLINE_DATA_DOTDOT_SIZE;
> > +	ctx->buflen = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DATA_DOTDOT_SIZE;
> > +	retval |= (*func)(fs, 0, blockcnt++, 0, 0, priv_data);
> > +	if (retval & BLOCK_CHANGED) {
> > +		errcode_t err;
> > +
> > +		err = ext2fs_write_inode(fs, ino, &inode);
> > +		if (err)
> > +			goto out;
> > +	}
> > +	if (retval & BLOCK_ABORT)
> > +		goto out;
> > +
> > +	data.fs = fs;
> > +	data.ino = ino;
> > +	retval = ext2fs_inline_data_ea_get(&data);
> > +	if (retval)
> > +		goto out;
> > +	if (data.ea_size > 0) {
> > +		ctx->buf = data.ea_data;
> > +		ctx->buflen = data.ea_size;
> > +		retval |= (*func)(fs, 0, blockcnt++, 0, 0, priv_data);
> > +		if (retval & BLOCK_CHANGED)
> > +			ext2fs_inline_data_ea_set(&data);
> > +		ext2fs_free_mem(&data.ea_data);
> > +		ctx->buf = 0;
> > +	}
> > +
> > +out:
> > +	retval |= BLOCK_ERROR;
> > +	return retval & BLOCK_ERROR ? ctx->errcode : 0;
> > +}
> > diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
> > index 1295e81..cfbe5dd 100644
> > --- a/lib/ext2fs/swapfs.c
> > +++ b/lib/ext2fs/swapfs.c
> > @@ -207,6 +207,7 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
> >  {
> >  	unsigned i, has_data_blocks, extra_isize, attr_magic;
> >  	int has_extents = 0;
> > +	int has_inline_data = 0;
> >  	int islnk = 0;
> >  	__u32 *eaf, *eat;
> >  
> > @@ -233,12 +234,19 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
> >  					   (struct ext2_inode *) t);
> >  	if (hostorder && (f->i_flags & EXT4_EXTENTS_FL))
> >  		has_extents = 1;
> > +	if (hostorder && (f->i_flags & EXT4_INLINE_DATA_FL))
> > +		has_inline_data = 1;
> >  	t->i_flags = ext2fs_swab32(f->i_flags);
> >  	if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL))
> >  		has_extents = 1;
> > +	if (!hostorder && (f->i_flags & EXT4_INLINE_DATA_FL))
> > +		has_inline_data = 1;
> >  	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
> > -	/* extent data are swapped on access, not here */
> > -	if (!has_extents && (!islnk || has_data_blocks)) {
> > +	/*
> > +	 * Extent data are swapped on access, not here
> > +	 * Inline data are not swapped beside parent ino is accessed
> 
> From the other patches it looks like the parent ino is swapped on access too.
> 
> I'm confused about what this comment is trying to say, though the code here
> says that inline data is swapped on access (if at all).

OK.  I will clarify this.

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

Powered by blists - more mailing lists