Whamcloud - gitweb
b=3244
authoryangjun <yangjun>
Fri, 20 Aug 2004 11:33:08 +0000 (11:33 +0000)
committeryangjun <yangjun>
Fri, 20 Aug 2004 11:33:08 +0000 (11:33 +0000)
-add ext3-nlinks-2.4.24.patch for make more than 32000 subdirectories.
-add rmdirmany tool to remove many subdirectories.
-add mkdir and rmdir test in sanity.sh.
-modify MDSSIZE=400000 OSTSIZE=400000 in local.sh.
-modify MDSSIZE=400000 in lov.sh.

lustre/kernel_patches/patches/ext3-nlinks-2.4.24.patch [new file with mode: 0644]
lustre/tests/rmdirmany.c [new file with mode: 0755]

diff --git a/lustre/kernel_patches/patches/ext3-nlinks-2.4.24.patch b/lustre/kernel_patches/patches/ext3-nlinks-2.4.24.patch
new file mode 100644 (file)
index 0000000..f198362
--- /dev/null
@@ -0,0 +1,170 @@
+--- ./fs/ext3/namei.c.orig     2004-08-19 12:53:21.000000000 +0800
++++ ./fs/ext3/namei.c  2004-08-19 12:44:18.000000000 +0800
+@@ -1541,11 +1541,16 @@
+ static inline void ext3_inc_count(handle_t *handle, struct inode *inode)
+ {
+       inode->i_nlink++;
++      if (is_dx(inode) && inode->i_nlink > 1) {
++              if (inode->i_nlink >= 65000) /* limit is 16-bit i_links_count */
++                      inode->i_nlink = 1;
++        }
+ }
+ static inline void ext3_dec_count(handle_t *handle, struct inode *inode)
+ {
+-      inode->i_nlink--;
++      if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
++              inode->i_nlink--;
+ }
+ static int ext3_add_nondir(handle_t *handle,
+@@ -1646,7 +1651,7 @@
+       struct ext3_dir_entry_2 * de;
+       int err;
+-      if (dir->i_nlink >= EXT3_LINK_MAX)
++      if (EXT3_DIR_LINK_MAXED(dir))
+               return -EMLINK;
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+@@ -1668,7 +1673,7 @@
+       inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+       dir_block = ext3_bread (handle, inode, 0, 1, &err);
+       if (!dir_block) {
+-              inode->i_nlink--; /* is this nlink == 0? */
++              ext3_dec_count(handle, inode); /* is this nlink == 0? */
+               ext3_mark_inode_dirty(handle, inode);
+               iput (inode);
+               goto out_stop;
+@@ -1700,7 +1705,7 @@
+               iput (inode);
+               goto out_stop;
+       }
+-      dir->i_nlink++;
++      ext3_inc_count(handle, dir);
+       ext3_update_dx_flag(dir);
+       ext3_mark_inode_dirty(handle, dir);
+       d_instantiate(dentry, inode);
+@@ -1761,10 +1766,11 @@
+                       }
+                       de = (struct ext3_dir_entry_2 *) bh->b_data;
+               }
+-              if (!ext3_check_dir_entry ("empty_dir", inode, de, bh,
+-                                         offset)) {
+-                      brelse (bh);
+-                      return 1;
++              if (!ext3_check_dir_entry("empty_dir", inode, de, bh, offset)) {
++                      /* On error skip the de and offset to the next block. */
++                      de = (void *)(bh->b_data + sb->s_blocksize);
++                      offset = (offset | (sb->s_blocksize - 1)) + 1;
++                      continue;
+               }
+               if (le32_to_cpu(de->inode)) {
+                       brelse (bh);
+@@ -1957,14 +1963,14 @@
+       retval = ext3_delete_entry(handle, dir, de, bh);
+       if (retval)
+               goto end_rmdir;
+-      if (inode->i_nlink != 2)
+-              ext3_warning (inode->i_sb, "ext3_rmdir",
+-                            "empty directory has nlink!=2 (%d)",
+-                            inode->i_nlink);
++      if (!EXT3_DIR_LINK_EMPTY(inode))
++              ext3_warning(inode->i_sb, __FUNCTION__,
++                           "empty directory has too many links (%d)",
++                           inode->i_nlink);
+       inode->i_version = ++event;
+       inode->i_nlink = 0;
+       ext3_orphan_add(handle, inode);
+-      dir->i_nlink--;
++      ext3_dec_count(handle, dir);
+       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       ext3_mark_inode_dirty(handle, inode);
+       ext3_update_dx_flag(dir);
+@@ -2046,7 +2052,7 @@
+       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       ext3_update_dx_flag(dir);
+       ext3_mark_inode_dirty(handle, dir);
+-      inode->i_nlink--;
++      ext3_dec_count(handle, inode);
+       if (!inode->i_nlink) {
+               ext3_try_to_delay_deletion(inode);
+               ext3_orphan_add(handle, inode);
+@@ -2140,9 +2146,8 @@
+       if (S_ISDIR(inode->i_mode))
+               return -EPERM;
+-      if (inode->i_nlink >= EXT3_LINK_MAX) {
++      if (EXT3_DIR_LINK_MAXED(inode))
+               return -EMLINK;
+-      }
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+                                       EXT3_INDEX_EXTRA_TRANS_BLOCKS);
+@@ -2226,8 +2231,8 @@
+               if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
+                       goto end_rename;
+               retval = -EMLINK;
+-              if (!new_inode && new_dir!=old_dir &&
+-                              new_dir->i_nlink >= EXT3_LINK_MAX)
++              if (!new_inode && new_dir != old_dir &&
++                  EXT3_DIR_LINK_MAXED(new_dir))
+                       goto end_rename;
+       }
+       if (!new_bh) {
+@@ -2285,7 +2290,7 @@
+       }
+       if (new_inode) {
+-              new_inode->i_nlink--;
++              ext3_dec_count(handle, new_inode);
+               new_inode->i_ctime = CURRENT_TIME;
+       }
+       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+@@ -2296,11 +2301,11 @@
+               PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino);
+               BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
+               ext3_journal_dirty_metadata(handle, dir_bh);
+-              old_dir->i_nlink--;
++              ext3_dec_count(handle, old_dir);
+               if (new_inode) {
+-                      new_inode->i_nlink--;
++                      ext3_dec_count(handle, new_inode);
+               } else {
+-                      new_dir->i_nlink++;
++                      ext3_inc_count(handle, new_dir);
+                       ext3_update_dx_flag(new_dir);
+                       ext3_mark_inode_dirty(handle, new_dir);
+               }
+--- ./include/linux/ext3_fs.h.orig     2004-08-19 12:53:52.000000000 +0800
++++ ./include/linux/ext3_fs.h  2004-08-19 11:06:33.000000000 +0800
+@@ -42,7 +42,7 @@
+ /*
+  * Always enable hashed directories
+  */
+-#define CONFIG_EXT3_INDEX
++#define CONFIG_EXT3_INDEX 1
+ /*
+  * Debug code
+@@ -581,14 +581,15 @@
+  */
+ #ifdef CONFIG_EXT3_INDEX
+-  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
+-                                            EXT3_FEATURE_COMPAT_DIR_INDEX) && \
++#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
++                                          EXT3_FEATURE_COMPAT_DIR_INDEX) && \
+                     (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
+-#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
+-#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
++#define EXT3_DIR_LINK_MAXED(dir) (!is_dx(dir) && (dir)->i_nlink >=EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || \
++                                (is_dx(dir) && (dir)->i_nlink == 1))
+ #else
+   #define is_dx(dir) 0
+-#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_MAXED(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
+ #define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
+ #endif
diff --git a/lustre/tests/rmdirmany.c b/lustre/tests/rmdirmany.c
new file mode 100755 (executable)
index 0000000..d0c663a
--- /dev/null
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int main(int argc, char ** argv)
+{
+        int i, rc = 0, count;
+        char dirname[4096];
+
+        if (argc < 3) {
+                printf("Usage %s dirnamebase count\n", argv[0]);
+                return 1;
+        }
+
+        if (strlen(argv[1]) > 4080) {
+                printf("name too long\n");
+                return 1;
+        }
+
+        count = strtoul(argv[2], NULL, 0);
+
+        for (i = 0; i < count; i++) {
+                sprintf(dirname, "%s-%d", argv[1], i);
+                rc = rmdir(dirname);
+                if (rc) {
+                        printf("rmdir(%s) error: %s\n",
+                               dirname, strerror(errno));
+                        break;
+                }
+               if ((i % 10000) == 0)
+                   printf(" - deleted %d (time %ld)\n", i, time(0));
+        }
+        return rc;
+}