From 20b325203cc9d7da5067242321d9e1bdfcee8ccc Mon Sep 17 00:00:00 2001 From: braam Date: Wed, 17 Sep 2003 19:14:16 +0000 Subject: [PATCH] - merge b_devel into b_llog --- .../patches/ext3-ea-in-inode-2.4.20.patch | 766 +++++++++++++++++++++ .../kernel_patches/pc/ext3-ea-in-inode-2.4.20.pc | 6 + lustre/lvfs/Makefile.am | 2 +- lustre/lvfs/fsfilt_ext3.c | 2 - lustre/lvfs/fsfilt_extN.c | 2 - lustre/obdclass/llog_cat.c | 3 +- lustre/obdclass/llog_lvfs.c | 2 +- 7 files changed, 775 insertions(+), 8 deletions(-) create mode 100644 lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch create mode 100644 lustre/kernel_patches/pc/ext3-ea-in-inode-2.4.20.pc diff --git a/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch new file mode 100644 index 0000000..f150020 --- /dev/null +++ b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch @@ -0,0 +1,766 @@ + fs/ext3/ialloc.c | 6 + fs/ext3/inode.c | 12 + fs/ext3/super.c | 6 + fs/ext3/xattr.c | 600 +++++++++++++++++++++++++++++++++++++++++++++- + include/linux/ext3_fs.h | 2 + include/linux/ext3_fs_i.h | 3 + 6 files changed, 616 insertions(+), 13 deletions(-) + +--- linux-2.4.20-vanilla/fs/ext3/ialloc.c~ext3-ea-in-inode-2.4.20 2003-09-17 21:06:28.000000000 +0400 ++++ linux-2.4.20-vanilla-alexey/fs/ext3/ialloc.c 2003-09-17 21:16:16.000000000 +0400 +@@ -577,6 +577,12 @@ repeat: + insert_inode_hash(inode); + inode->i_generation = sb->u.ext3_sb.s_next_generation++; + ++ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) { ++ inode->u.ext3_i.i_extra_isize = sizeof(__u16) /* i_extra_isize */ ++ + sizeof(__u16); /* i_pad1 */ ++ } else ++ inode->u.ext3_i.i_extra_isize = 0; ++ + inode->u.ext3_i.i_state = EXT3_STATE_NEW; + err = ext3_get_inode_loc_new(inode, &iloc, 1); + if (err) goto fail; +--- linux-2.4.20-vanilla/fs/ext3/inode.c~ext3-ea-in-inode-2.4.20 2003-09-17 21:06:28.000000000 +0400 ++++ linux-2.4.20-vanilla-alexey/fs/ext3/inode.c 2003-09-17 21:16:16.000000000 +0400 +@@ -2209,6 +2209,12 @@ void ext3_read_inode(struct inode * inod + inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block]; + INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); + ++ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ++ inode->u.ext3_i.i_extra_isize = ++ le16_to_cpu(raw_inode->i_extra_isize); ++ else ++ inode->u.ext3_i.i_extra_isize = 0; ++ + brelse (iloc.bh); + + if (S_ISREG(inode->i_mode)) { +@@ -2274,6 +2280,8 @@ static int ext3_do_update_inode(handle_t + if (err) + goto out_brelse; + } ++ if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) ++ memset(raw_inode, 0, EXT3_INODE_SIZE(inode->i_sb)); + raw_inode->i_mode = cpu_to_le16(inode->i_mode); + if(!(test_opt(inode->i_sb, NO_UID32))) { + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); +@@ -2357,6 +2365,10 @@ static int ext3_do_update_inode(handle_t + else for (block = 0; block < EXT3_N_BLOCKS; block++) + raw_inode->i_block[block] = inode->u.ext3_i.i_data[block]; + ++ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ++ raw_inode->i_extra_isize = ++ cpu_to_le16(EXT3_I(inode)->i_extra_isize); ++ + BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); + rc = ext3_journal_dirty_metadata(handle, bh); + if (!err) +--- linux-2.4.20-vanilla/fs/ext3/xattr.c~ext3-ea-in-inode-2.4.20 2003-09-17 21:06:27.000000000 +0400 ++++ linux-2.4.20-vanilla-alexey/fs/ext3/xattr.c 2003-09-17 21:17:55.000000000 +0400 +@@ -100,6 +100,9 @@ + static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, + struct ext3_xattr_header *); + ++int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *, ++ const void *, size_t, int); ++ + #ifdef CONFIG_EXT3_FS_XATTR_SHARING + + static int ext3_xattr_cache_insert(struct buffer_head *); +@@ -348,17 +351,12 @@ ext3_removexattr(struct dentry *dentry, + } + + /* +- * ext3_xattr_get() +- * +- * Copy an extended attribute into the buffer +- * provided, or compute the buffer size required. +- * Buffer is NULL to compute the size of the buffer required. ++ * ext3_xattr_block_get() + * +- * Returns a negative error number on failure, or the number of bytes +- * used / required on success. ++ * routine looks for attribute in EA block and returns it's value and size + */ + int +-ext3_xattr_get(struct inode *inode, int name_index, const char *name, ++ext3_xattr_block_get(struct inode *inode, int name_index, const char *name, + void *buffer, size_t buffer_size) + { + struct buffer_head *bh = NULL; +@@ -447,6 +445,94 @@ cleanup: + } + + /* ++ * ext3_xattr_ibode_get() ++ * ++ * routine looks for attribute in inode body and returns it's value and size ++ */ ++int ++ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name, ++ void *buffer, size_t buffer_size) ++{ ++ int size, name_len = strlen(name), storage_size; ++ struct ext3_xattr_entry *last; ++ struct ext3_inode *raw_inode; ++ struct ext3_iloc iloc; ++ char *start, *end; ++ int ret = -ENOENT; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return -ENOENT; ++ ++ ret = ext3_get_inode_loc(inode, &iloc); ++ if (ret) ++ return ret; ++ raw_inode = iloc.raw_inode; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { ++ brelse(iloc.bh); ++ return -ENOENT; ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_get", ++ "inode %ld", inode->i_ino); ++ brelse(iloc.bh); ++ return -EIO; ++ } ++ if (name_index == last->e_name_index && ++ name_len == last->e_name_len && ++ !memcmp(name, last->e_name, name_len)) ++ goto found; ++ last = next; ++ } ++ ++ /* can't find EA */ ++ brelse(iloc.bh); ++ return -ENOENT; ++ ++found: ++ size = le32_to_cpu(last->e_value_size); ++ if (buffer) { ++ ret = -ERANGE; ++ if (buffer_size >= size) { ++ memcpy(buffer, start + le16_to_cpu(last->e_value_offs), ++ size); ++ ret = size; ++ } ++ } else ++ ret = size; ++ brelse(iloc.bh); ++ return ret; ++} ++ ++int ext3_xattr_get(struct inode *inode, int name_index, const char *name, ++ void *buffer, size_t buffer_size) ++{ ++ int err; ++ ++ /* try to find attribute in inode body */ ++ err = ext3_xattr_ibody_get(inode, name_index, name, ++ buffer, buffer_size); ++ if (err < 0) ++ /* search was unsuccessful, try to find EA in dedicated block */ ++ err = ext3_xattr_block_get(inode, name_index, name, ++ buffer, buffer_size); ++ return err; ++} ++ ++/* + * ext3_xattr_list() + * + * Copy a list of attribute names into the buffer +@@ -457,7 +543,7 @@ cleanup: + * used / required on success. + */ + int +-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) ++ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size) + { + struct buffer_head *bh = NULL; + struct ext3_xattr_entry *entry; +@@ -530,6 +616,131 @@ cleanup: + return error; + } + ++/* ext3_xattr_ibody_list() ++ * ++ * generate list of attributes stored in inode body ++ */ ++int ++ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size) ++{ ++ struct ext3_xattr_entry *last; ++ struct ext3_inode *raw_inode; ++ char *start, *end, *buf; ++ struct ext3_iloc iloc; ++ int storage_size; ++ int ret; ++ int size = 0; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return 0; ++ ++ ret = ext3_get_inode_loc(inode, &iloc); ++ if (ret) ++ return ret; ++ raw_inode = iloc.raw_inode; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { ++ brelse(iloc.bh); ++ return 0; ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ struct ext3_xattr_handler *handler; ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_list", ++ "inode %ld", inode->i_ino); ++ brelse(iloc.bh); ++ return -EIO; ++ } ++ handler = ext3_xattr_handler(last->e_name_index); ++ if (handler) ++ size += handler->list(NULL, inode, last->e_name, ++ last->e_name_len); ++ last = next; ++ } ++ ++ if (!buffer) { ++ ret = size; ++ goto cleanup; ++ } else { ++ ret = -ERANGE; ++ if (size > buffer_size) ++ goto cleanup; ++ } ++ ++ last = (struct ext3_xattr_entry *) start; ++ buf = buffer; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ struct ext3_xattr_handler *handler; ++ handler = ext3_xattr_handler(last->e_name_index); ++ if (handler) ++ buf += handler->list(buf, inode, last->e_name, ++ last->e_name_len); ++ last = next; ++ } ++ ret = size; ++cleanup: ++ brelse(iloc.bh); ++ return ret; ++} ++ ++/* ++ * ext3_xattr_list() ++ * ++ * Copy a list of attribute names into the buffer ++ * provided, or compute the buffer size required. ++ * Buffer is NULL to compute the size of the buffer required. ++ * ++ * Returns a negative error number on failure, or the number of bytes ++ * used / required on success. ++ */ ++int ++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) ++{ ++ int error; ++ int size = buffer_size; ++ ++ /* get list of attributes stored in inode body */ ++ error = ext3_xattr_ibody_list(inode, buffer, buffer_size); ++ if (error < 0) { ++ /* some error occured while collecting ++ * attributes in inode body */ ++ size = 0; ++ goto cleanup; ++ } ++ size = error; ++ ++ /* get list of attributes stored in dedicated block */ ++ if (buffer) { ++ buffer_size -= error; ++ if (buffer_size <= 0) { ++ buffer = NULL; ++ buffer_size = 0; ++ } else ++ buffer += error; ++ } ++ ++ error = ext3_xattr_block_list(inode, buffer, buffer_size); ++ if (error < 0) ++ /* listing was successful, so we return len */ ++ size = 0; ++ ++cleanup: ++ return error + size; ++} ++ + /* + * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is + * not set, set it. +@@ -553,6 +764,279 @@ static void ext3_xattr_update_super_bloc + } + + /* ++ * ext3_xattr_ibody_find() ++ * ++ * search attribute and calculate free space in inode body ++ * NOTE: free space includes space our attribute hold ++ */ ++int ++ext3_xattr_ibody_find(struct inode *inode, int name_index, ++ const char *name, struct ext3_xattr_entry *rentry, int *free) ++{ ++ struct ext3_xattr_entry *last; ++ struct ext3_inode *raw_inode; ++ int name_len = strlen(name); ++ int err, storage_size; ++ struct ext3_iloc iloc; ++ char *start, *end; ++ int ret = -ENOENT; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return ret; ++ ++ err = ext3_get_inode_loc(inode, &iloc); ++ if (err) ++ return -EIO; ++ raw_inode = iloc.raw_inode; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ *free = storage_size - sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { ++ brelse(iloc.bh); ++ return -ENOENT; ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_find", ++ "inode %ld", inode->i_ino); ++ brelse(iloc.bh); ++ return -EIO; ++ } ++ ++ if (name_index == last->e_name_index && ++ name_len == last->e_name_len && ++ !memcmp(name, last->e_name, name_len)) { ++ memcpy(rentry, last, sizeof(struct ext3_xattr_entry)); ++ ret = 0; ++ } else { ++ *free -= EXT3_XATTR_LEN(last->e_name_len); ++ *free -= le32_to_cpu(last->e_value_size); ++ } ++ last = next; ++ } ++ ++ brelse(iloc.bh); ++ return ret; ++} ++ ++/* ++ * ext3_xattr_block_find() ++ * ++ * search attribute and calculate free space in EA block (if it allocated) ++ * NOTE: free space includes space our attribute hold ++ */ ++int ++ext3_xattr_block_find(struct inode *inode, int name_index, const char *name, ++ struct ext3_xattr_entry *rentry, int *free) ++{ ++ struct buffer_head *bh = NULL; ++ struct ext3_xattr_entry *entry; ++ char *end; ++ int name_len, error = -ENOENT; ++ ++ if (!EXT3_I(inode)->i_file_acl) { ++ *free = inode->i_sb->s_blocksize - ++ sizeof(struct ext3_xattr_header) - ++ sizeof(__u32); ++ return -ENOENT; ++ } ++ ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl); ++ bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl); ++ if (!bh) ++ return -EIO; ++ ea_bdebug(bh, "b_count=%d, refcount=%d", ++ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); ++ end = bh->b_data + bh->b_size; ++ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || ++ HDR(bh)->h_blocks != cpu_to_le32(1)) { ++bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", ++ "inode %ld: bad block %d", inode->i_ino, ++ EXT3_I(inode)->i_file_acl); ++ brelse(bh); ++ return -EIO; ++ } ++ /* find named attribute */ ++ name_len = strlen(name); ++ *free = bh->b_size - sizeof(__u32); ++ ++ entry = FIRST_ENTRY(bh); ++ while (!IS_LAST_ENTRY(entry)) { ++ struct ext3_xattr_entry *next = ++ EXT3_XATTR_NEXT(entry); ++ if ((char *)next >= end) ++ goto bad_block; ++ if (name_index == entry->e_name_index && ++ name_len == entry->e_name_len && ++ memcmp(name, entry->e_name, name_len) == 0) { ++ memcpy(rentry, entry, sizeof(struct ext3_xattr_entry)); ++ error = 0; ++ } else { ++ *free -= EXT3_XATTR_LEN(entry->e_name_len); ++ *free -= le32_to_cpu(entry->e_value_size); ++ } ++ entry = next; ++ } ++ brelse(bh); ++ ++ return error; ++} ++ ++/* ++ * ext3_xattr_inode_set() ++ * ++ * this routine add/remove/replace attribute in inode body ++ */ ++int ++ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index, ++ const char *name, const void *value, size_t value_len, ++ int flags) ++{ ++ struct ext3_xattr_entry *last, *next, *here = NULL; ++ struct ext3_inode *raw_inode; ++ int name_len = strlen(name); ++ int esize = EXT3_XATTR_LEN(name_len); ++ struct buffer_head *bh; ++ int err, storage_size; ++ struct ext3_iloc iloc; ++ int free, min_offs; ++ char *start, *end; ++ ++ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) ++ return -ENOSPC; ++ ++ err = ext3_get_inode_loc(inode, &iloc); ++ if (err) ++ return err; ++ raw_inode = iloc.raw_inode; ++ bh = iloc.bh; ++ ++ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - ++ EXT3_GOOD_OLD_INODE_SIZE - ++ EXT3_I(inode)->i_extra_isize - ++ sizeof(__u32); ++ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + ++ EXT3_I(inode)->i_extra_isize; ++ if ((*(__u32*) start) != EXT3_XATTR_MAGIC) { ++ /* inode had no attributes before */ ++ *((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC); ++ } ++ start += sizeof(__u32); ++ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; ++ min_offs = storage_size; ++ free = storage_size - sizeof(__u32); ++ ++ last = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(last)) { ++ next = EXT3_XATTR_NEXT(last); ++ if (le32_to_cpu(last->e_value_size) > storage_size || ++ (char *) next >= end) { ++ ext3_error(inode->i_sb, "ext3_xattr_ibody_set", ++ "inode %ld", inode->i_ino); ++ brelse(bh); ++ return -EIO; ++ } ++ ++ if (last->e_value_size) { ++ int offs = le16_to_cpu(last->e_value_offs); ++ if (offs < min_offs) ++ min_offs = offs; ++ } ++ if (name_index == last->e_name_index && ++ name_len == last->e_name_len && ++ !memcmp(name, last->e_name, name_len)) ++ here = last; ++ else { ++ /* we calculate all but our attribute ++ * because it will be removed before changing */ ++ free -= EXT3_XATTR_LEN(last->e_name_len); ++ free -= le32_to_cpu(last->e_value_size); ++ } ++ last = next; ++ } ++ ++ if (value && (esize + value_len > free)) { ++ brelse(bh); ++ return -ENOSPC; ++ } ++ ++ err = ext3_reserve_inode_write(handle, inode, &iloc); ++ if (err) { ++ brelse(bh); ++ return err; ++ } ++ ++ if (here) { ++ /* time to remove old value */ ++ struct ext3_xattr_entry *e; ++ int size = le32_to_cpu(here->e_value_size); ++ int border = le16_to_cpu(here->e_value_offs); ++ char *src; ++ ++ /* move tail */ ++ memmove(start + min_offs + size, start + min_offs, ++ border - min_offs); ++ ++ /* recalculate offsets */ ++ e = (struct ext3_xattr_entry *) start; ++ while (!IS_LAST_ENTRY(e)) { ++ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e); ++ int offs = le16_to_cpu(e->e_value_offs); ++ if (offs < border) ++ e->e_value_offs = ++ cpu_to_le16(offs + size); ++ e = next; ++ } ++ min_offs += size; ++ ++ /* remove entry */ ++ border = EXT3_XATTR_LEN(here->e_name_len); ++ src = (char *) here + EXT3_XATTR_LEN(here->e_name_len); ++ size = (char *) last - src; ++ if ((char *) here + size > end) ++ printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n", ++ __FILE__, __LINE__, here, size, end); ++ memmove(here, src, size); ++ last = (struct ext3_xattr_entry *) ((char *) last - border); ++ *((__u32 *) last) = 0; ++ } ++ ++ if (value) { ++ int offs = min_offs - value_len; ++ /* use last to create new entry */ ++ last->e_name_len = strlen(name); ++ last->e_name_index = name_index; ++ last->e_value_offs = cpu_to_le16(offs); ++ last->e_value_size = cpu_to_le32(value_len); ++ last->e_hash = last->e_value_block = 0; ++ memset(last->e_name, 0, esize); ++ memcpy(last->e_name, name, last->e_name_len); ++ if (start + offs + value_len > end) ++ printk("ALERT at %s:%d: 0x%p + %d + %d > 0x%p\n", ++ __FILE__, __LINE__, start, offs, ++ value_len, end); ++ memcpy(start + offs, value, value_len); ++ last = EXT3_XATTR_NEXT(last); ++ *((__u32 *) last) = 0; ++ } ++ ++ ext3_mark_iloc_dirty(handle, inode, &iloc); ++ brelse(bh); ++ ++ return 0; ++} ++ ++/* + * ext3_xattr_set() + * + * Create, replace or remove an extended attribute for this inode. Buffer +@@ -566,6 +1050,102 @@ static void ext3_xattr_update_super_bloc + */ + int + ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, ++ const char *name, const void *value, size_t value_len, int flags) ++{ ++ struct ext3_xattr_entry entry; ++ int err, where = 0, found = 0, total; ++ int free1 = -1, free2 = -1; ++ int name_len; ++ ++ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", ++ name_index, name, value, (long)value_len); ++ ++ if (IS_RDONLY(inode)) ++ return -EROFS; ++ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) ++ return -EPERM; ++ if (value == NULL) ++ value_len = 0; ++ if (name == NULL) ++ return -EINVAL; ++ name_len = strlen(name); ++ if (name_len > 255 || value_len > inode->i_sb->s_blocksize) ++ return -ERANGE; ++ down(&ext3_xattr_sem); ++ ++ /* try to find attribute in inode body */ ++ err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1); ++ if (err == 0) { ++ /* found EA in inode */ ++ found = 1; ++ where = 0; ++ } else if (err == -ENOENT) { ++ /* there is no such attribute in inode body */ ++ /* try to find attribute in dedicated block */ ++ err = ext3_xattr_block_find(inode, name_index, name, ++ &entry, &free2); ++ if (err != 0 && err != -ENOENT) { ++ /* not found EA in block */ ++ goto finish; ++ } ++ /* found EA in block */ ++ where = 1; ++ found = 1; ++ } else ++ goto finish; ++ ++ /* check flags: may replace? may create ? */ ++ if (found && (flags & XATTR_CREATE)) { ++ err = -EEXIST; ++ goto finish; ++ } else if (!found && (flags & XATTR_REPLACE)) { ++ err = -ENODATA; ++ goto finish; ++ } ++ ++ /* check if we have enough space to store attribute */ ++ total = EXT3_XATTR_LEN(strlen(name)) + value_len; ++ if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) { ++ /* have no enough space */ ++ err = -ENOSPC; ++ goto finish; ++ } ++ ++ /* time to remove attribute */ ++ if (found) { ++ if (where == 0) { ++ /* EA is stored in inode body */ ++ ext3_xattr_ibody_set(handle, inode, name_index, name, ++ NULL, 0, flags); ++ } else { ++ /* EA is stored in separated block */ ++ ext3_xattr_block_set(handle, inode, name_index, name, ++ NULL, 0, flags); ++ } ++ } ++ ++ /* try to store EA in inode body */ ++ err = ext3_xattr_ibody_set(handle, inode, name_index, name, ++ value, value_len, flags); ++ if (err) { ++ /* can't store EA in inode body */ ++ /* try to store in block */ ++ err = ext3_xattr_block_set(handle, inode, name_index, ++ name, value, value_len, flags); ++ } ++ ++finish: ++ up(&ext3_xattr_sem); ++ return err; ++} ++ ++/* ++ * ext3_xattr_block_set() ++ * ++ * this routine add/remove/replace attribute in EA block ++ */ ++int ++ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index, + const char *name, const void *value, size_t value_len, int flags) + { + struct super_block *sb = inode->i_sb; +@@ -603,7 +1183,6 @@ ext3_xattr_set(handle_t *handle, struct + name_len = strlen(name); + if (name_len > 255 || value_len > sb->s_blocksize) + return -ERANGE; +- down(&ext3_xattr_sem); + + if (block) { + /* The inode already has an extended attribute block. */ +@@ -801,7 +1380,6 @@ cleanup: + brelse(bh); + if (!(bh && header == HDR(bh))) + kfree(header); +- up(&ext3_xattr_sem); + + return error; + } +--- linux-2.4.20-vanilla/include/linux/ext3_fs.h~ext3-ea-in-inode-2.4.20 2003-09-17 21:16:09.000000000 +0400 ++++ linux-2.4.20-vanilla-alexey/include/linux/ext3_fs.h 2003-09-17 21:16:16.000000000 +0400 +@@ -264,6 +264,8 @@ struct ext3_inode { + __u32 m_i_reserved2[2]; + } masix2; + } osd2; /* OS dependent 2 */ ++ __u16 i_extra_isize; ++ __u16 i_pad1; + }; + + #define i_size_high i_dir_acl +--- linux-2.4.20-vanilla/include/linux/ext3_fs_i.h~ext3-ea-in-inode-2.4.20 2003-09-17 21:14:55.000000000 +0400 ++++ linux-2.4.20-vanilla-alexey/include/linux/ext3_fs_i.h 2003-09-17 21:16:16.000000000 +0400 +@@ -62,6 +62,9 @@ struct ext3_inode_info { + */ + loff_t i_disksize; + ++ /* on-disk additional lenght */ ++ __u16 i_extra_isize; ++ + /* + * truncate_sem is for serialising ext3_truncate() against + * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's +--- linux-2.4.20-vanilla/fs/ext3/super.c~ext3-ea-in-inode-2.4.20 2003-09-17 21:06:29.000000000 +0400 ++++ linux-2.4.20-vanilla-alexey/fs/ext3/super.c 2003-09-17 21:34:13.000000000 +0400 +@@ -1292,8 +1292,10 @@ struct super_block * ext3_read_super (st + } else { + sbi->s_inode_size = le16_to_cpu(es->s_inode_size); + sbi->s_first_ino = le32_to_cpu(es->s_first_ino); +- if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) { +- printk (KERN_ERR ++ if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) || ++ (sbi->s_inode_size & (sbi->s_inode_size - 1)) || ++ (sbi->s_inode_size > blocksize)) { ++ printk (KERN_ERR + "EXT3-fs: unsupported inode size: %d\n", + sbi->s_inode_size); + goto failed_mount; + +_ diff --git a/lustre/kernel_patches/pc/ext3-ea-in-inode-2.4.20.pc b/lustre/kernel_patches/pc/ext3-ea-in-inode-2.4.20.pc new file mode 100644 index 0000000..ae80099 --- /dev/null +++ b/lustre/kernel_patches/pc/ext3-ea-in-inode-2.4.20.pc @@ -0,0 +1,6 @@ +fs/ext3/ialloc.c +fs/ext3/inode.c +fs/ext3/xattr.c +include/linux/ext3_fs.h +include/linux/ext3_fs_i.h +fs/ext3/super.c diff --git a/lustre/lvfs/Makefile.am b/lustre/lvfs/Makefile.am index 5842f63..9df4c5d 100644 --- a/lustre/lvfs/Makefile.am +++ b/lustre/lvfs/Makefile.am @@ -25,7 +25,7 @@ else modulefs_DATA = lvfs.o $(FSMOD).o fsfilt_reiserfs.o EXTRA_PROGRAMS = lvfs $(FSMOD) fsfilt_reiserfs -lvfs_SOURCES = lvfs_common.c lvfs_linux.c fsfilt.c +lvfs_SOURCES = lvfs_common.c lvfs_linux.c fsfilt.c lvfs_internal.h endif diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index 830bf68..501e43f 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -331,7 +331,6 @@ static int fsfilt_ext3_set_md(struct inode *inode, void *handle, mark_inode_dirty(inode); return 0; } else { - down(&inode->i_sem); lock_kernel(); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) rc = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_LUSTRE, @@ -343,7 +342,6 @@ static int fsfilt_ext3_set_md(struct inode *inode, void *handle, lmm_size, 0); #endif unlock_kernel(); - up(&inode->i_sem); } if (rc) diff --git a/lustre/lvfs/fsfilt_extN.c b/lustre/lvfs/fsfilt_extN.c index d5adb5a..7141e45 100644 --- a/lustre/lvfs/fsfilt_extN.c +++ b/lustre/lvfs/fsfilt_extN.c @@ -325,12 +325,10 @@ static int fsfilt_extN_set_md(struct inode *inode, void *handle, mark_inode_dirty(inode); return 0; } else { - down(&inode->i_sem); lock_kernel(); rc = extN_xattr_set(handle, inode, EXTN_XATTR_INDEX_LUSTRE, XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0); unlock_kernel(); - up(&inode->i_sem); } if (rc) diff --git a/lustre/obdclass/llog_cat.c b/lustre/obdclass/llog_cat.c index f28c769..0f916d9 100644 --- a/lustre/obdclass/llog_cat.c +++ b/lustre/obdclass/llog_cat.c @@ -234,10 +234,9 @@ int llog_cat_cancel_records(struct llog_handle *cathandle, int count, struct llog_handle *loghandle; struct llog_log_hdr *llh; struct llog_logid *lgl = &cookies->lgc_lgl; - int res; rc = llog_cat_id2handle(cathandle, &loghandle, lgl); - if (res) { + if (rc) { CERROR("Cannot find log "LPX64"\n", lgl->lgl_oid); break; } diff --git a/lustre/obdclass/llog_lvfs.c b/lustre/obdclass/llog_lvfs.c index 7eeb6a8..640fdf7 100644 --- a/lustre/obdclass/llog_lvfs.c +++ b/lustre/obdclass/llog_lvfs.c @@ -322,7 +322,7 @@ static int llog_lvfs_create(struct obd_device *obd, struct llog_handle **res, { char logname[24]; struct llog_handle *handle; - struct l_dentry *dchild; + struct l_dentry *dchild = NULL; struct obdo *oa = NULL; int rc = 0, cleanup_phase = 1; int open_flags = O_RDWR | O_CREAT | O_LARGEFILE; -- 1.8.3.1