===================================================================
--- linux-2.6.18.orig/fs/ext3/inode.c
+++ linux-2.6.18/fs/ext3/inode.c
-@@ -2703,6 +2703,13 @@ void ext3_read_inode(struct inode * inod
+@@ -2690,6 +2690,13 @@ void ext3_read_inode(struct inode * inod
EXT3_INODE_GET_XTIME(i_atime, inode, raw_inode);
EXT3_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
if (S_ISREG(inode->i_mode)) {
inode->i_op = &ext3_file_inode_operations;
inode->i_fop = &ext3_file_operations;
-@@ -2841,8 +2848,14 @@ static int ext3_do_update_inode(handle_t
+@@ -2828,8 +2835,14 @@ static int ext3_do_update_inode(handle_t
} else for (block = 0; block < EXT3_N_BLOCKS; block++)
raw_inode->i_block[block] = ei->i_data[block];
BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
rc = ext3_journal_dirty_metadata(handle, bh);
-@@ -3116,10 +3129,32 @@ ext3_reserve_inode_write(handle_t *handl
+@@ -3103,10 +3116,32 @@ ext3_reserve_inode_write(handle_t *handl
int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode)
{
struct ext3_iloc iloc;
===================================================================
--- linux-2.6.18.orig/include/linux/ext3_fs.h
+++ linux-2.6.18/include/linux/ext3_fs.h
-@@ -201,6 +201,7 @@ struct ext3_group_desc
+@@ -224,6 +224,7 @@ struct ext3_group_desc
#define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */
#define EXT3_STATE_NEW 0x00000002 /* inode is newly created */
#define EXT3_STATE_XATTR 0x00000004 /* has in-inode xattrs */
/* Used to pass group descriptor data when online resize is done */
struct ext3_new_group_input {
-@@ -277,7 +278,7 @@ struct ext3_inode {
+@@ -297,7 +298,7 @@ struct ext3_inode {
__le32 i_flags; /* File flags */
union {
struct {
} linux1;
struct {
__u32 h_i_translator;
-@@ -322,6 +323,7 @@ struct ext3_inode {
+@@ -342,6 +343,7 @@ struct ext3_inode {
__le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
__le32 i_crtime; /* File Creation time */
__le32 i_crtime_extra; /* extra File Creation time (nsec << 2 | epoch) */
};
#define i_size_high i_dir_acl
-@@ -384,6 +386,8 @@ do { \
+@@ -404,6 +406,8 @@ do { \
raw_inode->xtime ## _extra); \
} while (0)
/* data type for block offset of block group */
typedef int ext3_grpblk_t;
-@@ -147,6 +149,8 @@ struct ext3_inode_info {
- struct timespec i_crtime;
+@@ -162,6 +164,8 @@ struct ext3_inode_info {
+ spinlock_t i_prealloc_lock;
void *i_filterdata;
+
struct ext3_xattr_info {
int name_index;
const char *name;
-@@ -1008,6 +1022,8 @@ ext3_xattr_set_handle(handle_t *handle,
- if (!error) {
+@@ -945,13 +959,18 @@ ext3_xattr_set_handle(handle_t *handle,
+ struct ext3_xattr_block_find bs = {
+ .s = { .not_found = -ENODATA, },
+ };
++ unsigned long no_expand;
+ int error;
+
+ if (!name)
+ return -EINVAL;
+ if (strlen(name) > 255)
+ return -ERANGE;
++
+ down_write(&EXT3_I(inode)->xattr_sem);
++ no_expand = EXT3_I(inode)->i_state & EXT3_STATE_NO_EXPAND;
++ EXT3_I(inode)->i_state |= EXT3_STATE_NO_EXPAND;
++
+ error = ext3_get_inode_loc(inode, &is.iloc);
+ if (error)
+ goto cleanup;
+@@ -1009,6 +1028,8 @@ ext3_xattr_set_handle(handle_t *handle,
ext3_xattr_update_super_block(handle, inode->i_sb);
inode->i_ctime = ext3_current_time(inode);
+ error = ext3_mark_iloc_dirty(handle, inode, &is.iloc);
+ if (!value)
+ EXT3_I(inode)->i_state &= ~EXT3_STATE_NO_EXPAND;
- error = ext3_mark_iloc_dirty(handle, inode, &is.iloc);
/*
* The bh is consumed by ext3_mark_iloc_dirty, even with
-@@ -1060,6 +1076,249 @@ retry:
+ * error != 0.
+@@ -1021,6 +1042,8 @@ ext3_xattr_set_handle(handle_t *handle,
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
++ if (no_expand == 0)
++ EXT3_I(inode)->i_state &= ~EXT3_STATE_NO_EXPAND;
+ up_write(&EXT3_I(inode)->xattr_sem);
+ return error;
+ }
+@@ -1060,6 +1083,249 @@ retry:
return error;
}