Whamcloud - gitweb
- merge b_devel into b_llog
authorbraam <braam>
Wed, 17 Sep 2003 19:14:16 +0000 (19:14 +0000)
committerbraam <braam>
Wed, 17 Sep 2003 19:14:16 +0000 (19:14 +0000)
lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch [new file with mode: 0644]
lustre/kernel_patches/pc/ext3-ea-in-inode-2.4.20.pc [new file with mode: 0644]
lustre/lvfs/Makefile.am
lustre/lvfs/fsfilt_ext3.c
lustre/lvfs/fsfilt_extN.c
lustre/obdclass/llog_cat.c
lustre/obdclass/llog_lvfs.c

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 (file)
index 0000000..f150020
--- /dev/null
@@ -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 (file)
index 0000000..ae80099
--- /dev/null
@@ -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
index 5842f63..9df4c5d 100644 (file)
@@ -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
 
 
index 830bf68..501e43f 100644 (file)
@@ -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)
index d5adb5a..7141e45 100644 (file)
@@ -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)
index f28c769..0f916d9 100644 (file)
@@ -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;
                 }
index 7eeb6a8..640fdf7 100644 (file)
@@ -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;