ext4: xattr-in-inode support
Large xattr support is implemented for EXT4_FEATURE_INCOMPAT_EA_INODE. If the size of an xattr value is larger than will fit in a single external block, then the xattr value will be saved into the body of an external xattr inode. The also helps support a larger number of xattr, since only the headers will be stored in the in-inode space or the single external block. The inode is referenced from the xattr header via "e_value_inum", which was formerly "e_value_block", but that field was never used. The e_value_size still contains the xattr size so that listing xattrs does not need to look up the inode if the data is not accessed. struct ext4_xattr_entry { __u8 e_name_len; /* length of name */ __u8 e_name_index; /* attribute name index */ __le16 e_value_offs; /* offset in disk block of value */ __le32 e_value_inum; /* inode in which value is stored */ __le32 e_value_size; /* size of attribute value */ __le32 e_hash; /* hash value of name and value */ char e_name[0]; /* attribute name */ }; The xattr inode is marked with the EXT4_EA_INODE_FL flag and also holds a back-reference to the owning inode in its i_mtime field, allowing the ext4/e2fsck to verify the correct inode is accessed. [ Applied fix by Dan Carpenter to avoid freeing an ERR_PTR. ] Lustre-Jira: https://jira.hpdd.intel.com/browse/LU-80 Lustre-bugzilla: https://bugzilla.lustre.org/show_bug.cgi?id=4424 Signed-off-by: Kalpak Shah <kalpak.shah@sun.com> Signed-off-by: James Simmons <uja.ornl@gmail.com> Signed-off-by: Andreas Dilger <andreas.dilger@intel.com> Signed-off-by: Tahsin Erdogan <tahsin@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
This commit is contained in:

committed by
Theodore Ts'o

parent
e08ac99fa2
commit
e50e5129f3
@@ -1797,6 +1797,7 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, ENCRYPT)
|
||||
EXT4_FEATURE_INCOMPAT_EXTENTS| \
|
||||
EXT4_FEATURE_INCOMPAT_64BIT| \
|
||||
EXT4_FEATURE_INCOMPAT_FLEX_BG| \
|
||||
EXT4_FEATURE_INCOMPAT_EA_INODE| \
|
||||
EXT4_FEATURE_INCOMPAT_MMP | \
|
||||
EXT4_FEATURE_INCOMPAT_INLINE_DATA | \
|
||||
EXT4_FEATURE_INCOMPAT_ENCRYPT | \
|
||||
@@ -2230,6 +2231,12 @@ struct mmpd_data {
|
||||
*/
|
||||
#define EXT4_MMP_MAX_CHECK_INTERVAL 300UL
|
||||
|
||||
/*
|
||||
* Maximum size of xattr attributes for FEATURE_INCOMPAT_EA_INODE 1Mb
|
||||
* This limit is arbitrary, but is reasonable for the xattr API.
|
||||
*/
|
||||
#define EXT4_XATTR_MAX_LARGE_EA_SIZE (1024 * 1024)
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
@@ -2242,6 +2249,10 @@ struct mmpd_data {
|
||||
# define ATTRIB_NORET __attribute__((noreturn))
|
||||
# define NORET_AND noreturn,
|
||||
|
||||
struct ext4_xattr_ino_array {
|
||||
unsigned int xia_count; /* # of used item in the array */
|
||||
unsigned int xia_inodes[0];
|
||||
};
|
||||
/* bitmap.c */
|
||||
extern unsigned int ext4_count_free(char *bitmap, unsigned numchars);
|
||||
void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
|
||||
@@ -2489,6 +2500,7 @@ extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks);
|
||||
extern void ext4_set_inode_flags(struct inode *);
|
||||
extern int ext4_alloc_da_blocks(struct inode *inode);
|
||||
extern void ext4_set_aops(struct inode *inode);
|
||||
extern int ext4_meta_trans_blocks(struct inode *, int nrblocks, int chunk);
|
||||
extern int ext4_writepage_trans_blocks(struct inode *);
|
||||
extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
|
||||
extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode,
|
||||
|
Reference in New Issue
Block a user