X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=ldiskfs%2Fkernel_patches%2Fpatches%2Frhel7.2%2Fext4-large-eas.patch;h=3b05c6e713445a680d447a9cf84f932a9b3a7fca;hp=03bdf178eb0e95d008092783b3085f3262e46525;hb=d36f00b3b7c977acf1a092d188535d34d079c57a;hpb=b8f8a5b8f0fe889b61acafb48a756cb3872b8598 diff --git a/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch b/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch index 03bdf17..3b05c6e 100644 --- a/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch +++ b/ldiskfs/kernel_patches/patches/rhel7.2/ext4-large-eas.patch @@ -20,7 +20,7 @@ Index: linux-stage/fs/ext4/ext4.h #define EXT4_MMP_MAX_CHECK_INTERVAL 300UL /* -+ * Maximum size of xattr attributes for FEATURE_INCOMPAT_EA_INODE 1Mb ++ * 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) @@ -81,17 +81,12 @@ Index: linux-stage/fs/ext4/inode.c if (IS_ERR(handle)) { ext4_std_error(inode->i_sb, PTR_ERR(handle)); /* -@@ -249,9 +249,36 @@ void ext4_evict_inode(struct inode *inod - sb_end_intwrite(inode->i_sb); - goto no_delete; - } -- +@@ -252,6 +252,32 @@ void ext4_evict_inode(struct inode *inod + if (IS_SYNC(inode)) ext4_handle_sync(handle); + -+ /* -+ * Delete xattr inode before deleting the main inode. -+ */ ++ /* Delete xattr inode before deleting the main inode. */ + err = ext4_xattr_delete_inode(handle, inode, &lea_ino_array); + if (err) { + ext4_warning(inode->i_sb, @@ -119,11 +114,22 @@ Index: linux-stage/fs/ext4/inode.c inode->i_size = 0; err = ext4_mark_inode_dirty(handle, inode); if (err) { -@@ -306,8 +333,12 @@ void ext4_evict_inode(struct inode *inod - ext4_clear_inode(inode); - else +@@ -269,10 +296,10 @@ void ext4_evict_inode(struct inode *inod + * enough credits left in the handle to remove the inode from + * the orphan list and set the dtime field. + */ +- if (!ext4_handle_has_enough_credits(handle, 3)) { +- err = ext4_journal_extend(handle, 3); ++ if (!ext4_handle_has_enough_credits(handle, extra_credits)) { ++ err = ext4_journal_extend(handle, extra_credits); + if (err > 0) +- err = ext4_journal_restart(handle, 3); ++ err = ext4_journal_restart(handle, extra_credits); + if (err != 0) { + ext4_warning(inode->i_sb, + "couldn't extend journal (err %d)", err); +@@ -308,6 +335,9 @@ void ext4_evict_inode(struct inode *inod ext4_free_inode(handle, inode); -+ ext4_journal_stop(handle); sb_end_intwrite(inode->i_sb); + @@ -132,7 +138,7 @@ Index: linux-stage/fs/ext4/inode.c return; no_delete: ext4_clear_inode(inode); /* We must guarantee clearing of inode... */ -@@ -4681,7 +4712,7 @@ static int ext4_index_trans_blocks(struc +@@ -4681,7 +4711,7 @@ static int ext4_index_trans_blocks(struc * * Also account for superblock, inode, quota and xattr blocks */ @@ -183,7 +189,7 @@ Index: linux-stage/fs/ext4/xattr.c { struct ext4_xattr_entry *entry; size_t name_len; -@@ -265,11 +273,104 @@ ext4_xattr_find_entry(struct ext4_xattr_ +@@ -265,11 +273,109 @@ ext4_xattr_find_entry(struct ext4_xattr_ break; } *pentry = entry; @@ -196,8 +202,7 @@ Index: linux-stage/fs/ext4/xattr.c +/* + * Read the EA value from an inode. + */ -+static int -+ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t *size) ++static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t *size) +{ + unsigned long block = 0; + struct buffer_head *bh = NULL; @@ -230,7 +235,14 @@ Index: linux-stage/fs/ext4/xattr.c + return err; +} + -+struct inode *ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, int *err) ++/* ++ * Fetch the xattr inode from disk. ++ * ++ * The xattr inode stores the parent inode number and generation so that ++ * the kernel and e2fsck can verify the xattr inode is valid upon access. ++ */ ++struct inode *ext4_xattr_inode_iget(struct inode *parent, ++ unsigned long ea_ino, int *err) +{ + struct inode *ea_inode = NULL; + @@ -243,7 +255,7 @@ Index: linux-stage/fs/ext4/xattr.c + return NULL; + } + -+ if (ea_inode->i_xattr_inode_parent != parent->i_ino || ++ if (EXT4_XATTR_INODE_GET_PARENT(ea_inode) != parent->i_ino || + ea_inode->i_generation != parent->i_generation) { + ext4_error(parent->i_sb, "Backpointer from EA inode %lu " + "to parent invalid.", ea_ino); @@ -269,9 +281,8 @@ Index: linux-stage/fs/ext4/xattr.c +/* + * Read the value from the EA inode. + */ -+static int -+ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer, -+ size_t *size) ++static int ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, ++ void *buffer, size_t *size) +{ + struct inode *ea_inode = NULL; + int err; @@ -458,7 +469,7 @@ Index: linux-stage/fs/ext4/xattr.c + * A back-pointer from EA inode to parent inode will be useful + * for e2fsck. + */ -+ ea_inode->i_xattr_inode_parent = inode->i_ino; ++ EXT4_XATTR_INODE_SET_PARENT(ea_inode, inode->i_ino); + unlock_new_inode(ea_inode); + } + @@ -611,7 +622,7 @@ Index: linux-stage/fs/ext4/xattr.c bs->s.here = bs->s.first; error = ext4_xattr_find_entry(&bs->s.here, i->name_index, - i->name, bs->bh->b_size, 1); -+ i->name, bs->bh->b_size, 1, inode); ++ i->name, bs->bh->b_size, 1, inode); if (error && error != -ENODATA) goto cleanup; bs->s.not_found = error; @@ -989,11 +1000,22 @@ Index: linux-stage/fs/ext4/xattr.h __le32 e_value_size; /* size of attribute value */ __le32 e_hash; /* hash value of name and value */ char e_name[0]; /* attribute name */ -@@ -67,6 +67,15 @@ struct ext4_xattr_entry { +@@ -67,6 +67,26 @@ struct ext4_xattr_entry { EXT4_I(inode)->i_extra_isize)) #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1)) -+#define i_xattr_inode_parent i_mtime.tv_sec ++/* ++ * Link EA inode back to parent one using i_mtime field. ++ * Extra integer type conversion added to ignore higher ++ * bits in i_mtime.tv_sec which might be set by ext4_get() ++ */ ++#define EXT4_XATTR_INODE_SET_PARENT(inode, inum) \ ++do { \ ++ (inode)->i_mtime.tv_sec = inum; \ ++} while(0) ++ ++#define EXT4_XATTR_INODE_GET_PARENT(inode) \ ++ ((__u32)(inode)->i_mtime.tv_sec) + +/* + * The minimum size of EA value when you start storing it in an external inode