Whamcloud - gitweb
LU-2760 ldiskfs: update rhel6.3 series to handle mkdir errors
authorJames Simmons <uja.ornl@gmail.com>
Tue, 5 Mar 2013 17:42:35 +0000 (12:42 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 22 Mar 2013 17:36:48 +0000 (13:36 -0400)
ext4_mkdir can fail in several paths to dirtying an inode but
the errors aren't caught. This patch adds the upstream commit
that handles the errors and adjusts the dependent patches
accordingly.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: James Simmons <uja.ornl@gmail.com>
Change-Id: If86538e88c7386a06016ffae6893bacc8ba131e4
Reviewed-on: http://review.whamcloud.com/5279
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
ldiskfs/kernel_patches/patches/rhel6.3/ext4-add-more-error-checks-to-ext4_mkdir.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/rhel6.3/ext4-osd-iop-common.patch
ldiskfs/kernel_patches/patches/rhel6.3/ext4_data_in_dirent.patch
ldiskfs/kernel_patches/patches/rhel6.3/ext4_pdirop.patch
ldiskfs/kernel_patches/patches/sles11sp1/ext4-update-sles11-rhel6.patch
ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.series
ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series

diff --git a/ldiskfs/kernel_patches/patches/rhel6.3/ext4-add-more-error-checks-to-ext4_mkdir.patch b/ldiskfs/kernel_patches/patches/rhel6.3/ext4-add-more-error-checks-to-ext4_mkdir.patch
new file mode 100644 (file)
index 0000000..79d7a68
--- /dev/null
@@ -0,0 +1,75 @@
+From dabd991f9d8e3232bb4531c920daddac8d10d313 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung@gmail.com>
+Date: Mon, 10 Jan 2011 12:11:16 -0500
+Subject: ext4: add more error checks to ext4_mkdir()
+Git-commit: dabd991f
+Patch-mainline: v2.6.38-rc1
+
+Check return value of ext4_journal_get_write_access,
+ext4_journal_dirty_metadata and ext4_mark_inode_dirty. Move brelse()
+under 'out_stop' to release bh properly in case of journal error.
+
+Upstream-Signed-off-by: Namhyung Kim <namhyung@gmail.com>
+Upstream-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Upstream-Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ fs/ext4/namei.c |   21 ++++++++++++++-------
+ 1 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 96a594d..6dfc5b9 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1789,7 +1789,7 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+ {
+       handle_t *handle;
+       struct inode *inode;
+-      struct buffer_head *dir_block;
++      struct buffer_head *dir_block = NULL;
+       struct ext4_dir_entry_2 *de;
+       unsigned int blocksize = dir->i_sb->s_blocksize;
+       int err, retries = 0;
+@@ -1822,7 +1822,9 @@ retry:
+       if (!dir_block)
+               goto out_clear_inode;
+       BUFFER_TRACE(dir_block, "get_write_access");
+-      ext4_journal_get_write_access(handle, dir_block);
++      err = ext4_journal_get_write_access(handle, dir_block);
++      if (err)
++              goto out_clear_inode;
+       de = (struct ext4_dir_entry_2 *) dir_block->b_data;
+       de->inode = cpu_to_le32(inode->i_ino);
+       de->name_len = 1;
+@@ -1839,10 +1841,12 @@ retry:
+       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+       inode->i_nlink = 2;
+       BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
+-      ext4_handle_dirty_metadata(handle, inode, dir_block);
+-      brelse(dir_block);
+-      ext4_mark_inode_dirty(handle, inode);
+-      err = ext4_add_entry(handle, dentry, inode);
++      err = ext4_handle_dirty_metadata(handle, inode, dir_block);
++      if (err)
++              goto out_clear_inode;
++      err = ext4_mark_inode_dirty(handle, inode);
++      if (!err)
++              err = ext4_add_entry(handle, dentry, inode);
+       if (err) {
+ out_clear_inode:
+               clear_nlink(inode);
+@@ -1853,10 +1857,13 @@ out_clear_inode:
+       }
+       ext4_inc_count(handle, dir);
+       ext4_update_dx_flag(dir);
+-      ext4_mark_inode_dirty(handle, dir);
++      err = ext4_mark_inode_dirty(handle, dir);
++      if (err)
++              goto out_clear_inode;
+       d_instantiate(dentry, inode);
+       unlock_new_inode(inode);
+ out_stop:
++      brelse(dir_block);
+       ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+
index c144e81..1f1fb2a 100644 (file)
@@ -1,8 +1,6 @@
-Index: linux-stage/fs/ext4/ext4.h
-===================================================================
---- linux-stage.orig/fs/ext4/ext4.h
-+++ linux-stage/fs/ext4/ext4.h
-@@ -1599,6 +1599,19 @@ extern int ext4_orphan_add(handle_t *, s
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1778,6 +1778,19 @@ extern int ext4_orphan_add(handle_t *, s
  extern int ext4_orphan_del(handle_t *, struct inode *);
  extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
                                __u32 start_minor_hash, __u32 *next_hash);
  extern int ext4_orphan_del(handle_t *, struct inode *);
  extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
                                __u32 start_minor_hash, __u32 *next_hash);
@@ -22,10 +20,8 @@ Index: linux-stage/fs/ext4/ext4.h
  
  /* resize.c */
  extern int ext4_group_add(struct super_block *sb,
  
  /* resize.c */
  extern int ext4_group_add(struct super_block *sb,
-Index: linux-stage/fs/ext4/namei.c
-===================================================================
---- linux-stage.orig/fs/ext4/namei.c
-+++ linux-stage/fs/ext4/namei.c
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
 @@ -24,6 +24,7 @@
   *    Theodore Ts'o, 2002
   */
 @@ -24,6 +24,7 @@
   *    Theodore Ts'o, 2002
   */
@@ -55,7 +51,7 @@ Index: linux-stage/fs/ext4/namei.c
  
  static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct qstr *d_name,
                       struct ext4_dir_entry_2 **res_dir, int *err)
  
  static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct qstr *d_name,
                       struct ext4_dir_entry_2 **res_dir, int *err)
-@@ -1503,8 +1505,8 @@ static int make_indexed_dir(handle_t *ha
+@@ -1515,8 +1517,8 @@ static int make_indexed_dir(handle_t *ha
   * may not sleep between calling this and putting something into
   * the entry, as someone else might have used it while you slept.
   */
   * may not sleep between calling this and putting something into
   * the entry, as someone else might have used it while you slept.
   */
@@ -66,7 +62,7 @@ Index: linux-stage/fs/ext4/namei.c
  {
        struct inode *dir = dentry->d_parent->d_inode;
        struct buffer_head *bh;
  {
        struct inode *dir = dentry->d_parent->d_inode;
        struct buffer_head *bh;
-@@ -1553,6 +1555,7 @@ static int ext4_add_entry(handle_t *hand
+@@ -1565,6 +1567,7 @@ static int ext4_add_entry(handle_t *hand
        brelse(bh);
        return retval;
  }
        brelse(bh);
        return retval;
  }
@@ -74,7 +70,7 @@ Index: linux-stage/fs/ext4/namei.c
  
  /*
   * Returns 0 for success, or a negative error value
  
  /*
   * Returns 0 for success, or a negative error value
-@@ -1692,10 +1695,10 @@ cleanup:
+@@ -1704,10 +1707,10 @@ cleanup:
   * ext4_delete_entry deletes a directory entry by merging it with the
   * previous entry
   */
   * ext4_delete_entry deletes a directory entry by merging it with the
   * previous entry
   */
@@ -89,7 +85,7 @@ Index: linux-stage/fs/ext4/namei.c
  {
        struct ext4_dir_entry_2 *de, *pde;
        unsigned int blocksize = dir->i_sb->s_blocksize;
  {
        struct ext4_dir_entry_2 *de, *pde;
        unsigned int blocksize = dir->i_sb->s_blocksize;
-@@ -1730,7 +1733,7 @@ static int ext4_delete_entry(handle_t *h
+@@ -1742,7 +1745,7 @@ static int ext4_delete_entry(handle_t *h
        }
        return -ENOENT;
  }
        }
        return -ENOENT;
  }
@@ -98,7 +94,7 @@ Index: linux-stage/fs/ext4/namei.c
  /*
   * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
   * since this indicates that nlinks count was previously 1.
  /*
   * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
   * since this indicates that nlinks count was previously 1.
-@@ -1795,6 +1798,27 @@ static unsigned ext4_dentry_goal(struct 
+@@ -1806,6 +1809,27 @@ static unsigned ext4_dentry_goal(struct
        return inum;
  }
  
        return inum;
  }
  
@@ -126,7 +122,7 @@ Index: linux-stage/fs/ext4/namei.c
  /*
   * By the time this is called, we already have created
   * the directory cache entry for the new file, but it
  /*
   * By the time this is called, we already have created
   * the directory cache entry for the new file, but it
-@@ -1871,40 +1895,33 @@ retry:
+@@ -1882,44 +1906,32 @@ retry:
        return err;
  }
  
        return err;
  }
  
@@ -138,17 +134,17 @@ Index: linux-stage/fs/ext4/namei.c
  {
 -      handle_t *handle;
 -      struct inode *inode;
  {
 -      handle_t *handle;
 -      struct inode *inode;
--      struct buffer_head *dir_block;
+-      struct buffer_head *dir_block = NULL;
 -      struct ext4_dir_entry_2 *de;
 +      struct buffer_head * dir_block;
 +      struct ext4_dir_entry_2 * de;
        unsigned int blocksize = dir->i_sb->s_blocksize;
 -      int err, retries = 0;
 -      struct ext4_dir_entry_2 *de;
 +      struct buffer_head * dir_block;
 +      struct ext4_dir_entry_2 * de;
        unsigned int blocksize = dir->i_sb->s_blocksize;
 -      int err, retries = 0;
--
--      if (EXT4_DIR_LINK_MAX(dir))
--              return -EMLINK;
 +      int err = 0;
  
 +      int err = 0;
  
+-      if (EXT4_DIR_LINK_MAX(dir))
+-              return -EMLINK;
+-
 -retry:
 -      handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
 -                                      EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
 -retry:
 -      handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
 -                                      EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -164,27 +160,39 @@ Index: linux-stage/fs/ext4/namei.c
 -      err = PTR_ERR(inode);
 -      if (IS_ERR(inode))
 -              goto out_stop;
 -      err = PTR_ERR(inode);
 -      if (IS_ERR(inode))
 -              goto out_stop;
+-
        inode->i_op = &ext4_dir_inode_operations;
        inode->i_fop = &ext4_dir_operations;
        inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
        dir_block = ext4_bread(handle, inode, 0, 1, &err);
        inode->i_op = &ext4_dir_inode_operations;
        inode->i_fop = &ext4_dir_operations;
        inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
        dir_block = ext4_bread(handle, inode, 0, 1, &err);
--      if (!dir_block)
+       if (!dir_block)
 -              goto out_clear_inode;
 -              goto out_clear_inode;
-+      if (!dir_block) {
-+              clear_nlink(inode);
-+              ext4_mark_inode_dirty(handle, inode);
-+              iput (inode);
 +              goto get_out;
 +              goto get_out;
-+      }
        BUFFER_TRACE(dir_block, "get_write_access");
        BUFFER_TRACE(dir_block, "get_write_access");
-       ext4_journal_get_write_access(handle, dir_block);
+       err = ext4_journal_get_write_access(handle, dir_block);
+       if (err)
+-              goto out_clear_inode;
++              goto get_out;
        de = (struct ext4_dir_entry_2 *) dir_block->b_data;
        de = (struct ext4_dir_entry_2 *) dir_block->b_data;
-@@ -1926,9 +1943,45 @@ retry:
-       ext4_handle_dirty_metadata(handle, dir, dir_block);
-       brelse(dir_block);
-       ext4_mark_inode_dirty(handle, inode);
+       de->inode = cpu_to_le32(inode->i_ino);
+       de->name_len = 1;
+@@ -1938,18 +1950,47 @@ retry:
+       BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
+       err = ext4_handle_dirty_metadata(handle, inode, dir_block);
+       if (err)
+-              goto out_clear_inode;
++              goto get_out;
+       err = ext4_mark_inode_dirty(handle, inode);
+-      if (!err)
+-              err = ext4_add_entry(handle, dentry, inode);
+-      if (err) {
+-out_clear_inode:
+-              clear_nlink(inode);
+-              unlock_new_inode(inode);
+-              ext4_mark_inode_dirty(handle, inode);
+-              iput(inode);
 +get_out:
 +get_out:
++      brelse(dir_block);
 +      return err;
 +}
 +EXPORT_SYMBOL(ext4_add_dot_dotdot);
 +      return err;
 +}
 +EXPORT_SYMBOL(ext4_add_dot_dotdot);
@@ -207,23 +215,40 @@ Index: linux-stage/fs/ext4/namei.c
 +              return PTR_ERR(handle);
 +
 +      if (IS_DIRSYNC(dir))
 +              return PTR_ERR(handle);
 +
 +      if (IS_DIRSYNC(dir))
-+              handle->h_sync = 1;
++              ext4_handle_sync(handle);
 +
 +
-+      inode = ext4_new_inode(handle, dir, S_IFDIR | mode,
-+                             &dentry->d_name, ext4_dentry_goal(dir->i_sb, dentry));
++      inode = ext4_new_inode(handle, dir, S_IFDIR | mode, &dentry->d_name,
++                             ext4_dentry_goal(dir->i_sb, dentry));
 +      err = PTR_ERR(inode);
 +      if (IS_ERR(inode))
 +      err = PTR_ERR(inode);
 +      if (IS_ERR(inode))
-+              goto out_stop;
+               goto out_stop;
+-      }
 +
 +      err = ext4_add_dot_dotdot(handle, dir, inode);
 +
 +      err = ext4_add_dot_dotdot(handle, dir, inode);
-+      if (err) {
-+              unlock_new_inode(inode);
-+              goto out_stop;
-+      }
++      if (err)
++              goto out_clear_inode;
 +
 +
-       err = ext4_add_entry(handle, dentry, inode);
-       if (err) {
--out_clear_inode:
-               clear_nlink(inode);
-               unlock_new_inode(inode);
-               ext4_mark_inode_dirty(handle, inode);
++      err = ext4_add_entry(handle, dentry, inode);
++      if (err)
++              goto out_clear_inode;
+       ext4_inc_count(handle, dir);
+       ext4_update_dx_flag(dir);
+       err = ext4_mark_inode_dirty(handle, dir);
+@@ -1958,11 +1999,16 @@ out_clear_inode:
+       d_instantiate(dentry, inode);
+       unlock_new_inode(inode);
+ out_stop:
+-      brelse(dir_block);
+       ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
++out_clear_inode:
++      clear_nlink(inode);
++      unlock_new_inode(inode);
++      ext4_mark_inode_dirty(handle, inode);
++      iput(inode);
++      goto out_stop;
+ }
+ /*
index 75e5634..72c2395 100644 (file)
@@ -7,11 +7,9 @@ is present.
 make use of dentry->d_fsdata to pass fid to ext4. so no
 changes in ext4_add_entry() interface required.
 
 make use of dentry->d_fsdata to pass fid to ext4. so no
 changes in ext4_add_entry() interface required.
 
-Index: linux-stage/fs/ext4/dir.c
-===================================================================
---- linux-stage.orig/fs/ext4/dir.c
-+++ linux-stage/fs/ext4/dir.c
-@@ -53,11 +53,18 @@ const struct file_operations ext4_dir_op
+--- a/fs/ext4/dir.c
++++ b/fs/ext4/dir.c
+@@ -37,11 +37,18 @@ static int ext4_dx_readdir(struct file *
  
  static unsigned char get_dtype(struct super_block *sb, int filetype)
  {
  
  static unsigned char get_dtype(struct super_block *sb, int filetype)
  {
@@ -31,8 +29,8 @@ Index: linux-stage/fs/ext4/dir.c
 +
  }
  
 +
  }
  
-@@ -70,11 +77,11 @@ int ext4_check_dir_entry(const char *fun
+ /**
+@@ -73,11 +80,11 @@ int ext4_check_dir_entry(const char *fun
        const int rlen = ext4_rec_len_from_disk(de->rec_len,
                                                dir->i_sb->s_blocksize);
  
        const int rlen = ext4_rec_len_from_disk(de->rec_len,
                                                dir->i_sb->s_blocksize);
  
@@ -44,9 +42,9 @@ Index: linux-stage/fs/ext4/dir.c
 -      else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
 +      else if (unlikely(rlen < EXT4_DIR_REC_LEN(de)))
                error_msg = "rec_len is too small for name_len";
 -      else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
 +      else if (unlikely(rlen < EXT4_DIR_REC_LEN(de)))
                error_msg = "rec_len is too small for name_len";
-       else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
+       else if (unlikely(((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize))
                error_msg = "directory entry across blocks";
                error_msg = "directory entry across blocks";
-@@ -182,7 +189,7 @@ revalidate:
+@@ -181,7 +188,7 @@ revalidate:
                                 * failure will be detected in the
                                 * dirent test below. */
                                if (ext4_rec_len_from_disk(de->rec_len,
                                 * failure will be detected in the
                                 * dirent test below. */
                                if (ext4_rec_len_from_disk(de->rec_len,
@@ -55,7 +53,7 @@ Index: linux-stage/fs/ext4/dir.c
                                        break;
                                i += ext4_rec_len_from_disk(de->rec_len,
                                                            sb->s_blocksize);
                                        break;
                                i += ext4_rec_len_from_disk(de->rec_len,
                                                            sb->s_blocksize);
-@@ -345,12 +352,17 @@ int ext4_htree_store_dirent(struct file 
+@@ -457,12 +464,17 @@ int ext4_htree_store_dirent(struct file
        struct fname *fname, *new_fn;
        struct dir_private_info *info;
        int len;
        struct fname *fname, *new_fn;
        struct dir_private_info *info;
        int len;
@@ -74,7 +72,7 @@ Index: linux-stage/fs/ext4/dir.c
        new_fn = kzalloc(len, GFP_KERNEL);
        if (!new_fn)
                return -ENOMEM;
        new_fn = kzalloc(len, GFP_KERNEL);
        if (!new_fn)
                return -ENOMEM;
-@@ -359,7 +371,7 @@ int ext4_htree_store_dirent(struct file 
+@@ -471,7 +483,7 @@ int ext4_htree_store_dirent(struct file
        new_fn->inode = le32_to_cpu(dirent->inode);
        new_fn->name_len = dirent->name_len;
        new_fn->file_type = dirent->file_type;
        new_fn->inode = le32_to_cpu(dirent->inode);
        new_fn->name_len = dirent->name_len;
        new_fn->file_type = dirent->file_type;
@@ -83,11 +81,9 @@ Index: linux-stage/fs/ext4/dir.c
        new_fn->name[dirent->name_len] = 0;
  
        while (*p) {
        new_fn->name[dirent->name_len] = 0;
  
        while (*p) {
-Index: linux-stage/fs/ext4/ext4.h
-===================================================================
---- linux-stage.orig/fs/ext4/ext4.h
-+++ linux-stage/fs/ext4/ext4.h
-@@ -1267,6 +1267,7 @@ EXT4_INODE_BIT_FNS(state, state_flags)
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1294,6 +1294,7 @@ EXT4_INODE_BIT_FNS(state, state_flags)
  #define EXT4_FEATURE_INCOMPAT_64BIT           0x0080
  #define EXT4_FEATURE_INCOMPAT_MMP               0x0100
  #define EXT4_FEATURE_INCOMPAT_FLEX_BG         0x0200
  #define EXT4_FEATURE_INCOMPAT_64BIT           0x0080
  #define EXT4_FEATURE_INCOMPAT_MMP               0x0100
  #define EXT4_FEATURE_INCOMPAT_FLEX_BG         0x0200
@@ -95,7 +91,7 @@ Index: linux-stage/fs/ext4/ext4.h
  
  #define EXT4_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
  #define EXT4_FEATURE_INCOMPAT_SUPP    (EXT4_FEATURE_INCOMPAT_FILETYPE| \
  
  #define EXT4_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
  #define EXT4_FEATURE_INCOMPAT_SUPP    (EXT4_FEATURE_INCOMPAT_FILETYPE| \
-@@ -1275,7 +1276,9 @@ EXT4_INODE_BIT_FNS(state, state_flags)
+@@ -1302,7 +1303,9 @@ EXT4_INODE_BIT_FNS(state, state_flags)
                                         EXT4_FEATURE_INCOMPAT_EXTENTS| \
                                         EXT4_FEATURE_INCOMPAT_64BIT| \
                                         EXT4_FEATURE_INCOMPAT_FLEX_BG| \
                                         EXT4_FEATURE_INCOMPAT_EXTENTS| \
                                         EXT4_FEATURE_INCOMPAT_64BIT| \
                                         EXT4_FEATURE_INCOMPAT_FLEX_BG| \
@@ -106,7 +102,7 @@ Index: linux-stage/fs/ext4/ext4.h
  #define EXT4_FEATURE_RO_COMPAT_SUPP   (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
  #define EXT4_FEATURE_RO_COMPAT_SUPP   (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
-@@ -1357,6 +1360,43 @@ struct ext4_dir_entry_2 {
+@@ -1388,6 +1391,43 @@ struct ext4_dir_entry_2 {
  #define EXT4_FT_SYMLINK               7
  
  #define EXT4_FT_MAX           8
  #define EXT4_FT_SYMLINK               7
  
  #define EXT4_FT_MAX           8
@@ -150,7 +146,7 @@ Index: linux-stage/fs/ext4/ext4.h
  
  /*
   * EXT4_DIR_PAD defines the directory entries boundaries
  
  /*
   * EXT4_DIR_PAD defines the directory entries boundaries
-@@ -1365,8 +1405,11 @@ struct ext4_dir_entry_2 {
+@@ -1396,8 +1436,11 @@ struct ext4_dir_entry_2 {
   */
  #define EXT4_DIR_PAD                  4
  #define EXT4_DIR_ROUND                        (EXT4_DIR_PAD - 1)
   */
  #define EXT4_DIR_PAD                  4
  #define EXT4_DIR_ROUND                        (EXT4_DIR_PAD - 1)
@@ -163,7 +159,7 @@ Index: linux-stage/fs/ext4/ext4.h
  #define EXT4_MAX_REC_LEN              ((1<<16)-1)
  
  static inline unsigned int
  #define EXT4_MAX_REC_LEN              ((1<<16)-1)
  
  static inline unsigned int
-@@ -1726,7 +1769,7 @@ extern struct buffer_head * ext4_find_en
+@@ -1791,7 +1834,7 @@ extern struct buffer_head * ext4_find_en
                                            struct ext4_dir_entry_2 ** res_dir);
  #define ll_ext4_find_entry(inode, dentry, res_dir) ext4_find_entry(inode, &(dentry)->d_name, res_dir)
  extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
                                            struct ext4_dir_entry_2 ** res_dir);
  #define ll_ext4_find_entry(inode, dentry, res_dir) ext4_find_entry(inode, &(dentry)->d_name, res_dir)
  extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
@@ -172,7 +168,7 @@ Index: linux-stage/fs/ext4/ext4.h
  extern struct buffer_head *ext4_append(handle_t *handle,
                                       struct inode *inode,
                                       ext4_lblk_t *block, int *err);
  extern struct buffer_head *ext4_append(handle_t *handle,
                                       struct inode *inode,
                                       ext4_lblk_t *block, int *err);
-@@ -2069,6 +2112,28 @@ extern wait_queue_head_t aio_wq[];
+@@ -2143,6 +2186,28 @@ extern wait_queue_head_t aio_wq[];
  #define to_aio_wq(v) (&aio_wq[((unsigned long)v) % WQ_HASH_SZ])
  extern void ext4_aio_wait(struct inode *inode);
  
  #define to_aio_wq(v) (&aio_wq[((unsigned long)v) % WQ_HASH_SZ])
  extern void ext4_aio_wait(struct inode *inode);
  
@@ -201,10 +197,8 @@ Index: linux-stage/fs/ext4/ext4.h
  #endif        /* __KERNEL__ */
  
  #endif        /* _EXT4_H */
  #endif        /* __KERNEL__ */
  
  #endif        /* _EXT4_H */
-Index: linux-stage/fs/ext4/namei.c
-===================================================================
---- linux-stage.orig/fs/ext4/namei.c
-+++ linux-stage/fs/ext4/namei.c
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
 @@ -169,7 +169,8 @@ static unsigned dx_get_count(struct dx_e
  static unsigned dx_get_limit(struct dx_entry *entries);
  static void dx_set_count(struct dx_entry *entries, unsigned value);
 @@ -169,7 +169,8 @@ static unsigned dx_get_count(struct dx_e
  static unsigned dx_get_limit(struct dx_entry *entries);
  static void dx_set_count(struct dx_entry *entries, unsigned value);
@@ -215,7 +209,7 @@ Index: linux-stage/fs/ext4/namei.c
  static unsigned dx_node_limit(struct inode *dir);
  static struct dx_frame *dx_probe(const struct qstr *d_name,
                                 struct inode *dir,
  static unsigned dx_node_limit(struct inode *dir);
  static struct dx_frame *dx_probe(const struct qstr *d_name,
                                 struct inode *dir,
-@@ -212,11 +213,12 @@ ext4_next_entry(struct ext4_dir_entry_2 
+@@ -212,11 +213,12 @@ ext4_next_entry(struct ext4_dir_entry_2
   */
  struct dx_root_info * dx_get_dx_info(struct ext4_dir_entry_2 *de)
  {
   */
  struct dx_root_info * dx_get_dx_info(struct ext4_dir_entry_2 *de)
  {
@@ -260,7 +254,7 @@ Index: linux-stage/fs/ext4/namei.c
        return entry_space / sizeof(struct dx_entry);
  }
  
        return entry_space / sizeof(struct dx_entry);
  }
  
-@@ -317,7 +326,7 @@ static struct stats dx_show_leaf(struct 
+@@ -317,7 +326,7 @@ static struct stats dx_show_leaf(struct
                                printk(":%x.%u ", h.hash,
                                       ((char *) de - base));
                        }
                                printk(":%x.%u ", h.hash,
                                       ((char *) de - base));
                        }
@@ -375,7 +369,7 @@ Index: linux-stage/fs/ext4/namei.c
  
        /* Initialize as for dx_probe */
        hinfo.hash_version = dx_info->hash_version;
  
        /* Initialize as for dx_probe */
        hinfo.hash_version = dx_info->hash_version;
-@@ -1511,6 +1534,8 @@ static int ext4_update_dotdot(handle_t *
+@@ -1523,6 +1546,8 @@ static int ext4_update_dotdot(handle_t *
        struct buffer_head * dir_block;
        struct ext4_dir_entry_2 * de;
        int len, journal = 0, err = 0;
        struct buffer_head * dir_block;
        struct ext4_dir_entry_2 * de;
        int len, journal = 0, err = 0;
@@ -384,7 +378,7 @@ Index: linux-stage/fs/ext4/namei.c
  
        if (IS_ERR(handle))
                return PTR_ERR(handle);
  
        if (IS_ERR(handle))
                return PTR_ERR(handle);
-@@ -1526,19 +1551,24 @@ static int ext4_update_dotdot(handle_t *
+@@ -1538,19 +1563,24 @@ static int ext4_update_dotdot(handle_t *
        /* the first item must be "." */
        assert(de->name_len == 1 && de->name[0] == '.');
        len = le16_to_cpu(de->rec_len);
        /* the first item must be "." */
        assert(de->name_len == 1 && de->name[0] == '.');
        len = le16_to_cpu(de->rec_len);
@@ -414,14 +408,14 @@ Index: linux-stage/fs/ext4/namei.c
        de = (struct ext4_dir_entry_2 *)
                        ((char *) de + le16_to_cpu(de->rec_len));
        if (!journal) {
        de = (struct ext4_dir_entry_2 *)
                        ((char *) de + le16_to_cpu(de->rec_len));
        if (!journal) {
-@@ -1552,10 +1582,15 @@ static int ext4_update_dotdot(handle_t *
+@@ -1564,10 +1594,15 @@ static int ext4_update_dotdot(handle_t *
        if (len > 0)
                de->rec_len = cpu_to_le16(len);
        else
 -              assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2));
 +              assert(le16_to_cpu(de->rec_len) >= __EXT4_DIR_REC_LEN(2));
        if (len > 0)
                de->rec_len = cpu_to_le16(len);
        else
 -              assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2));
 +              assert(le16_to_cpu(de->rec_len) >= __EXT4_DIR_REC_LEN(2));
-       de->name_len = 2;
-       strcpy (de->name, "..");
+       de->name_len = 2;
+       strcpy (de->name, "..");
 -      ext4_set_de_type(dir->i_sb, de, S_IFDIR);
 +      if (data != NULL && ext4_get_dirent_data_len(de) >= dlen) {
 +              de->name[2] = 0;
 -      ext4_set_de_type(dir->i_sb, de, S_IFDIR);
 +      if (data != NULL && ext4_get_dirent_data_len(de) >= dlen) {
 +              de->name[2] = 0;
@@ -432,7 +426,7 @@ Index: linux-stage/fs/ext4/namei.c
  
  out_journal:
        if (journal) {
  
  out_journal:
        if (journal) {
-@@ -1978,12 +2013,13 @@ retry:
+@@ -1989,12 +2024,13 @@ retry:
  /* Initialize @inode as a subdirectory of @dir, and add the
   * "." and ".." entries into the first directory block. */
  int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
  /* Initialize @inode as a subdirectory of @dir, and add the
   * "." and ".." entries into the first directory block. */
  int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
@@ -448,20 +442,7 @@ Index: linux-stage/fs/ext4/namei.c
  
        if (IS_ERR(handle))
                return PTR_ERR(handle);
  
        if (IS_ERR(handle))
                return PTR_ERR(handle);
-@@ -1996,28 +2032,40 @@ int ext4_add_dot_dotdot(handle_t *handle
-       inode->i_fop = &ext4_dir_operations;
-       inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-       dir_block = ext4_bread(handle, inode, 0, 1, &err);
--      if (!dir_block) {
--              clear_nlink(inode);
--              ext4_mark_inode_dirty(handle, inode);
--              iput (inode);
-+      if (!dir_block)
-               goto get_out;
--      }
-+
-       BUFFER_TRACE(dir_block, "get_write_access");
-       ext4_journal_get_write_access(handle, dir_block);
+@@ -2015,17 +2051,32 @@ int ext4_add_dot_dotdot(handle_t *handle
        de = (struct ext4_dir_entry_2 *) dir_block->b_data;
        de->inode = cpu_to_le32(inode->i_ino);
        de->name_len = 1;
        de = (struct ext4_dir_entry_2 *) dir_block->b_data;
        de->inode = cpu_to_le32(inode->i_ino);
        de->name_len = 1;
@@ -496,22 +477,17 @@ Index: linux-stage/fs/ext4/namei.c
 +      }
        inode->i_nlink = 2;
        BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
 +      }
        inode->i_nlink = 2;
        BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
-       ext4_handle_dirty_metadata(handle, dir, dir_block);
-@@ -2054,9 +2102,12 @@ retry:
+       err = ext4_handle_dirty_metadata(handle, inode, dir_block);
+@@ -2064,7 +2115,7 @@ retry:
        if (IS_ERR(inode))
                goto out_stop;
  
 -      err = ext4_add_dot_dotdot(handle, dir, inode);
 +      err = ext4_add_dot_dotdot(handle, dir, inode, NULL, NULL);
        if (IS_ERR(inode))
                goto out_stop;
  
 -      err = ext4_add_dot_dotdot(handle, dir, inode);
 +      err = ext4_add_dot_dotdot(handle, dir, inode, NULL, NULL);
-       if (err) {
-+              clear_nlink(inode);
-               unlock_new_inode(inode);
-+              ext4_mark_inode_dirty(handle, inode);
-+              iput (inode);
-               goto out_stop;
-       }
+       if (err)
+               goto out_clear_inode;
  
  
-@@ -2092,7 +2143,7 @@ static int empty_dir(struct inode *inode
+@@ -2103,7 +2154,7 @@ static int empty_dir(struct inode *inode
        int err = 0;
  
        sb = inode->i_sb;
        int err = 0;
  
        sb = inode->i_sb;
index 029f549..dbd6a8e 100644 (file)
  
 -      err = ext4_add_entry(handle, dentry, inode);
 +      err = ext4_add_entry(handle, dentry, inode, NULL);
  
 -      err = ext4_add_entry(handle, dentry, inode);
 +      err = ext4_add_entry(handle, dentry, inode, NULL);
-       if (err) {
-               clear_nlink(inode);
-               unlock_new_inode(inode);
+       if (err)
+               goto out_clear_inode;
+       ext4_inc_count(handle, dir);
 @@ -2381,7 +2789,7 @@ static int ext4_rmdir(struct inode *dir,
                return PTR_ERR(handle);
  
 @@ -2381,7 +2789,7 @@ static int ext4_rmdir(struct inode *dir,
                return PTR_ERR(handle);
  
index 3b9f80d..81fc943 100644 (file)
@@ -1016,6 +1016,15 @@ diff -urpN linux-stage.orig/fs/ext4/namei.c linux-stage/fs/ext4/namei.c
                        err = -ENOSPC;
                        goto cleanup;
                }
                        err = -ENOSPC;
                        goto cleanup;
                }
+@@ -1904,7 +1921,7 @@
+       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+       inode->i_nlink = 2;
+       BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
+-      ext4_handle_dirty_metadata(handle, dir, dir_block);
++      ext4_handle_dirty_metadata(handle, inode, dir_block);
+       brelse(dir_block);
+       ext4_mark_inode_dirty(handle, inode);
+       err = ext4_add_entry(handle, dentry, inode);
 @@ -1943,11 +1960,11 @@ static int empty_dir(struct inode *inode
        if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
            !(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
 @@ -1943,11 +1960,11 @@ static int empty_dir(struct inode *inode
        if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
            !(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
index 28d44bb..e051972 100644 (file)
@@ -17,6 +17,7 @@ rhel6.3/ext4-big-endian-check-2.6.patch
 rhel6.3/ext4-alloc-policy-2.6.patch
 rhel6.3/ext4-force_over_128tb.patch
 rhel6.3/ext4-pdir-fix.patch
 rhel6.3/ext4-alloc-policy-2.6.patch
 rhel6.3/ext4-force_over_128tb.patch
 rhel6.3/ext4-pdir-fix.patch
+rhel6.3/ext4-add-more-error-checks-to-ext4_mkdir.patch
 rhel6.3/ext4-osd-iop-common.patch
 rhel6.3/ext4-osd-iam-exports.patch
 rhel6.3/ext4-dynlocks-common.patch
 rhel6.3/ext4-osd-iop-common.patch
 rhel6.3/ext4-osd-iam-exports.patch
 rhel6.3/ext4-dynlocks-common.patch
index d4f5db5..2c35389 100644 (file)
@@ -18,6 +18,7 @@ rhel6.3/ext4-big-endian-check-2.6.patch
 rhel6.3/ext4-alloc-policy-2.6.patch
 rhel6.3/ext4-force_over_128tb.patch
 rhel6.3/ext4-pdir-fix.patch
 rhel6.3/ext4-alloc-policy-2.6.patch
 rhel6.3/ext4-force_over_128tb.patch
 rhel6.3/ext4-pdir-fix.patch
+rhel6.3/ext4-add-more-error-checks-to-ext4_mkdir.patch
 rhel6.3/ext4-osd-iop-common.patch
 rhel6.3/ext4-osd-iam-exports.patch
 rhel6.3/ext4-dynlocks-common.patch
 rhel6.3/ext4-osd-iop-common.patch
 rhel6.3/ext4-osd-iam-exports.patch
 rhel6.3/ext4-dynlocks-common.patch