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 Index: linux-2.6.22-rc1/fs/ext4/inode.c =================================================================== --- linux-2.6.22-rc1.orig/fs/ext4/inode.c 2007-05-18 16:33:09.000000000 -0700 +++ linux-2.6.22-rc1/fs/ext4/inode.c 2007-05-18 16:33:12.000000000 -0700 @@ -3117,6 +3117,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-18 16:33:09.000000000 -0700 +++ linux-2.6.22-rc1/fs/ext4/xattr.c 2007-05-18 16:33:12.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) +int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, + 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-18 16:33:09.000000000 -0700 +++ linux-2.6.22-rc1/fs/ext4/xattr.h 2007-05-18 16:33:12.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 inline 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 */