libext2fs: update iblock when using ea_inode feature
PATCH 3/4 libext2fs: update iblock when using ea_inode feature
When a xattr is stored in an ea_inode, ext2fs_xattrs_* functions do not update the inode block count.
This patch uses a cached inode to update the block count and quota when writing xattrs.
It also fix an xattr remove case: the current ACL block was not release by ext2fs_xattrs_write().
Add a helper function ext2fs_iblk_get() to get the inode block count in cluster count unit.
Add ext2fs_xattrs_open_inode() to specify an optional cached inode to use or update.
The function handle an optional quota context argument to update quota accounting. It is hard to predict inode quota usage with ea_inode deduplication.
For testing purposes, modify the debugfs "ea_set" command to handle input file larger than the FS block size.
Add a regression test: d_xattr_ea_inode
Lustre-bug-id: https://jira.whamcloud.com/browse/LU-20049
--- debugfs/xattrs.c | 19 ++- e2fsck/pass1.c | 12 +- lib/ext2fs/ext2fs.h | 7 ++ lib/ext2fs/ext_attr.c | 227 ++++++++++++++++++++++------------ lib/ext2fs/i_block.c | 14 +++ lib/support/quotaio.h | 1 - tests/d_xattr_ea_inode/expect | 137 ++++++++++++++++++++ tests/d_xattr_ea_inode/name | 1 + tests/d_xattr_ea_inode/script | 85 +++++++++++++ 9 files changed, 415 insertions(+), 88 deletions(-) create mode 100644 tests/d_xattr_ea_inode/expect create mode 100644 tests/d_xattr_ea_inode/name create mode 100644 tests/d_xattr_ea_inode/script
debugfs/xattrs.c +17 -2
@@ -14,6 +14,7 @@ extern int optind;extern char *optarg;#endif #include <ctype.h> +#include <unistd.h> #include "support/cstring.h" #include "debugfs.h"
@@ -299,10 +300,24 @@ void do_set_xattr(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)), goto out;if (fp) { - err =ext2fs_get_mem (current_fs->blocksize, &buf); +struct stat st; + +if (fstat (fileno (fp), &st)) { + err = errno; + goto out; + } +if (st.st_size >sysconf (_SC_ARG_MAX)) { + err =EFBIG ; + goto out; + } + err =ext2fs_get_mem (st.st_size, &buf);if (err) goto out; - buflen =fread (buf,1 , current_fs->blocksize, fp); + buflen =fread (buf,1 , st.st_size, fp); +if (ferror (fp)) { + err = errno; + goto out; + } }else { buf = argv[optind +2 ]; buflen =parse_c_string (buf);
e2fsck/pass1.c +7 -5
@@ -968,18 +968,18 @@ static void reserve_block_for_lnf_repair(e2fsck_t ctx)static errcode_t get_inline_data_ea_size (ext2_filsys fs,ext2_ino_t ino,struct ext2_inode *inode, -size_t *sz) +size_t inode_size,size_t *sz) {void *p;struct ext2_xattr_handle *handle;errcode_t retval; - retval =ext2fs_xattrs_open (fs, ino, &handle); + retval =ext2fs_xattrs_open_inode (fs, ino, inode, inode_size,NULL , + &handle);if (retval)return retval; - retval =ext2fs_xattrs_read_inode (handle, - (struct ext2_inode_large *)inode); + retval =ext2fs_xattrs_read (handle);if (retval) goto err;
@@ -1580,6 +1580,7 @@ void e2fsck_pass1(e2fsck_t ctx)size_t size =0 ; pctx.errcode =get_inline_data_ea_size (fs, ino, inode, + inode_size, &size);if (!pctx.errcode &&fix_problem (ctx,PR_1_INLINE_DATA_FEATURE , &pctx)) {
@@ -1603,7 +1604,8 @@ void e2fsck_pass1(e2fsck_t ctx) flags = fs->flags;if (failed_csum) fs->flags |=EXT2_FLAG_IGNORE_CSUM_ERRORS ; - err =get_inline_data_ea_size (fs, ino, inode, &size); + err =get_inline_data_ea_size (fs, ino, inode, + inode_size, &size); fs->flags = (flags &EXT2_FLAG_IGNORE_CSUM_ERRORS ) | (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS );
lib/ext2fs/ext2fs.h +7 -0
@@ -94,6 +94,8 @@ typedef __s64 __bitwise ext2_off64_t;typedef __s64 __bitwise e2_blkcnt_t ;typedef __u32 __bitwise ext2_dirhash_t ; +typedef struct quota_ctx *quota_ctx_t ; +#if EXT2_FLAT_INCLUDES #include "com_err.h" #include "ext2_io.h"
@@ -1408,6 +1410,10 @@ errcode_t ext2fs_xattr_set(struct ext2_xattr_handle *handle,errcode_t ext2fs_xattr_remove (struct ext2_xattr_handle *handle,const char *key);errcode_t ext2fs_xattr_remove_all (struct ext2_xattr_handle *handle); +errcode_t ext2fs_xattrs_open_inode (ext2_filsys fs,ext2_ino_t ino, +struct ext2_inode *inode,size_t inode_size, +quota_ctx_t qctx, +struct ext2_xattr_handle **handle);errcode_t ext2fs_xattrs_open (ext2_filsys fs,ext2_ino_t ino,struct ext2_xattr_handle **handle);errcode_t ext2fs_xattrs_close (struct ext2_xattr_handle **handle);
@@ -1607,6 +1613,7 @@ errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,errcode_t ext2fs_iblk_sub_blocks (ext2_filsys fs,struct ext2_inode *inode,blk64_t num_blocks);errcode_t ext2fs_iblk_set (ext2_filsys fs,struct ext2_inode *inode,blk64_t b); +blk64_t ext2fs_iblk_get (ext2_filsys fs,struct ext2_inode *inode);/* imager.c */ extern errcode_t ext2fs_image_inode_write (ext2_filsys fs,int fd,int flags);
lib/ext2fs/ext_attr.c +147 -80
491 lines not on this page · raw message
lib/ext2fs/i_block.c +14 -0
@@ -88,3 +88,17 @@ errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b)return EOVERFLOW ;return 0 ; } + +blk64_t ext2fs_iblk_get (ext2_filsys fs,struct ext2_inode *inode) +{ +blk64_t blk = inode->i_blocks; + +if (ext2fs_has_feature_huge_file (fs->super)) + blk += ((blk64_t ) inode->osd2.linux2.l_i_blocks_hi) <<32 ; + +if (!ext2fs_has_feature_huge_file (fs->super) || + !(inode->i_flags &EXT4_HUGE_FILE_FL )) + blk /= fs->blocksize /512 ; + +return EXT2FS_B2C (fs, blk); +}
lib/support/quotaio.h +0 -1
@@ -58,7 +58,6 @@ enum quota_type {#define QUOTA_PRJ_BIT (1 << PRJQUOTA)#define QUOTA_ALL_BIT (QUOTA_USR_BIT | QUOTA_GRP_BIT | QUOTA_PRJ_BIT) -typedef struct quota_ctx *quota_ctx_t ;struct dict_t ;struct quota_ctx {
tests/d_xattr_ea_inode/expect new file +137 -0
137 lines not on this page · raw message
tests/d_xattr_ea_inode/name new file +1 -0
@@ -0,0 +1 @@ +edit extended attributes in debugfs with ea_inode feature
tests/d_xattr_ea_inode/script new file +85 -0
85 lines not on this page · raw message
Signature · 1 line
2.43.7