Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-mds-num-2.4.24.patch
diff --git a/lustre/kernel_patches/patches/ext3-mds-num-2.4.24.patch b/lustre/kernel_patches/patches/ext3-mds-num-2.4.24.patch
new file mode 100644 (file)
index 0000000..35aa918
--- /dev/null
@@ -0,0 +1,285 @@
+Index: linux-2.4.24/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.24.orig/fs/ext3/namei.c  2004-03-01 19:42:04.000000000 +0300
++++ linux-2.4.24/fs/ext3/namei.c       2004-03-29 19:27:13.000000000 +0400
+@@ -1100,6 +1100,23 @@
+       inode = NULL;
+       if (bh) {
+               unsigned long ino = le32_to_cpu(de->inode);
++              unsigned type = de->file_type;
++              __u32 *mds;
++              mds = (__u32 *)((char *) de + EXT3_DIR_REC_LEN(de->name_len));
++                if ((type & 128) && EXT3_HAS_INCOMPAT_FEATURE(dir->i_sb,
++                              EXT3_FEATURE_INCOMPAT_MDSNUM) &&
++                              mds[0] != EXT3_SB(dir->i_sb)->s_mdsnum) {
++                      struct ext3_super_block *es;
++                      es = EXT3_SB(dir->i_sb)->s_es;
++                      ext3_unlock_htree(dir, lock);
++                      brelse (bh);
++                      dentry->d_flags |= DCACHE_CROSS_REF;
++                      dentry->d_generation = mds[1];
++                      dentry->d_mdsnum = mds[0];
++                      dentry->d_inum = ino;
++                      d_add(dentry, NULL);
++                      return NULL;
++              }
+               ext3_unlock_htree(dir, lock);
+               brelse (bh);
+               inode = iget(dir->i_sb, ino);
+@@ -1160,7 +1177,7 @@
+       while (count--) {
+               struct ext3_dir_entry_2 *de =
+                       (struct ext3_dir_entry_2 *) (from + map->offs);
+-              rec_len = EXT3_DIR_REC_LEN(de->name_len);
++              rec_len = EXT3_DIR_REC_LEN_DE(de);
+               memcpy (to, de, rec_len);
+               ((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
+               de->inode = 0;
+@@ -1181,7 +1198,7 @@
+               next = (struct ext3_dir_entry_2 *) ((char *) de +
+                                                   le16_to_cpu(de->rec_len));
+               if (de->inode && de->name_len) {
+-                      rec_len = EXT3_DIR_REC_LEN(de->name_len);
++                      rec_len = EXT3_DIR_REC_LEN_DE(de);
+                       if (de > to)
+                               memmove(to, de, rec_len);
+                       to->rec_len = rec_len;
+@@ -1297,6 +1314,7 @@
+                            struct buffer_head * bh)
+ {
+       struct inode    *dir = dentry->d_parent->d_inode;
++      struct super_block *sb = dir->i_sb;
+       const char      *name = dentry->d_name.name;
+       int             namelen = dentry->d_name.len;
+       unsigned long   offset = 0;
+@@ -1305,6 +1323,10 @@
+       char            *top;
+       
+       reclen = EXT3_DIR_REC_LEN(namelen);
++        if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
++                      && (dentry->d_flags & DCACHE_CROSS_REF)
++                      && (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum))
++              reclen += 8; /* we need space to store mds num */
+       if (!de) {
+               de = (struct ext3_dir_entry_2 *)bh->b_data;
+               top = bh->b_data + dir->i_sb->s_blocksize - reclen;
+@@ -1318,7 +1340,7 @@
+                               brelse (bh);
+                               return -EEXIST;
+                       }
+-                      nlen = EXT3_DIR_REC_LEN(de->name_len);
++                      nlen = EXT3_DIR_REC_LEN_DE(de);
+                       rlen = le16_to_cpu(de->rec_len);
+                       if ((de->inode? rlen - nlen: rlen) >= reclen)
+                               break;
+@@ -1337,7 +1359,7 @@
+       }
+       
+       /* By now the buffer is marked for journaling */
+-      nlen = EXT3_DIR_REC_LEN(de->name_len);
++      nlen = EXT3_DIR_REC_LEN_DE(de);
+       rlen = le16_to_cpu(de->rec_len);
+       if (de->inode) {
+               struct ext3_dir_entry_2 *de1 =
+@@ -1349,8 +1371,20 @@
+       de->file_type = EXT3_FT_UNKNOWN;
+       if (inode) {
+               de->inode = cpu_to_le32(inode->i_ino);
+-              ext3_set_de_type(dir->i_sb, de, inode->i_mode);
+-      } else
++              ext3_set_de_type(sb, de, inode->i_mode);
++      } else if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
++                      && (dentry->d_flags & DCACHE_CROSS_REF)) {
++              if (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum) {
++                      __u32 *mds;
++                      mds = (__u32 *)((char *)de + EXT3_DIR_REC_LEN(namelen));
++                      mds[0] = cpu_to_le32(dentry->d_mdsnum);
++                      mds[1] = cpu_to_le32(dentry->d_generation);
++                      de->inode = cpu_to_le32(dentry->d_inum);
++                      de->file_type = 128;
++              } else {
++                      de->inode = cpu_to_le32(dentry->d_inum);
++              }
++      } else 
+               de->inode = 0;
+       de->name_len = namelen;
+       memcpy (de->name, name, namelen);
+@@ -2662,6 +2696,77 @@
+ }
+ /*
++ * caller has to make sure directory is protected
++ */
++int ext3_add_dir_entry(struct dentry *dentry)
++{
++      struct inode *dir = dentry->d_parent->d_inode;
++      handle_t *handle;
++      int err;
++
++      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS);
++      if (IS_ERR(handle)) {
++              return PTR_ERR(handle);
++      }
++
++      if (IS_SYNC(dir))
++              handle->h_sync = 1;
++
++      err = ext3_add_entry(handle, dentry, NULL);
++      ext3_journal_stop(handle, dir);
++      return err;
++}
++
++/*
++ * caller has to make sure directory is protected
++ */
++int ext3_del_dir_entry(struct dentry *dentry)
++{
++      struct inode * inode;
++      struct inode * dir = dentry->d_parent->d_inode;
++      struct buffer_head * bh;
++      struct ext3_dir_entry_2 * de;
++      handle_t *handle;
++      void *lock;
++      int retval;
++
++      handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
++      if (IS_ERR(handle)) {
++              return PTR_ERR(handle);
++      }
++
++      if (IS_SYNC(dir))
++              handle->h_sync = 1;
++
++      retval = -ENOENT;
++      bh = ext3_find_entry (dentry, &de, 1, &lock);
++      if (!bh)
++              goto end_unlink;
++
++      inode = dentry->d_inode;
++      if (inode)
++              DQUOT_INIT(inode);
++
++      retval = ext3_delete_entry(handle, dir, de, bh);
++      ext3_unlock_htree(dir, lock);
++      if (retval)
++              goto end_unlink;
++      dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++      ext3_update_dx_flag(dir);
++      ext3_mark_inode_dirty(handle, dir);
++      if (inode) {
++              inode->i_ctime = dir->i_ctime;
++              ext3_mark_inode_dirty(handle, inode);
++      }
++      retval = 0;
++
++end_unlink:
++      ext3_journal_stop(handle, dir);
++      brelse (bh);
++      return retval;
++}
++/*
+  * directories can handle most operations...
+  */
+ struct inode_operations ext3_dir_inode_operations = {
+Index: linux-2.4.24/fs/ext3/dir.c
+===================================================================
+--- linux-2.4.24.orig/fs/ext3/dir.c    2004-03-01 19:20:49.000000000 +0300
++++ linux-2.4.24/fs/ext3/dir.c 2004-03-01 19:42:15.000000000 +0300
+@@ -42,6 +42,9 @@
+ static unsigned char get_dtype(struct super_block *sb, int filetype)
+ {
++      if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM))
++              return DT_UNKNOWN;
++
+       if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
+           (filetype >= EXT3_FT_MAX))
+               return DT_UNKNOWN;
+Index: linux-2.4.24/fs/ext3/ext3-exports.c
+===================================================================
+--- linux-2.4.24.orig/fs/ext3/ext3-exports.c   2004-03-01 19:20:50.000000000 +0300
++++ linux-2.4.24/fs/ext3/ext3-exports.c        2004-03-11 23:40:49.000000000 +0300
+@@ -26,3 +26,10 @@
+ EXPORT_SYMBOL(ext3_decode_error);
+ EXPORT_SYMBOL(__ext3_std_error);
++int ext3_add_dir_entry (struct dentry *dentry);
++EXPORT_SYMBOL(ext3_add_dir_entry);
++int ext3_del_dir_entry(struct dentry *dentry);
++EXPORT_SYMBOL(ext3_del_dir_entry);
++
++
++
+Index: linux-2.4.24/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.24.orig/include/linux/ext3_fs.h  2004-03-01 19:42:04.000000000 +0300
++++ linux-2.4.24/include/linux/ext3_fs.h       2004-03-01 19:42:15.000000000 +0300
+@@ -431,7 +431,8 @@
+       __u8    s_def_hash_version;     /* Default hash version to use */
+       __u8    s_reserved_char_pad;
+       __u16   s_reserved_word_pad;
+-      __u32   s_reserved[192];        /* Padding to the end of the block */
++      __u32   s_mdsnum;
++      __u32   s_reserved[191];        /* Padding to the end of the block */
+ };
+ #ifdef __KERNEL__
+@@ -504,10 +505,12 @@
+ #define EXT3_FEATURE_INCOMPAT_FILETYPE                0x0002
+ #define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
++#define EXT3_FEATURE_INCOMPAT_MDSNUM          0x0010 /* direntry has mdsnum */
+ #define EXT3_FEATURE_COMPAT_SUPP      EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT3_FEATURE_INCOMPAT_SUPP    (EXT3_FEATURE_INCOMPAT_FILETYPE| \
+-                                       EXT3_FEATURE_INCOMPAT_RECOVER)
++                                       EXT3_FEATURE_INCOMPAT_RECOVER| \
++                                       EXT3_FEATURE_INCOMPAT_MDSNUM)
+ #define EXT3_FEATURE_RO_COMPAT_SUPP   (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+                                        EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
+                                        EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
+@@ -568,6 +571,9 @@
+ #define EXT3_DIR_ROUND                        (EXT3_DIR_PAD - 1)
+ #define EXT3_DIR_REC_LEN(name_len)    (((name_len) + 8 + EXT3_DIR_ROUND) & \
+                                        ~EXT3_DIR_ROUND)
++#define EXT3_DIR_REC_LEN_DE(de)       (EXT3_DIR_REC_LEN((de)->name_len) + \
++                                      (((de)->file_type & 128) ? 8 : 0))
++
+ /*
+  * Hash Tree Directory indexing
+  * (c) Daniel Phillips, 2001
+Index: linux-2.4.24/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.24.orig/include/linux/ext3_fs_sb.h       2004-03-01 19:20:49.000000000 +0300
++++ linux-2.4.24/include/linux/ext3_fs_sb.h    2004-03-01 19:42:21.000000000 +0300
+@@ -86,6 +86,7 @@
+       wait_queue_head_t s_delete_thread_queue;
+       wait_queue_head_t s_delete_waiter_queue;
+ #endif
++      u32 s_mdsnum;
+ };
+ #endif        /* _LINUX_EXT3_FS_SB */
+Index: linux-2.4.24/include/linux/dcache.h
+===================================================================
+--- linux-2.4.24.orig/include/linux/dcache.h   2004-03-01 19:20:49.000000000 +0300
++++ linux-2.4.24/include/linux/dcache.h        2004-03-01 19:42:15.000000000 +0300
+@@ -118,6 +118,9 @@
+       atomic_t d_count;
+       unsigned int d_flags;
+       struct inode  * d_inode;        /* Where the name belongs to - NULL is negative */
++      unsigned d_inum;                /* for cross-fs references (Lustre) */
++      unsigned d_mdsnum;              /* for cross-fs references (Lustre) */
++      unsigned d_generation;          /* for cross-fs references (Lustre) */
+       struct dentry * d_parent;       /* parent directory */
+       struct list_head d_hash;        /* lookup hash list */
+       struct list_head d_lru;         /* d_count = 0 LRU list */
+@@ -189,6 +192,7 @@
+                                        */
+ #define DCACHE_REFERENCED     0x0008  /* Recently used, don't discard. */
+ #define DCACHE_LUSTRE_INVALID 0x0010  /* Lustre invalidated */
++#define DCACHE_CROSS_REF      0x0020  /* entry points to inode on another MDS */
+ extern spinlock_t dcache_lock;