Whamcloud - gitweb
b=20298 (Merge head ldiskfs and b1_8 ldiskfs)
authordeshmukh <deshmukh>
Thu, 27 Aug 2009 06:47:04 +0000 (06:47 +0000)
committerdeshmukh <deshmukh>
Thu, 27 Aug 2009 06:47:04 +0000 (06:47 +0000)
i=adilger
i=girish

This is related to unifying the ldiskfs branch between b1_8 and HEAD.
For that adding the patches to series files which is required for HEAD.
Also some other changes required in makefile and config file.

23 files changed:
ldiskfs/kernel_patches/patches/ext3-dynlocks-2.6-rhel5.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext3-dynlocks-common.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext3-extents-2.6.16-sles10.patch
ldiskfs/kernel_patches/patches/ext3-hash-indexed-dir-dotdot-update.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext3-mballoc3-sles10.patch
ldiskfs/kernel_patches/patches/ext3-nlinks-2.6.9.patch
ldiskfs/kernel_patches/patches/ext3-osd-iam-exports.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext3-pdir-fix.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-dynlocks-2.6-rhel5.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-dynlocks-common-sles11.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-dynlocks-common.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-osd-iam-exports.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-osd-iop-common-sles11.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-pdir-fix.patch [new file with mode: 0644]
ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series
ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series
ldiskfs/kernel_patches/series/ldiskfs-2.6-sles10.series
ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series
ldiskfs/ldiskfs/Makefile.in
ldiskfs/ldiskfs/autoMakefile.am

diff --git a/ldiskfs/kernel_patches/patches/ext3-dynlocks-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext3-dynlocks-2.6-rhel5.patch
new file mode 100644 (file)
index 0000000..85064da
--- /dev/null
@@ -0,0 +1,33 @@
+diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/Makefile linux-2.6.18-128.1.6_2/fs/ext3/Makefile
+--- linux-2.6.18-128.1.6_1/fs/ext3/Makefile    2009-08-13 19:19:54.000000000 +0530
++++ linux-2.6.18-128.1.6_2/fs/ext3/Makefile    2009-08-13 19:20:30.000000000 +0530
+@@ -5,7 +5,8 @@
+ obj-$(CONFIG_EXT3_FS) += ext3.o
+ ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+-         ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o mballoc.o
++         ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
++         mballoc.o dynlocks.o
+ ext3-$(CONFIG_EXT3_FS_XATTR)   += xattr.o xattr_user.o xattr_trusted.o
+ ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
+diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/super.c linux-2.6.18-128.1.6_2/fs/ext3/super.c
+--- linux-2.6.18-128.1.6_1/fs/ext3/super.c     2009-08-13 19:19:54.000000000 +0530
++++ linux-2.6.18-128.1.6_2/fs/ext3/super.c     2009-08-13 19:23:23.000000000 +0530
+@@ -3529,6 +3530,7 @@ static int __init init_ext3_fs(void)
+       err = init_inodecache();
+       if (err)
+               goto out1;
++      dynlock_cache_init();
+         err = register_filesystem(&ext3_fs_type);
+       if (err)
+               goto out;
+@@ -3546,6 +3548,7 @@ out1:
+ static void __exit exit_ext3_fs(void)
+ {
+       unregister_filesystem(&ext3_fs_type);
++      dynlock_cache_exit();
+       destroy_inodecache();
+       exit_ext3_xattr();
+       exit_ext3_proc();
+
diff --git a/ldiskfs/kernel_patches/patches/ext3-dynlocks-common.patch b/ldiskfs/kernel_patches/patches/ext3-dynlocks-common.patch
new file mode 100644 (file)
index 0000000..73b0c87
--- /dev/null
@@ -0,0 +1,278 @@
+diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/dynlocks.c linux-2.6.18-128.1.6_2/fs/ext3/dynlocks.c
+--- linux-2.6.18-128.1.6_1/fs/ext3/dynlocks.c  1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.18-128.1.6_2/fs/ext3/dynlocks.c  2009-08-13 20:42:59.000000000 +0530
+@@ -0,0 +1,236 @@
++/*
++ * Dynamic Locks
++ *
++ * struct dynlock is lockspace
++ * one may request lock (exclusive or shared) for some value
++ * in that lockspace
++ *
++ */
++
++#include <linux/dynlocks.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++
++#define DYNLOCK_HANDLE_MAGIC  0xd19a10c
++#define DYNLOCK_HANDLE_DEAD   0xd1956ee
++#define DYNLOCK_LIST_MAGIC    0x11ee91e6
++
++static kmem_cache_t * dynlock_cachep = NULL;
++
++struct dynlock_handle {
++      unsigned                dh_magic;
++      struct list_head        dh_list;
++      unsigned long           dh_value;       /* lock value */
++      int                     dh_refcount;    /* number of users */
++      int                     dh_readers;
++      int                     dh_writers;
++      int                     dh_pid;         /* holder of the lock */
++      wait_queue_head_t       dh_wait;
++};
++
++int __init dynlock_cache_init(void)
++{
++      int rc = 0;
++
++      printk(KERN_INFO "init dynlocks cache\n");
++      dynlock_cachep = kmem_cache_create("dynlock_cache",
++                                       sizeof(struct dynlock_handle),
++                                       0,
++                                       SLAB_HWCACHE_ALIGN,
++                                       NULL, NULL);
++      if (dynlock_cachep == NULL) {
++              printk(KERN_ERR "Not able to create dynlock cache");
++              rc = -ENOMEM;
++      }
++      return rc;
++}
++
++void __exit dynlock_cache_exit(void)
++{
++      printk(KERN_INFO "exit dynlocks cache\n");
++      kmem_cache_destroy(dynlock_cachep);
++}
++
++/*
++ * dynlock_init
++ *
++ * initialize lockspace
++ *
++ */
++void dynlock_init(struct dynlock *dl)
++{
++      spin_lock_init(&dl->dl_list_lock);
++      INIT_LIST_HEAD(&dl->dl_list);
++      dl->dl_magic = DYNLOCK_LIST_MAGIC;
++}
++EXPORT_SYMBOL(dynlock_init);
++
++/*
++ * dynlock_lock
++ *
++ * acquires lock (exclusive or shared) in specified lockspace
++ * each lock in lockspace is allocated separately, so user have
++ * to specify GFP flags.
++ * routine returns pointer to lock. this pointer is intended to
++ * be passed to dynlock_unlock
++ *
++ */
++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value,
++                                  enum dynlock_type lt, gfp_t gfp)
++{
++      struct dynlock_handle *nhl = NULL;
++      struct dynlock_handle *hl;
++
++      BUG_ON(dl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++
++repeat:
++      /* find requested lock in lockspace */
++      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl->dl_list.next == NULL);
++      BUG_ON(dl->dl_list.prev == NULL);
++      list_for_each_entry(hl, &dl->dl_list, dh_list) {
++              BUG_ON(hl->dh_list.next == NULL);
++              BUG_ON(hl->dh_list.prev == NULL);
++              BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++              if (hl->dh_value == value) {
++                      /* lock is found */
++                      if (nhl) {
++                              /* someone else just allocated
++                               * lock we didn't find and just created
++                               * so, we drop our lock
++                               */
++                              kmem_cache_free(dynlock_cachep, nhl);
++                              nhl = NULL;
++                      }
++                      hl->dh_refcount++;
++                      goto found;
++              }
++      }
++      /* lock not found */
++      if (nhl) {
++              /* we already have allocated lock. use it */
++              hl = nhl;
++              nhl = NULL;
++              list_add(&hl->dh_list, &dl->dl_list);
++              goto found;
++      }
++      spin_unlock(&dl->dl_list_lock);
++      
++      /* lock not found and we haven't allocated lock yet. allocate it */
++      nhl = kmem_cache_alloc(dynlock_cachep, gfp);
++      if (nhl == NULL)
++              return NULL;
++      nhl->dh_refcount = 1;
++      nhl->dh_value = value;
++      nhl->dh_readers = 0;
++      nhl->dh_writers = 0;
++      nhl->dh_magic = DYNLOCK_HANDLE_MAGIC;
++      init_waitqueue_head(&nhl->dh_wait);
++
++      /* while lock is being allocated, someone else may allocate it
++       * and put onto to list. check this situation
++       */
++      goto repeat;
++
++found:
++      if (lt == DLT_WRITE) {
++              /* exclusive lock: user don't want to share lock at all
++               * NOTE: one process may take the same lock several times
++               * this functionaly is useful for rename operations */
++              while ((hl->dh_writers && hl->dh_pid != current->pid) ||
++                              hl->dh_readers) {
++                      spin_unlock(&dl->dl_list_lock);
++                      wait_event(hl->dh_wait,
++                              hl->dh_writers == 0 && hl->dh_readers == 0);
++                      spin_lock(&dl->dl_list_lock);
++              }
++              hl->dh_writers++;
++      } else {
++              /* shared lock: user do not want to share lock with writer */
++              while (hl->dh_writers) {
++                      spin_unlock(&dl->dl_list_lock);
++                      wait_event(hl->dh_wait, hl->dh_writers == 0);
++                      spin_lock(&dl->dl_list_lock);
++              }
++              hl->dh_readers++;
++      }
++      hl->dh_pid = current->pid;
++      spin_unlock(&dl->dl_list_lock);
++
++      return hl;
++}
++EXPORT_SYMBOL(dynlock_lock);
++
++
++/*
++ * dynlock_unlock
++ *
++ * user have to specify lockspace (dl) and pointer to lock structure
++ * returned by dynlock_lock()
++ *
++ */
++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *hl)
++{
++      int wakeup = 0;
++      
++      BUG_ON(dl == NULL);
++      BUG_ON(hl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++
++      if (hl->dh_magic != DYNLOCK_HANDLE_MAGIC)
++              printk(KERN_EMERG "wrong lock magic: %#x\n", hl->dh_magic);
++
++      BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++      BUG_ON(hl->dh_writers != 0 && current->pid != hl->dh_pid);
++
++      spin_lock(&dl->dl_list_lock);
++      if (hl->dh_writers) {
++              BUG_ON(hl->dh_readers != 0);
++              hl->dh_writers--;
++              if (hl->dh_writers == 0)
++                      wakeup = 1;
++      } else if (hl->dh_readers) {
++              hl->dh_readers--;
++              if (hl->dh_readers == 0)
++                      wakeup = 1;
++      } else {
++              BUG();
++      }
++      if (wakeup) {
++              hl->dh_pid = 0;
++              wake_up(&hl->dh_wait);
++      }
++      if (--(hl->dh_refcount) == 0) {
++              hl->dh_magic = DYNLOCK_HANDLE_DEAD;
++              list_del(&hl->dh_list);
++              kmem_cache_free(dynlock_cachep, hl);
++      }
++      spin_unlock(&dl->dl_list_lock);
++}
++EXPORT_SYMBOL(dynlock_unlock);
++
++int dynlock_is_locked(struct dynlock *dl, unsigned long value)
++{
++      struct dynlock_handle *hl;
++      int result = 0;
++
++      /* find requested lock in lockspace */
++      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl->dl_list.next == NULL);
++      BUG_ON(dl->dl_list.prev == NULL);
++      list_for_each_entry(hl, &dl->dl_list, dh_list) {
++              BUG_ON(hl->dh_list.next == NULL);
++              BUG_ON(hl->dh_list.prev == NULL);
++              BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++              if (hl->dh_value == value && hl->dh_pid == current->pid) {
++                      /* lock is found */
++                      result = 1;
++                      break;
++              }
++      }
++      spin_unlock(&dl->dl_list_lock);
++      return result;
++}
++EXPORT_SYMBOL(dynlock_is_locked);
+diff -rupN linux-2.6.18-128.1.6_1/include/linux/dynlocks.h linux-2.6.18-128.1.6_2/include/linux/dynlocks.h
+--- linux-2.6.18-128.1.6_1/include/linux/dynlocks.h    1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.18-128.1.6_2/include/linux/dynlocks.h    2009-08-13 20:43:18.000000000 +0530
+@@ -0,0 +1,34 @@
++#ifndef _LINUX_DYNLOCKS_H
++#define _LINUX_DYNLOCKS_H
++
++#include <linux/list.h>
++#include <linux/wait.h>
++
++struct dynlock_handle;
++
++/*
++ * lock's namespace:
++ *   - list of locks
++ *   - lock to protect this list
++ */
++struct dynlock {
++      unsigned                dl_magic;
++      struct list_head        dl_list;
++      spinlock_t              dl_list_lock;
++};
++
++enum dynlock_type {
++      DLT_WRITE,
++      DLT_READ
++};
++
++int dynlock_cache_init(void);
++void dynlock_cache_exit(void);
++void dynlock_init(struct dynlock *dl);
++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value,
++                                  enum dynlock_type lt, gfp_t gfp);
++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *lock);
++int dynlock_is_locked(struct dynlock *dl, unsigned long value);
++
++#endif
++
index bbccd36..5b363ea 100644 (file)
@@ -2395,17 +2395,16 @@ Index: linux-2.6.16.54-0.2.5/fs/ext3/inode.c
        if (ext3_should_journal_data(inode))
                ret = 3 * (bpp + indirects) + 2;
        else
-Index: linux-2.6.16.54-0.2.5/fs/ext3/Makefile
+Index: linux-2.6.18.8/fs/ext3/Makefile
 ===================================================================
---- linux-2.6.16.54-0.2.5.orig/fs/ext3/Makefile
-+++ linux-2.6.16.54-0.2.5/fs/ext3/Makefile
-@@ -5,7 +5,8 @@
+--- linux-2.6.18.8.orig/fs/ext3/Makefile       2007-07-17 09:18:11.000000000 +0200
++++ linux-2.6.18.8/fs/ext3/Makefile    2007-07-17 11:08:11.000000000 +0200
+@@ -5,7 +5,7 @@
  obj-$(CONFIG_EXT3_FS) += ext3.o
  
  ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
 -         ioctl.o namei.o super.o symlink.o hash.o resize.o
-+         ioctl.o namei.o super.o symlink.o hash.o resize.o \
-+         extents.o
++         ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o
  
  ext3-$(CONFIG_EXT3_FS_XATTR)   += xattr.o xattr_user.o xattr_trusted.o
  ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
diff --git a/ldiskfs/kernel_patches/patches/ext3-hash-indexed-dir-dotdot-update.patch b/ldiskfs/kernel_patches/patches/ext3-hash-indexed-dir-dotdot-update.patch
new file mode 100644 (file)
index 0000000..a817045
--- /dev/null
@@ -0,0 +1,87 @@
+Index: linux-stage/fs/ext3/namei.c
+===================================================================
+--- linux-stage.orig/fs/ext3/namei.c   2009-08-10 22:31:03.000000000 +0800
++++ linux-stage/fs/ext3/namei.c        2009-08-10 22:33:38.000000000 +0800
+@@ -1471,6 +1471,72 @@
+ }
+ #endif
++/* update ".." for hash-indexed directory, split the item "." if necessary */
++static int ext3_update_dotdot(handle_t *handle, struct dentry *dentry,
++                               struct inode *inode)
++{
++      struct inode * dir = dentry->d_parent->d_inode;
++      struct buffer_head * dir_block;
++      struct ext3_dir_entry_2 * de;
++      int len, journal = 0, err = 0;
++
++      if (IS_ERR(handle))
++              return PTR_ERR(handle);
++
++      if (IS_DIRSYNC(dir))
++              handle->h_sync = 1;
++
++      dir_block = ext3_bread(handle, dir, 0, 0, &err);
++      if (!dir_block)
++              goto out;
++
++      de = (struct ext3_dir_entry_2 *)dir_block->b_data;
++      /* the first item must be "." */
++      assert(de->name_len == 1 && de->name[0] == '.');
++      len = le16_to_cpu(de->rec_len);
++      assert(len >= EXT3_DIR_REC_LEN(1));
++      if (len > EXT3_DIR_REC_LEN(1)) {
++              BUFFER_TRACE(dir_block, "get_write_access");
++              err = ext3_journal_get_write_access(handle, dir_block);
++              if (err)
++                      goto out_journal;
++
++              journal = 1;
++              de->rec_len = cpu_to_le16(EXT3_DIR_REC_LEN(1));
++      }
++
++      len -= EXT3_DIR_REC_LEN(1);
++      assert(len == 0 || len >= EXT3_DIR_REC_LEN(2));
++      de = (struct ext3_dir_entry_2 *)
++                      ((char *) de + le16_to_cpu(de->rec_len));
++      if (!journal) {
++              BUFFER_TRACE(dir_block, "get_write_access");
++              err = ext3_journal_get_write_access(handle, dir_block);
++              if (err)
++                      goto out_journal;
++      }
++
++      de->inode = cpu_to_le32(inode->i_ino);
++      if (len > 0)
++              de->rec_len = cpu_to_le16(len);
++      else
++              assert(le16_to_cpu(de->rec_len) >= EXT3_DIR_REC_LEN(2));
++      de->name_len = 2;
++      strcpy (de->name, "..");
++      ext3_set_de_type(dir->i_sb, de, S_IFDIR);
++
++out_journal:
++      if (journal) {
++              BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
++              err = ext3_journal_dirty_metadata(handle, dir_block);
++              ext3_mark_inode_dirty(handle, dir);
++      }
++      brelse (dir_block);
++
++out:
++      return err;
++}
++
+ /*
+  *    ext3_add_entry()
+  *
+@@ -1502,6 +1568,9 @@
+               return -EINVAL;
+ #ifdef CONFIG_EXT3_INDEX
+       if (is_dx(dir)) {
++              if (dentry->d_name.len == 2 &&
++                  memcmp(dentry->d_name.name, "..", 2) == 0)
++                      return ext3_update_dotdot(handle, dentry, inode);
+               retval = ext3_dx_add_entry(handle, dentry, inode);
+               if (!retval || (retval != ERR_BAD_DX_DIR))
+                       return retval;
index 88be686..655e4bb 100644 (file)
@@ -243,16 +243,16 @@ Index: linux-2.6.16.46-0.14/fs/ext3/extents.c
        /* 
         * TODO: optimization is possible here
         * probably we need not scaning at all,
-Index: linux-2.6.16.46-0.14/fs/ext3/Makefile
+Index: linux-2.6.18.8/fs/ext3/Makefile
 ===================================================================
---- linux-2.6.16.46-0.14.orig/fs/ext3/Makefile
-+++ linux-2.6.16.46-0.14/fs/ext3/Makefile
-@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
+--- linux-2.6.18.8.orig/fs/ext3/Makefile
++++ linux-2.6.18.8/fs/ext3/Makefile
+@@ -5,7 +5,7 @@
+ obj-$(CONFIG_EXT3_FS) += ext3.o
  
  ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
-          ioctl.o namei.o super.o symlink.o hash.o resize.o \
--         extents.o
-+         extents.o mballoc.o
+-         ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o
++         ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o mballoc.o
  
  ext3-$(CONFIG_EXT3_FS_XATTR)   += xattr.o xattr_user.o xattr_trusted.o
  ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
index fb32a64..50ff2e1 100644 (file)
@@ -30,6 +30,15 @@ Index: linux-2.6.12/fs/ext3/namei.c
                return -EMLINK;
  
  retry:
+@@ -1782,7 +1793,7 @@ retry:
+       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? */
++              drop_nlink(inode); /* is this nlink == 0? */
+               ext3_mark_inode_dirty(handle, inode);
+               iput (inode);
+               goto out_stop;
 @@ -1758,7 +1764,7 @@ retry:
                iput (inode);
                goto out_stop;
diff --git a/ldiskfs/kernel_patches/patches/ext3-osd-iam-exports.patch b/ldiskfs/kernel_patches/patches/ext3-osd-iam-exports.patch
new file mode 100644 (file)
index 0000000..aecab61
--- /dev/null
@@ -0,0 +1,65 @@
+Index: linux-2.6.16.60-0.33_org/fs/ext3/hash.c
+===================================================================
+--- linux-2.6.16.60-0.33_org/fs/ext3/hash.c    2009-07-01 18:16:50.000000000 +0530
++++ linux-2.6.16.60-0.33_new/fs/ext3/hash.c    2009-07-01 18:26:58.000000000 +0530
+@@ -8,7 +8,7 @@
+  * This file may be redistributed under the terms of the GNU Public
+  * License.
+  */
+-
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/sched.h>
+@@ -173,3 +173,4 @@ int ext3fs_dirhash(const char *name, int
+       hinfo->minor_hash = minor_hash;
+       return 0;
+ }
++EXPORT_SYMBOL(ext3fs_dirhash);
+Index: linux-2.6.16.60-0.33_org/fs/ext3/namei.c
+===================================================================
+--- linux-2.6.16.60-0.33_org/fs/ext3/namei.c   2009-07-01 18:16:50.000000000 +0530
++++ linux-2.6.16.60-0.33_new/fs/ext3/namei.c   2009-07-01 18:24:49.000000000 +0530
+@@ -75,6 +75,7 @@ struct buffer_head *ext3_append(handle_t
+       return bh;
+ }
++EXPORT_SYMBOL(ext3_append);
+ #ifndef assert
+ #define assert(test) J_ASSERT(test)
+Index: linux-2.6.16.60-0.33_org/fs/ext3/super.c
+===================================================================
+--- linux-2.6.16.60-0.33_org/fs/ext3/super.c   2009-07-01 18:16:50.000000000 +0530
++++ linux-2.6.16.60-0.33_new/fs/ext3/super.c   2009-07-01 18:24:27.000000000 +0530
+@@ -260,6 +260,7 @@ void __ext3_std_error (struct super_bloc
+       ext3_handle_error(sb);
+ }
++EXPORT_SYMBOL(__ext3_std_error);
+ /*
+  * ext3_abort is a much stronger failure handler than ext3_error.  The
+Index: linux-2.6.16.60-0.33_org/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.6.16.60-0.33_org/include/linux/ext3_fs.h   2009-07-01 18:16:50.000000000 +0530
++++ linux-2.6.16.60-0.33_new/include/linux/ext3_fs.h   2009-07-01 18:22:09.000000000 +0530
+@@ -1055,6 +1055,8 @@ extern void ext3_abort (struct super_blo
+ extern void ext3_warning (struct super_block *, const char *, const char *, ...)
+       __attribute__ ((format (printf, 3, 4)));
+ extern void ext3_update_dynamic_rev (struct super_block *sb);
++extern void __ext3_std_error (struct super_block * sb, const char * function,
++                              int errno);
+ #define ext3_std_error(sb, errno)                             \
+ do {                                                          \
+@@ -1076,6 +1078,8 @@ extern struct file_operations ext3_file_
+ /* namei.c */
+ extern struct inode_operations ext3_dir_inode_operations;
+ extern struct inode_operations ext3_special_inode_operations;
++extern struct buffer_head *ext3_append(handle_t *handle, struct inode *inode,
++                                      u32 *block, int *err);
+ /* symlink.c */
+ extern struct inode_operations ext3_symlink_inode_operations;
+
diff --git a/ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch b/ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch
new file mode 100644 (file)
index 0000000..30a8184
--- /dev/null
@@ -0,0 +1,227 @@
+diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/namei.c linux-2.6.18-128.1.6_2/fs/ext3/namei.c
+--- linux-2.6.18-128.1.6_1/fs/ext3/namei.c     2009-08-13 19:07:07.000000000 +0530
++++ linux-2.6.18-128.1.6_2/fs/ext3/namei.c     2009-08-13 19:10:43.000000000 +0530
+@@ -24,6 +24,7 @@
+  *    Theodore Ts'o, 2002
+  */
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
+ #include <linux/jbd.h>
+@@ -841,7 +842,7 @@ static inline int search_dirblock(struct
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
+-static struct buffer_head * ext3_find_entry (struct dentry *dentry,
++struct buffer_head * ext3_find_entry (struct dentry *dentry,
+                                       struct ext3_dir_entry_2 ** res_dir)
+ {
+       struct super_block * sb;
+@@ -953,6 +954,7 @@ cleanup_and_exit:
+               brelse (bh_use[ra_ptr]);
+       return ret;
+ }
++EXPORT_SYMBOL(ext3_find_entry);
+ #ifdef CONFIG_EXT3_INDEX
+ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
+@@ -1489,7 +1491,7 @@ 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.
+  */
+-static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
++int ext3_add_entry (handle_t *handle, struct dentry *dentry,
+       struct inode *inode)
+ {
+       struct inode *dir = dentry->d_parent->d_inode;
+@@ -1542,6 +1544,7 @@ static int ext3_add_entry (handle_t *han
+       de->rec_len = cpu_to_le16(blocksize);
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+ }
++EXPORT_SYMBOL(ext3_add_entry);
+ #ifdef CONFIG_EXT3_INDEX
+ /*
+@@ -1684,10 +1687,10 @@ cleanup:
+  * ext3_delete_entry deletes a directory entry by merging it with the
+  * previous entry
+  */
+-static int ext3_delete_entry (handle_t *handle, 
+-                            struct inode * dir,
+-                            struct ext3_dir_entry_2 * de_del,
+-                            struct buffer_head * bh)
++int ext3_delete_entry (handle_t *handle,
++                      struct inode * dir,
++                      struct ext3_dir_entry_2 * de_del,
++                      struct buffer_head * bh)
+ {
+       struct ext3_dir_entry_2 * de, * pde;
+       int i;
+@@ -1719,6 +1722,7 @@ static int ext3_delete_entry (handle_t *
+       }
+       return -ENOENT;
+ }
++EXPORT_SYMBOL(ext3_delete_entry);
+ /*
+  * ext3_mark_inode_dirty is somewhat expensive, so unlike ext2 we
+@@ -1774,6 +1778,26 @@ static struct inode * ext3_new_inode_wan
+       return ext3_new_inode(handle, dir, mode, inum);
+ }
++struct inode * ext3_create_inode(handle_t *handle, struct inode * dir, int mode)
++{
++      struct inode *inode;
++
++      inode = ext3_new_inode(handle, dir, mode, 0);
++      if (!IS_ERR(inode)) {
++              if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
++#ifdef CONFIG_LDISKFS_FS_XATTR
++                      inode->i_op = &ext3_special_inode_operations;
++#endif
++              } else {
++                      inode->i_op = &ext3_file_inode_operations;
++                      inode->i_fop = &ext3_file_operations;
++                      ext3_set_aops(inode);
++              }
++      }
++      return inode;
++}
++EXPORT_SYMBOL(ext3_create_inode);
++
+ /*
+  * By the time this is called, we already have created
+  * the directory cache entry for the new file, but it
+@@ -1848,42 +1872,28 @@ retry:
+       return err;
+ }
+-static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
++/* Initialize @inode as a subdirectory of @dir, and add the
++ * "." and ".." entries into the first directory block. */
++int ext3_add_dot_dotdot(handle_t *handle, struct inode * dir,
++                       struct inode *inode)
+ {
+-      handle_t *handle;
+-      struct inode * inode;
+       struct buffer_head * dir_block;
+       struct ext3_dir_entry_2 * de;
+-      int err, retries = 0;
+-
+-      if (EXT3_DIR_LINK_MAX(dir))
+-              return -EMLINK;
++      int err = 0;
+-retry:
+-      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
+-                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+-                                      2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+-      inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+-      err = PTR_ERR(inode);
+-      if (IS_ERR(inode))
+-              goto out_stop;
+-
+       inode->i_op = &ext3_dir_inode_operations;
+       inode->i_fop = &ext3_dir_operations;
+       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) {
+-              drop_nlink(inode); /* is this nlink == 0? */
+-              ext3_mark_inode_dirty(handle, inode);
+-              iput (inode);
+-              goto out_stop;
+-      }
++      if (!dir_block)
++              goto get_out;
++
+       BUFFER_TRACE(dir_block, "get_write_access");
+       ext3_journal_get_write_access(handle, dir_block);
+       de = (struct ext3_dir_entry_2 *) dir_block->b_data;
+@@ -1904,6 +1914,45 @@ retry:
+       ext3_journal_dirty_metadata(handle, dir_block);
+       brelse (dir_block);
+       ext3_mark_inode_dirty(handle, inode);
++
++get_out:
++      return err;
++
++}
++EXPORT_SYMBOL(ext3_add_dot_dotdot);
++
++static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
++{
++      handle_t *handle;
++      struct inode * inode;
++      int err, retries = 0;
++
++      if (EXT3_DIR_LINK_MAX(dir))
++              return -EMLINK;
++
++retry:
++      handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
++                                      EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
++                                      2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
++      if (IS_ERR(handle))
++              return PTR_ERR(handle);
++
++      if (IS_DIRSYNC(dir))
++              handle->h_sync = 1;
++
++      inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
++      err = PTR_ERR(inode);
++      if (IS_ERR(inode))
++              goto out_stop;
++
++      err = ext3_add_dot_dotdot(handle, dir, inode);
++      if (err) {
++              inode->i_nlink = 0;
++              ext3_mark_inode_dirty(handle, inode);
++              iput (inode);
++              goto out_stop;
++      }
++
+       err = ext3_add_entry (handle, dentry, inode);
+       if (err) {
+               inode->i_nlink = 0;
+diff -rupN linux-2.6.18-128.1.6_1/include/linux/ext3_fs.h linux-2.6.18-128.1.6_2/include/linux/ext3_fs.h
+--- linux-2.6.18-128.1.6_1/include/linux/ext3_fs.h     2009-08-13 19:07:07.000000000 +0530
++++ linux-2.6.18-128.1.6_2/include/linux/ext3_fs.h     2009-08-13 19:14:07.000000000 +0530
+@@ -1076,6 +1076,10 @@ extern int ext3_group_extend(struct supe
+                               ext3_fsblk_t n_blocks_count);
+ /* super.c */
++extern int ext3_xattr_set_handle(handle_t *handle, struct inode *inode,
++                               int name_index, const char *name,
++                               const void *value, size_t value_len,
++                               int flags);
+ extern struct proc_dir_entry *proc_root_ext3;
+ extern int __init init_ext3_proc(void);
+ extern void exit_ext3_proc(void);
+@@ -1107,6 +1111,19 @@ extern struct inode_operations ext3_file
+ extern const struct file_operations ext3_file_operations;
+ /* namei.c */
++extern struct inode *ext3_create_inode(handle_t *handle,
++                                     struct inode * dir, int mode);
++extern int ext3_add_entry(handle_t *handle, struct dentry *dentry,
++                        struct inode *inode);
++extern int ext3_delete_entry(handle_t *handle,
++                           struct inode * dir,
++                           struct ext3_dir_entry_2 * de_del,
++                           struct buffer_head * bh);
++extern struct buffer_head * ext3_find_entry(struct dentry *dentry,
++                                          struct ext3_dir_entry_2
++                                          ** res_dir);
++extern int ext3_add_dot_dotdot(handle_t *handle, struct inode *dir,
++                             struct inode *inode);
+ extern struct inode_operations ext3_dir_inode_operations;
+ extern struct inode_operations ext3_special_inode_operations;
+
diff --git a/ldiskfs/kernel_patches/patches/ext3-pdir-fix.patch b/ldiskfs/kernel_patches/patches/ext3-pdir-fix.patch
new file mode 100644 (file)
index 0000000..471ea3c
--- /dev/null
@@ -0,0 +1,68 @@
+diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/namei.c linux-2.6.18-128.1.6_2/fs/ext3/namei.c
+--- linux-2.6.18-128.1.6_1/fs/ext3/namei.c     2009-08-13 19:27:12.000000000 +0530
++++ linux-2.6.18-128.1.6_2/fs/ext3/namei.c     2009-08-13 19:33:34.000000000 +0530
+@@ -51,19 +51,25 @@
+ #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+ #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+-static struct buffer_head *ext3_append(handle_t *handle,
++struct buffer_head *ext3_append(handle_t *handle,
+                                       struct inode *inode,
+                                       u32 *block, int *err)
+ {
+       struct buffer_head *bh;
++      struct ext3_inode_info *ei = EXT3_I(inode);
++ 
++      /* with parallel dir operations all appends
++       * have to be serialized -bzzz */
++      down(&ei->i_append_sem);
+       *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
+-      if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
++      bh = ext3_bread(handle, inode, *block, 1, err);
++      if (bh != NULL) {
+               inode->i_size += inode->i_sb->s_blocksize;
+-              EXT3_I(inode)->i_disksize = inode->i_size;
+-              ext3_journal_get_write_access(handle,bh);
++              ei->i_disksize = inode->i_size;
+       }
++      up(&ei->i_append_sem);
+       return bh;
+ }
+diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/super.c linux-2.6.18-128.1.6_2/fs/ext3/super.c
+--- linux-2.6.18-128.1.6_1/fs/ext3/super.c     2009-08-13 19:27:12.000000000 +0530
++++ linux-2.6.18-128.1.6_2/fs/ext3/super.c     2009-08-13 19:27:40.000000000 +0530
+@@ -481,6 +481,9 @@ static struct inode *ext3_alloc_inode(st
+       ei->i_acl = EXT3_ACL_NOT_CACHED;
+       ei->i_default_acl = EXT3_ACL_NOT_CACHED;
+ #endif
++      dynlock_init(&ei->i_htree_lock);
++      sema_init(&ei->i_append_sem, 1);
++
+       ei->i_block_alloc_info = NULL;
+       ei->vfs_inode.i_version = 1;
+diff -rupN linux-2.6.18-128.1.6_1/include/linux/ext3_fs_i.h linux-2.6.18-128.1.6_2/include/linux/ext3_fs_i.h
+--- linux-2.6.18-128.1.6_1/include/linux/ext3_fs_i.h   2009-08-13 19:27:12.000000000 +0530
++++ linux-2.6.18-128.1.6_2/include/linux/ext3_fs_i.h   2009-08-13 19:31:22.000000000 +0530
+@@ -16,6 +16,7 @@
+ #ifndef _LINUX_EXT3_FS_I
+ #define _LINUX_EXT3_FS_I
++#include <linux/dynlocks.h>
+ #include <linux/rwsem.h>
+ #include <linux/rbtree.h>
+ #include <linux/seqlock.h>
+@@ -104,6 +105,10 @@ struct ext3_inode_info {
+       /* block reservation info */
+       struct ext3_block_alloc_info *i_block_alloc_info;
++      /* following fields for parallel directory operations -bzzz */
++      struct dynlock   i_htree_lock;
++      struct semaphore i_append_sem;
++
+       __u32   i_dir_start_lookup;
+ #ifdef CONFIG_EXT3_FS_XATTR
+       /*
diff --git a/ldiskfs/kernel_patches/patches/ext4-dynlocks-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-dynlocks-2.6-rhel5.patch
new file mode 100644 (file)
index 0000000..2a11baa
--- /dev/null
@@ -0,0 +1,32 @@
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/Makefile linux-2.6.27.21-0.1_2//fs/ext4/Makefile
+--- linux-2.6.27.21-0.1_1//fs/ext4/Makefile    2009-08-21 15:12:51.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/Makefile    2009-08-21 15:13:23.000000000 +0530
+@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o
+ ext4dev-y     := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+                  ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
+-                 ext4_jbd2.o migrate.o mballoc.o
++                 ext4_jbd2.o migrate.o mballoc.o dynlocks.o
+ ext4dev-$(CONFIG_EXT4DEV_FS_XATTR)    += xattr.o xattr_user.o xattr_trusted.o
+ ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL)        += acl.o
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/super.c linux-2.6.27.21-0.1_2//fs/ext4/super.c
+--- linux-2.6.27.21-0.1_1//fs/ext4/super.c     2009-08-21 15:12:51.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/super.c     2009-08-21 15:18:18.000000000 +0530
+@@ -4126,6 +4126,7 @@ static int __init init_ext4_fs(void)
+       err = init_inodecache();
+       if (err)
+               goto out1;
++      dynlock_cache_init();
+       err = register_filesystem(&ext4_fs_type);
+       if (err)
+               goto out;
+@@ -4149,6 +4150,7 @@ static void __exit exit_ext4_fs(void)
+       unregister_filesystem(&ext4_fs_type);
+       unregister_filesystem(&ext4dev_fs_type);
+       destroy_inodecache();
++      dynlock_cache_exit();
+       exit_ext4_xattr();
+       exit_ext4_mballoc();
+       remove_proc_entry("fs/ext4", NULL);
+
diff --git a/ldiskfs/kernel_patches/patches/ext4-dynlocks-common-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-dynlocks-common-sles11.patch
new file mode 100644 (file)
index 0000000..34dc2c8
--- /dev/null
@@ -0,0 +1,280 @@
+diff -rupN 2.6.27.21/fs/ext4/dynlocks.c 2.6.27.21_1//fs/ext4/dynlocks.c
+--- 2.6.27.21/fs/ext4/dynlocks.c       1970-01-01 05:30:00.000000000 +0530
++++ 2.6.27.21_1//fs/ext4/dynlocks.c    2009-08-23 10:39:59.000000000 +0530
+@@ -0,0 +1,238 @@
++/*
++ * Dynamic Locks
++ *
++ * struct dynlock is lockspace
++ * one may request lock (exclusive or shared) for some value
++ * in that lockspace
++ *
++ */
++
++#include <linux/dynlocks.h>
++#include <linux/module.h>
++#include <linux/slab_def.h>
++#include <linux/sched.h>
++
++#define DYNLOCK_HANDLE_MAGIC  0xd19a10c
++#define DYNLOCK_HANDLE_DEAD   0xd1956ee
++#define DYNLOCK_LIST_MAGIC    0x11ee91e6
++
++typedef struct kmem_cache kmem_cache_t;
++
++static kmem_cache_t * dynlock_cachep = NULL;
++
++struct dynlock_handle {
++      unsigned                dh_magic;
++      struct list_head        dh_list;
++      unsigned long           dh_value;       /* lock value */
++      int                     dh_refcount;    /* number of users */
++      int                     dh_readers;
++      int                     dh_writers;
++      int                     dh_pid;         /* holder of the lock */
++      wait_queue_head_t       dh_wait;
++};
++
++int __init dynlock_cache_init(void)
++{
++      int rc = 0;
++
++      printk(KERN_INFO "init dynlocks cache\n");
++      dynlock_cachep = kmem_cache_create("dynlock_cache",
++                                       sizeof(struct dynlock_handle),
++                                       0,
++                                       SLAB_HWCACHE_ALIGN,
++                                       NULL);
++      if (dynlock_cachep == NULL) {
++              printk(KERN_ERR "Not able to create dynlock cache");
++              rc = -ENOMEM;
++      }
++      return rc;
++}
++
++void __exit dynlock_cache_exit(void)
++{
++      printk(KERN_INFO "exit dynlocks cache\n");
++      kmem_cache_destroy(dynlock_cachep);
++}
++
++/*
++ * dynlock_init
++ *
++ * initialize lockspace
++ *
++ */
++void dynlock_init(struct dynlock *dl)
++{
++      spin_lock_init(&dl->dl_list_lock);
++      INIT_LIST_HEAD(&dl->dl_list);
++      dl->dl_magic = DYNLOCK_LIST_MAGIC;
++}
++EXPORT_SYMBOL(dynlock_init);
++
++/*
++ * dynlock_lock
++ *
++ * acquires lock (exclusive or shared) in specified lockspace
++ * each lock in lockspace is allocated separately, so user have
++ * to specify GFP flags.
++ * routine returns pointer to lock. this pointer is intended to
++ * be passed to dynlock_unlock
++ *
++ */
++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value,
++                                  enum dynlock_type lt, gfp_t gfp)
++{
++      struct dynlock_handle *nhl = NULL;
++      struct dynlock_handle *hl;
++
++      BUG_ON(dl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++
++repeat:
++      /* find requested lock in lockspace */
++      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl->dl_list.next == NULL);
++      BUG_ON(dl->dl_list.prev == NULL);
++      list_for_each_entry(hl, &dl->dl_list, dh_list) {
++              BUG_ON(hl->dh_list.next == NULL);
++              BUG_ON(hl->dh_list.prev == NULL);
++              BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++              if (hl->dh_value == value) {
++                      /* lock is found */
++                      if (nhl) {
++                              /* someone else just allocated
++                               * lock we didn't find and just created
++                               * so, we drop our lock
++                               */
++                              kmem_cache_free(dynlock_cachep, nhl);
++                              nhl = NULL;
++                      }
++                      hl->dh_refcount++;
++                      goto found;
++              }
++      }
++      /* lock not found */
++      if (nhl) {
++              /* we already have allocated lock. use it */
++              hl = nhl;
++              nhl = NULL;
++              list_add(&hl->dh_list, &dl->dl_list);
++              goto found;
++      }
++      spin_unlock(&dl->dl_list_lock);
++      
++      /* lock not found and we haven't allocated lock yet. allocate it */
++      nhl = kmem_cache_alloc(dynlock_cachep, gfp);
++      if (nhl == NULL)
++              return NULL;
++      nhl->dh_refcount = 1;
++      nhl->dh_value = value;
++      nhl->dh_readers = 0;
++      nhl->dh_writers = 0;
++      nhl->dh_magic = DYNLOCK_HANDLE_MAGIC;
++      init_waitqueue_head(&nhl->dh_wait);
++
++      /* while lock is being allocated, someone else may allocate it
++       * and put onto to list. check this situation
++       */
++      goto repeat;
++
++found:
++      if (lt == DLT_WRITE) {
++              /* exclusive lock: user don't want to share lock at all
++               * NOTE: one process may take the same lock several times
++               * this functionaly is useful for rename operations */
++              while ((hl->dh_writers && hl->dh_pid != current->pid) ||
++                              hl->dh_readers) {
++                      spin_unlock(&dl->dl_list_lock);
++                      wait_event(hl->dh_wait,
++                              hl->dh_writers == 0 && hl->dh_readers == 0);
++                      spin_lock(&dl->dl_list_lock);
++              }
++              hl->dh_writers++;
++      } else {
++              /* shared lock: user do not want to share lock with writer */
++              while (hl->dh_writers) {
++                      spin_unlock(&dl->dl_list_lock);
++                      wait_event(hl->dh_wait, hl->dh_writers == 0);
++                      spin_lock(&dl->dl_list_lock);
++              }
++              hl->dh_readers++;
++      }
++      hl->dh_pid = current->pid;
++      spin_unlock(&dl->dl_list_lock);
++
++      return hl;
++}
++EXPORT_SYMBOL(dynlock_lock);
++
++
++/*
++ * dynlock_unlock
++ *
++ * user have to specify lockspace (dl) and pointer to lock structure
++ * returned by dynlock_lock()
++ *
++ */
++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *hl)
++{
++      int wakeup = 0;
++      
++      BUG_ON(dl == NULL);
++      BUG_ON(hl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++
++      if (hl->dh_magic != DYNLOCK_HANDLE_MAGIC)
++              printk(KERN_EMERG "wrong lock magic: %#x\n", hl->dh_magic);
++
++      BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++      BUG_ON(hl->dh_writers != 0 && current->pid != hl->dh_pid);
++
++      spin_lock(&dl->dl_list_lock);
++      if (hl->dh_writers) {
++              BUG_ON(hl->dh_readers != 0);
++              hl->dh_writers--;
++              if (hl->dh_writers == 0)
++                      wakeup = 1;
++      } else if (hl->dh_readers) {
++              hl->dh_readers--;
++              if (hl->dh_readers == 0)
++                      wakeup = 1;
++      } else {
++              BUG();
++      }
++      if (wakeup) {
++              hl->dh_pid = 0;
++              wake_up(&hl->dh_wait);
++      }
++      if (--(hl->dh_refcount) == 0) {
++              hl->dh_magic = DYNLOCK_HANDLE_DEAD;
++              list_del(&hl->dh_list);
++              kmem_cache_free(dynlock_cachep, hl);
++      }
++      spin_unlock(&dl->dl_list_lock);
++}
++EXPORT_SYMBOL(dynlock_unlock);
++
++int dynlock_is_locked(struct dynlock *dl, unsigned long value)
++{
++      struct dynlock_handle *hl;
++      int result = 0;
++
++      /* find requested lock in lockspace */
++      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl->dl_list.next == NULL);
++      BUG_ON(dl->dl_list.prev == NULL);
++      list_for_each_entry(hl, &dl->dl_list, dh_list) {
++              BUG_ON(hl->dh_list.next == NULL);
++              BUG_ON(hl->dh_list.prev == NULL);
++              BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++              if (hl->dh_value == value && hl->dh_pid == current->pid) {
++                      /* lock is found */
++                      result = 1;
++                      break;
++              }
++      }
++      spin_unlock(&dl->dl_list_lock);
++      return result;
++}
++EXPORT_SYMBOL(dynlock_is_locked);
+diff -rupN 2.6.27.21/include/linux/dynlocks.h 2.6.27.21_1//include/linux/dynlocks.h
+--- 2.6.27.21/include/linux/dynlocks.h 1970-01-01 05:30:00.000000000 +0530
++++ 2.6.27.21_1//include/linux/dynlocks.h      2009-08-23 10:40:07.000000000 +0530
+@@ -0,0 +1,34 @@
++#ifndef _LINUX_DYNLOCKS_H
++#define _LINUX_DYNLOCKS_H
++
++#include <linux/list.h>
++#include <linux/wait.h>
++
++struct dynlock_handle;
++
++/*
++ * lock's namespace:
++ *   - list of locks
++ *   - lock to protect this list
++ */
++struct dynlock {
++      unsigned                dl_magic;
++      struct list_head        dl_list;
++      spinlock_t              dl_list_lock;
++};
++
++enum dynlock_type {
++      DLT_WRITE,
++      DLT_READ
++};
++
++int dynlock_cache_init(void);
++void dynlock_cache_exit(void);
++void dynlock_init(struct dynlock *dl);
++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value,
++                                  enum dynlock_type lt, gfp_t gfp);
++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *lock);
++int dynlock_is_locked(struct dynlock *dl, unsigned long value);
++
++#endif
++
diff --git a/ldiskfs/kernel_patches/patches/ext4-dynlocks-common.patch b/ldiskfs/kernel_patches/patches/ext4-dynlocks-common.patch
new file mode 100644 (file)
index 0000000..e360662
--- /dev/null
@@ -0,0 +1,278 @@
+diff -rupN linux-2.6.18-128.1.6_1/fs/ext4/dynlocks.c linux-2.6.18-128.1.6_2/fs/ext4/dynlocks.c
+--- linux-2.6.18-128.1.6_1/fs/ext4/dynlocks.c  1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.18-128.1.6_2/fs/ext4/dynlocks.c  2009-08-13 20:42:59.000000000 +0530
+@@ -0,0 +1,236 @@
++/*
++ * Dynamic Locks
++ *
++ * struct dynlock is lockspace
++ * one may request lock (exclusive or shared) for some value
++ * in that lockspace
++ *
++ */
++
++#include <linux/dynlocks.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++
++#define DYNLOCK_HANDLE_MAGIC  0xd19a10c
++#define DYNLOCK_HANDLE_DEAD   0xd1956ee
++#define DYNLOCK_LIST_MAGIC    0x11ee91e6
++
++static kmem_cache_t * dynlock_cachep = NULL;
++
++struct dynlock_handle {
++      unsigned                dh_magic;
++      struct list_head        dh_list;
++      unsigned long           dh_value;       /* lock value */
++      int                     dh_refcount;    /* number of users */
++      int                     dh_readers;
++      int                     dh_writers;
++      int                     dh_pid;         /* holder of the lock */
++      wait_queue_head_t       dh_wait;
++};
++
++int __init dynlock_cache_init(void)
++{
++      int rc = 0;
++
++      printk(KERN_INFO "init dynlocks cache\n");
++      dynlock_cachep = kmem_cache_create("dynlock_cache",
++                                       sizeof(struct dynlock_handle),
++                                       0,
++                                       SLAB_HWCACHE_ALIGN,
++                                       NULL, NULL);
++      if (dynlock_cachep == NULL) {
++              printk(KERN_ERR "Not able to create dynlock cache");
++              rc = -ENOMEM;
++      }
++      return rc;
++}
++
++void __exit dynlock_cache_exit(void)
++{
++      printk(KERN_INFO "exit dynlocks cache\n");
++      kmem_cache_destroy(dynlock_cachep);
++}
++
++/*
++ * dynlock_init
++ *
++ * initialize lockspace
++ *
++ */
++void dynlock_init(struct dynlock *dl)
++{
++      spin_lock_init(&dl->dl_list_lock);
++      INIT_LIST_HEAD(&dl->dl_list);
++      dl->dl_magic = DYNLOCK_LIST_MAGIC;
++}
++EXPORT_SYMBOL(dynlock_init);
++
++/*
++ * dynlock_lock
++ *
++ * acquires lock (exclusive or shared) in specified lockspace
++ * each lock in lockspace is allocated separately, so user have
++ * to specify GFP flags.
++ * routine returns pointer to lock. this pointer is intended to
++ * be passed to dynlock_unlock
++ *
++ */
++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value,
++                                  enum dynlock_type lt, gfp_t gfp)
++{
++      struct dynlock_handle *nhl = NULL;
++      struct dynlock_handle *hl;
++
++      BUG_ON(dl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++
++repeat:
++      /* find requested lock in lockspace */
++      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl->dl_list.next == NULL);
++      BUG_ON(dl->dl_list.prev == NULL);
++      list_for_each_entry(hl, &dl->dl_list, dh_list) {
++              BUG_ON(hl->dh_list.next == NULL);
++              BUG_ON(hl->dh_list.prev == NULL);
++              BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++              if (hl->dh_value == value) {
++                      /* lock is found */
++                      if (nhl) {
++                              /* someone else just allocated
++                               * lock we didn't find and just created
++                               * so, we drop our lock
++                               */
++                              kmem_cache_free(dynlock_cachep, nhl);
++                              nhl = NULL;
++                      }
++                      hl->dh_refcount++;
++                      goto found;
++              }
++      }
++      /* lock not found */
++      if (nhl) {
++              /* we already have allocated lock. use it */
++              hl = nhl;
++              nhl = NULL;
++              list_add(&hl->dh_list, &dl->dl_list);
++              goto found;
++      }
++      spin_unlock(&dl->dl_list_lock);
++      
++      /* lock not found and we haven't allocated lock yet. allocate it */
++      nhl = kmem_cache_alloc(dynlock_cachep, gfp);
++      if (nhl == NULL)
++              return NULL;
++      nhl->dh_refcount = 1;
++      nhl->dh_value = value;
++      nhl->dh_readers = 0;
++      nhl->dh_writers = 0;
++      nhl->dh_magic = DYNLOCK_HANDLE_MAGIC;
++      init_waitqueue_head(&nhl->dh_wait);
++
++      /* while lock is being allocated, someone else may allocate it
++       * and put onto to list. check this situation
++       */
++      goto repeat;
++
++found:
++      if (lt == DLT_WRITE) {
++              /* exclusive lock: user don't want to share lock at all
++               * NOTE: one process may take the same lock several times
++               * this functionaly is useful for rename operations */
++              while ((hl->dh_writers && hl->dh_pid != current->pid) ||
++                              hl->dh_readers) {
++                      spin_unlock(&dl->dl_list_lock);
++                      wait_event(hl->dh_wait,
++                              hl->dh_writers == 0 && hl->dh_readers == 0);
++                      spin_lock(&dl->dl_list_lock);
++              }
++              hl->dh_writers++;
++      } else {
++              /* shared lock: user do not want to share lock with writer */
++              while (hl->dh_writers) {
++                      spin_unlock(&dl->dl_list_lock);
++                      wait_event(hl->dh_wait, hl->dh_writers == 0);
++                      spin_lock(&dl->dl_list_lock);
++              }
++              hl->dh_readers++;
++      }
++      hl->dh_pid = current->pid;
++      spin_unlock(&dl->dl_list_lock);
++
++      return hl;
++}
++EXPORT_SYMBOL(dynlock_lock);
++
++
++/*
++ * dynlock_unlock
++ *
++ * user have to specify lockspace (dl) and pointer to lock structure
++ * returned by dynlock_lock()
++ *
++ */
++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *hl)
++{
++      int wakeup = 0;
++      
++      BUG_ON(dl == NULL);
++      BUG_ON(hl == NULL);
++      BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC);
++
++      if (hl->dh_magic != DYNLOCK_HANDLE_MAGIC)
++              printk(KERN_EMERG "wrong lock magic: %#x\n", hl->dh_magic);
++
++      BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++      BUG_ON(hl->dh_writers != 0 && current->pid != hl->dh_pid);
++
++      spin_lock(&dl->dl_list_lock);
++      if (hl->dh_writers) {
++              BUG_ON(hl->dh_readers != 0);
++              hl->dh_writers--;
++              if (hl->dh_writers == 0)
++                      wakeup = 1;
++      } else if (hl->dh_readers) {
++              hl->dh_readers--;
++              if (hl->dh_readers == 0)
++                      wakeup = 1;
++      } else {
++              BUG();
++      }
++      if (wakeup) {
++              hl->dh_pid = 0;
++              wake_up(&hl->dh_wait);
++      }
++      if (--(hl->dh_refcount) == 0) {
++              hl->dh_magic = DYNLOCK_HANDLE_DEAD;
++              list_del(&hl->dh_list);
++              kmem_cache_free(dynlock_cachep, hl);
++      }
++      spin_unlock(&dl->dl_list_lock);
++}
++EXPORT_SYMBOL(dynlock_unlock);
++
++int dynlock_is_locked(struct dynlock *dl, unsigned long value)
++{
++      struct dynlock_handle *hl;
++      int result = 0;
++
++      /* find requested lock in lockspace */
++      spin_lock(&dl->dl_list_lock);
++      BUG_ON(dl->dl_list.next == NULL);
++      BUG_ON(dl->dl_list.prev == NULL);
++      list_for_each_entry(hl, &dl->dl_list, dh_list) {
++              BUG_ON(hl->dh_list.next == NULL);
++              BUG_ON(hl->dh_list.prev == NULL);
++              BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC);
++              if (hl->dh_value == value && hl->dh_pid == current->pid) {
++                      /* lock is found */
++                      result = 1;
++                      break;
++              }
++      }
++      spin_unlock(&dl->dl_list_lock);
++      return result;
++}
++EXPORT_SYMBOL(dynlock_is_locked);
+diff -rupN linux-2.6.18-128.1.6_1/include/linux/dynlocks.h linux-2.6.18-128.1.6_2/include/linux/dynlocks.h
+--- linux-2.6.18-128.1.6_1/include/linux/dynlocks.h    1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.18-128.1.6_2/include/linux/dynlocks.h    2009-08-13 20:43:18.000000000 +0530
+@@ -0,0 +1,34 @@
++#ifndef _LINUX_DYNLOCKS_H
++#define _LINUX_DYNLOCKS_H
++
++#include <linux/list.h>
++#include <linux/wait.h>
++
++struct dynlock_handle;
++
++/*
++ * lock's namespace:
++ *   - list of locks
++ *   - lock to protect this list
++ */
++struct dynlock {
++      unsigned                dl_magic;
++      struct list_head        dl_list;
++      spinlock_t              dl_list_lock;
++};
++
++enum dynlock_type {
++      DLT_WRITE,
++      DLT_READ
++};
++
++int dynlock_cache_init(void);
++void dynlock_cache_exit(void);
++void dynlock_init(struct dynlock *dl);
++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value,
++                                  enum dynlock_type lt, gfp_t gfp);
++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *lock);
++int dynlock_is_locked(struct dynlock *dl, unsigned long value);
++
++#endif
++
diff --git a/ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch b/ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch
new file mode 100644 (file)
index 0000000..d354f89
--- /dev/null
@@ -0,0 +1,87 @@
+Index: linux-stage/fs/ext4/namei.c
+===================================================================
+--- linux-stage.orig/fs/ext4/namei.c   2009-08-10 22:44:33.000000000 +0800
++++ linux-stage/fs/ext4/namei.c        2009-08-10 22:48:22.000000000 +0800
+@@ -1493,6 +1493,72 @@
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+ }
++/* update ".." for hash-indexed directory, split the item "." if necessary */
++static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry,
++                               struct inode *inode)
++{
++      struct inode * dir = dentry->d_parent->d_inode;
++      struct buffer_head * dir_block;
++      struct ext4_dir_entry_2 * de;
++      int len, journal = 0, err = 0;
++
++      if (IS_ERR(handle))
++              return PTR_ERR(handle);
++
++      if (IS_DIRSYNC(dir))
++              handle->h_sync = 1;
++
++      dir_block = ext4_bread(handle, dir, 0, 0, &err);
++      if (!dir_block)
++              goto out;
++
++      de = (struct ext4_dir_entry_2 *)dir_block->b_data;
++      /* the first item must be "." */
++      assert(de->name_len == 1 && de->name[0] == '.');
++      len = le16_to_cpu(de->rec_len);
++      assert(len >= EXT4_DIR_REC_LEN(1));
++      if (len > EXT4_DIR_REC_LEN(1)) {
++              BUFFER_TRACE(dir_block, "get_write_access");
++              err = ext4_journal_get_write_access(handle, dir_block);
++              if (err)
++                      goto out_journal;
++
++              journal = 1;
++              de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(1));
++      }
++
++      len -= EXT4_DIR_REC_LEN(1);
++      assert(len == 0 || len >= EXT4_DIR_REC_LEN(2));
++      de = (struct ext4_dir_entry_2 *)
++                      ((char *) de + le16_to_cpu(de->rec_len));
++      if (!journal) {
++              BUFFER_TRACE(dir_block, "get_write_access");
++              err = ext4_journal_get_write_access(handle, dir_block);
++              if (err)
++                      goto out_journal;
++      }
++
++      de->inode = cpu_to_le32(inode->i_ino);
++      if (len > 0)
++              de->rec_len = cpu_to_le16(len);
++      else
++              assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2));
++      de->name_len = 2;
++      strcpy (de->name, "..");
++      ext4_set_de_type(dir->i_sb, de, S_IFDIR);
++
++out_journal:
++      if (journal) {
++              BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
++              err = ext4_journal_dirty_metadata(handle, dir_block);
++              ext4_mark_inode_dirty(handle, dir);
++      }
++      brelse (dir_block);
++
++out:
++      return err;
++}
++
+ /*
+  *    ext4_add_entry()
+  *
+@@ -1521,6 +1587,9 @@
+       if (!dentry->d_name.len)
+               return -EINVAL;
+       if (is_dx(dir)) {
++              if (dentry->d_name.len == 2 &&
++                  memcmp(dentry->d_name.name, "..", 2) == 0)
++                      return ext4_update_dotdot(handle, dentry, inode);
+               retval = ext4_dx_add_entry(handle, dentry, inode);
+               if (!retval || (retval != ERR_BAD_DX_DIR))
+                       return retval;
diff --git a/ldiskfs/kernel_patches/patches/ext4-osd-iam-exports.patch b/ldiskfs/kernel_patches/patches/ext4-osd-iam-exports.patch
new file mode 100644 (file)
index 0000000..6b65eb0
--- /dev/null
@@ -0,0 +1,64 @@
+diff -rupN 2.6.27.21_2/fs/ext4/ext4.h 2.6.27.21_3/fs/ext4/ext4.h
+--- 2.6.27.21_2/fs/ext4/ext4.h 2009-07-17 12:19:59.000000000 +0530
++++ 2.6.27.21_3/fs/ext4/ext4.h 2009-07-17 12:38:59.000000000 +0530
+@@ -1181,6 +1181,9 @@ 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 struct buffer_head *ext4_append(handle_t *handle,
++                                     struct inode *inode,
++                                     ext4_lblk_t *block, int *err);
+ /* resize.c */
+ extern int ext4_group_add(struct super_block *sb,
+diff -rupN 2.6.27.21_2/fs/ext4/hash.c 2.6.27.21_3/fs/ext4/hash.c
+--- 2.6.27.21_2/fs/ext4/hash.c 2009-07-17 12:12:56.000000000 +0530
++++ 2.6.27.21_3/fs/ext4/hash.c 2009-07-17 12:40:22.000000000 +0530
+@@ -9,6 +9,7 @@
+  * License.
+  */
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/jbd2.h>
+ #include <linux/cryptohash.h>
+@@ -206,3 +207,4 @@ int ext4fs_dirhash(const char *name, int
+       hinfo->minor_hash = minor_hash;
+       return 0;
+ }
++EXPORT_SYMBOL(ext4fs_dirhash);
+diff -rupN 2.6.27.21_2/fs/ext4/namei.c 2.6.27.21_3/fs/ext4/namei.c
+--- 2.6.27.21_2/fs/ext4/namei.c        2009-07-17 12:23:51.000000000 +0530
++++ 2.6.27.21_3/fs/ext4/namei.c        2009-07-17 12:37:59.000000000 +0530
+@@ -51,9 +51,9 @@
+ #define NAMEI_RA_SIZE      (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+ #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+-static struct buffer_head *ext4_append(handle_t *handle,
+-                                      struct inode *inode,
+-                                      ext4_lblk_t *block, int *err)
++struct buffer_head *ext4_append(handle_t *handle,
++                              struct inode *inode,
++                              ext4_lblk_t *block, int *err)
+ {
+       struct buffer_head *bh;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+@@ -72,6 +72,7 @@ static struct buffer_head *ext4_append(h
+       up(&ei->i_append_sem);
+       return bh;
+ }
++EXPORT_SYMBOL(ext4_append);
+ #ifndef assert
+ #define assert(test) J_ASSERT(test)
+diff -rupN 2.6.27.21_2/fs/ext4/super.c 2.6.27.21_3/fs/ext4/super.c
+--- 2.6.27.21_2/fs/ext4/super.c        2009-07-17 12:12:57.000000000 +0530
++++ 2.6.27.21_3/fs/ext4/super.c        2009-07-17 12:40:52.000000000 +0530
+@@ -377,6 +377,7 @@ void __ext4_std_error(struct super_block
+       ext4_handle_error(sb);
+ }
++EXPORT_SYMBOL(__ext4_std_error);
+ /*
+  * ext4_abort is a much stronger failure handler than ext4_error.  The
diff --git a/ldiskfs/kernel_patches/patches/ext4-osd-iop-common-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-osd-iop-common-sles11.patch
new file mode 100644 (file)
index 0000000..7e9d654
--- /dev/null
@@ -0,0 +1,237 @@
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/ext4.h linux-2.6.27.21-0.1_2//fs/ext4/ext4.h
+--- linux-2.6.27.21-0.1_1//fs/ext4/ext4.h      2009-08-24 15:32:00.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/ext4.h      2009-08-24 15:32:55.000000000 +0530
+@@ -1171,6 +1171,18 @@ extern int ext4_fiemap(struct inode *, s
+ /* migrate.c */
+ extern int ext4_ext_migrate(struct inode *);
+ /* namei.c */
++extern struct inode *ext4_create_inode(handle_t *handle,
++                                        struct inode * dir, int mode);
++extern int ext4_add_entry(handle_t *handle, struct dentry *dentry,
++                           struct inode *inode);
++extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
++                              struct ext4_dir_entry_2 * de_del,
++                              struct buffer_head * bh);
++extern struct buffer_head * ext4_find_entry (struct inode *dir,
++                                          const struct qstr *d_name,
++                                          struct ext4_dir_entry_2 ** res_dir);
++extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
++                                struct inode *inode);
+ extern int ext4_orphan_add(handle_t *, struct inode *);
+ extern int ext4_orphan_del(handle_t *, struct inode *);
+ extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/namei.c linux-2.6.27.21-0.1_2//fs/ext4/namei.c
+--- linux-2.6.27.21-0.1_1//fs/ext4/namei.c     2009-08-24 15:32:00.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/namei.c     2009-08-24 15:43:56.000000000 +0530
+@@ -24,6 +24,7 @@
+  *    Theodore Ts'o, 2002
+  */
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
+ #include <linux/jbd2.h>
+@@ -882,9 +883,9 @@ static inline int search_dirblock(struct
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
+-static struct buffer_head * ext4_find_entry (struct inode *dir,
+-                                      const struct qstr *d_name,
+-                                      struct ext4_dir_entry_2 ** res_dir)
++struct buffer_head * ext4_find_entry (struct inode *dir,
++                                    const struct qstr *d_name,
++                                    struct ext4_dir_entry_2 ** res_dir)
+ {
+       struct super_block *sb;
+       struct buffer_head *bh_use[NAMEI_RA_SIZE];
+@@ -991,6 +992,7 @@ cleanup_and_exit:
+               brelse(bh_use[ra_ptr]);
+       return ret;
+ }
++EXPORT_SYMBOL(ext4_find_entry);
+ 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)
+@@ -1511,8 +1513,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.
+  */
+-static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
+-                        struct inode *inode)
++int ext4_add_entry(handle_t *handle, struct dentry *dentry,
++                 struct inode *inode)
+ {
+       struct inode *dir = dentry->d_parent->d_inode;
+       struct buffer_head *bh;
+@@ -1557,6 +1559,7 @@ static int ext4_add_entry(handle_t *hand
+       de->rec_len = ext4_rec_len_to_disk(blocksize);
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+ }
++EXPORT_SYMBOL(ext4_add_entry);
+ /*
+  * Returns 0 for success, or a negative error value
+@@ -1699,10 +1702,10 @@ cleanup:
+  * ext4_delete_entry deletes a directory entry by merging it with the
+  * previous entry
+  */
+-static int ext4_delete_entry(handle_t *handle,
+-                           struct inode *dir,
+-                           struct ext4_dir_entry_2 *de_del,
+-                           struct buffer_head *bh)
++int ext4_delete_entry(handle_t *handle,
++                    struct inode *dir,
++                    struct ext4_dir_entry_2 *de_del,
++                    struct buffer_head *bh)
+ {
+       struct ext4_dir_entry_2 *de, *pde;
+       int i;
+@@ -1733,7 +1736,7 @@ static int ext4_delete_entry(handle_t *h
+       }
+       return -ENOENT;
+ }
+-
++EXPORT_SYMBOL(ext4_delete_entry);
+ /*
+  * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
+  * since this indicates that nlinks count was previously 1.
+@@ -1796,6 +1799,26 @@ static unsigned ext4_dentry_goal(struct
+       return inum;
+ }
++struct inode * ext4_create_inode(handle_t *handle, struct inode * dir, int mode)
++{
++      struct inode *inode;
++
++      inode = ext4_new_inode(handle, dir, mode);
++      if (!IS_ERR(inode)) {
++              if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
++#ifdef CONFIG_LDISKFS_FS_XATTR
++                      inode->i_op = &ext4_special_inode_operations;
++#endif
++              } else {
++                      inode->i_op = &ext4_file_inode_operations;
++                      inode->i_fop = &ext4_file_operations;
++                      ext4_set_aops(inode);
++              }
++      }
++      return inode;
++}
++EXPORT_SYMBOL(ext4_create_inode);
++
+ /*
+  * By the time this is called, we already have created
+  * the directory cache entry for the new file, but it
+@@ -1872,51 +1895,43 @@ retry:
+       return err;
+ }
+-static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++/* 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,
++                      struct inode *inode)
+ {
+-      handle_t *handle;
+-      struct inode *inode;
+-      struct buffer_head *dir_block;
+-      struct ext4_dir_entry_2 *de;
+-      int err, retries = 0;
+-
+-      if (EXT4_DIR_LINK_MAX(dir))
+-              return -EMLINK;
++      struct buffer_head * dir_block;
++      struct ext4_dir_entry_2 * de;
++      int err = 0;
+-retry:
+-      handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+-                                      EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+-                                      2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+-      inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
+-                                  ext4_dentry_goal(dir->i_sb, dentry));
+-      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);
+-      if (!dir_block)
+-              goto out_clear_inode;
++      dir_block = ext4_bread (handle, inode, 0, 1, &err);
++      if (!dir_block) {
++              clear_nlink(inode);
++              ext4_mark_inode_dirty(handle, inode);
++              iput (inode);
++              goto get_out;
++      }
+       BUFFER_TRACE(dir_block, "get_write_access");
+       ext4_journal_get_write_access(handle, dir_block);
+       de = (struct ext4_dir_entry_2 *) dir_block->b_data;
+       de->inode = cpu_to_le32(inode->i_ino);
+       de->name_len = 1;
+       de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len));
+-      strcpy(de->name, ".");
++      strcpy (de->name, ".");
+       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+       de = ext4_next_entry(de);
+       de->inode = cpu_to_le32(dir->i_ino);
+       de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
+-                                              EXT4_DIR_REC_LEN(1));
++                                            EXT4_DIR_REC_LEN(1));
+       de->name_len = 2;
+       strcpy(de->name, "..");
+       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+@@ -1925,9 +1940,43 @@ retry:
+       ext4_journal_dirty_metadata(handle, dir_block);
+       brelse(dir_block);
+       ext4_mark_inode_dirty(handle, inode);
++get_out:
++      return err;
++}
++EXPORT_SYMBOL(ext4_add_dot_dotdot);
++
++
++static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++{
++      handle_t *handle;
++      struct inode *inode;
++      int err, retries = 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 +
++                                      2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
++      if (IS_ERR(handle))
++              return PTR_ERR(handle);
++
++      if (IS_DIRSYNC(dir))
++              handle->h_sync = 1;
++
++      inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
++                                  ext4_dentry_goal(dir->i_sb, dentry));
++      err = PTR_ERR(inode);
++      if (IS_ERR(inode))
++              goto out_stop;
++
++      err = ext4_add_dot_dotdot(handle, dir, inode);
++      if (err)
++              goto out_stop;
++
+       err = ext4_add_entry(handle, dentry, inode);
+       if (err) {
+-out_clear_inode:
+               clear_nlink(inode);
+               ext4_mark_inode_dirty(handle, inode);
+               iput(inode);
diff --git a/ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch b/ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch
new file mode 100644 (file)
index 0000000..bc184c5
--- /dev/null
@@ -0,0 +1,237 @@
+diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/ext4.h linux-2.6.18-128.1.6_2//fs/ext4/ext4.h
+--- linux-2.6.18-128.1.6_1//fs/ext4/ext4.h     2009-08-24 15:54:11.000000000 +0530
++++ linux-2.6.18-128.1.6_2//fs/ext4/ext4.h     2009-08-24 15:54:52.000000000 +0530
+@@ -1144,6 +1144,18 @@ extern int ext4_fiemap(struct inode *, s
+ extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
+                      unsigned long);
+ /* namei.c */
++extern struct inode *ext4_create_inode(handle_t *handle,
++                                     struct inode * dir, int mode);
++extern int ext4_add_entry(handle_t *handle, struct dentry *dentry,
++                        struct inode *inode);
++extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
++                           struct ext4_dir_entry_2 * de_del,
++                           struct buffer_head * bh);
++extern struct buffer_head * ext4_find_entry(struct dentry *dentry,
++                                          struct ext4_dir_entry_2
++                                          ** res_dir);
++extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
++                             struct inode *inode);
+ extern int ext4_orphan_add(handle_t *, struct inode *);
+ extern int ext4_orphan_del(handle_t *, struct inode *);
+ extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
+diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/inode.c linux-2.6.18-128.1.6_2//fs/ext4/inode.c
+--- linux-2.6.18-128.1.6_1//fs/ext4/inode.c    2009-08-24 15:54:11.000000000 +0530
++++ linux-2.6.18-128.1.6_2//fs/ext4/inode.c    2009-08-24 15:54:52.000000000 +0530
+@@ -2891,6 +2891,7 @@ bad_inode:
+       iput(inode);
+       return ERR_PTR(ret);
+ }
++EXPORT_SYMBOL(ext4_iget);
+ static int ext4_inode_blocks_set(handle_t *handle,
+                               struct ext4_inode *raw_inode,
+diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ext4/namei.c
+--- linux-2.6.18-128.1.6_1//fs/ext4/namei.c    2009-08-24 15:54:11.000000000 +0530
++++ linux-2.6.18-128.1.6_2//fs/ext4/namei.c    2009-08-24 15:55:18.000000000 +0530
+@@ -24,6 +24,7 @@
+  *    Theodore Ts'o, 2002
+  */
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
+ #include <linux/jbd2.h>
+@@ -878,8 +879,8 @@ static inline int search_dirblock(struct
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
+-static struct buffer_head * ext4_find_entry (struct dentry *dentry,
+-                                      struct ext4_dir_entry_2 ** res_dir)
++struct buffer_head * ext4_find_entry (struct dentry *dentry,
++                                    struct ext4_dir_entry_2 ** res_dir)
+ {
+       struct super_block * sb;
+       struct buffer_head * bh_use[NAMEI_RA_SIZE];
+@@ -986,6 +987,7 @@ cleanup_and_exit:
+               brelse (bh_use[ra_ptr]);
+       return ret;
+ }
++EXPORT_SYMBOL(ext4_find_entry);
+ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
+                      struct ext4_dir_entry_2 **res_dir, int *err)
+@@ -1506,8 +1508,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.
+  */
+-static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
+-      struct inode *inode)
++int ext4_add_entry (handle_t *handle, struct dentry *dentry,
++                  struct inode *inode)
+ {
+       struct inode *dir = dentry->d_parent->d_inode;
+       unsigned long offset;
+@@ -1553,6 +1555,7 @@ static int ext4_add_entry (handle_t *han
+       de->rec_len = ext4_rec_len_to_disk(blocksize);
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+ }
++EXPORT_SYMBOL(ext4_add_entry);
+ /*
+  * Returns 0 for success, or a negative error value
+@@ -1693,10 +1696,10 @@ cleanup:
+  * ext4_delete_entry deletes a directory entry by merging it with the
+  * previous entry
+  */
+-static int ext4_delete_entry (handle_t *handle,
+-                            struct inode * dir,
+-                            struct ext4_dir_entry_2 * de_del,
+-                            struct buffer_head * bh)
++int ext4_delete_entry (handle_t *handle,
++                     struct inode * dir,
++                     struct ext4_dir_entry_2 * de_del,
++                     struct buffer_head * bh)
+ {
+       struct ext4_dir_entry_2 * de, * pde;
+       int i;
+@@ -1727,7 +1730,7 @@ static int ext4_delete_entry (handle_t *
+       }
+       return -ENOENT;
+ }
+-
++EXPORT_SYMBOL(ext4_delete_entry);
+ /*
+  * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
+  * since this indicates that nlinks count was previously 1.
+@@ -1790,6 +1793,26 @@ static struct inode * ext4_new_inode_wan
+       return ext4_new_inode(handle, dir, mode, inum);
+ }
++struct inode * ext4_create_inode(handle_t *handle, struct inode * dir, int mode)
++{
++      struct inode *inode;
++
++      inode = ext4_new_inode(handle, dir, mode, 0);
++      if (!IS_ERR(inode)) {
++              if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
++#ifdef CONFIG_LDISKFS_FS_XATTR
++                      inode->i_op = &ext4_special_inode_operations;
++#endif
++              } else {
++                      inode->i_op = &ext4_file_inode_operations;
++                      inode->i_fop = &ext4_file_operations;
++                      ext4_set_aops(inode);
++              }
++      }
++      return inode;
++}
++EXPORT_SYMBOL(ext4_create_inode);
++
+ /*
+  * By the time this is called, we already have created
+  * the directory cache entry for the new file, but it
+@@ -1864,38 +1887,25 @@ retry:
+       return err;
+ }
+-static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+-{
+-      handle_t *handle;
+-      struct inode * inode;
++/* 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,
++                       struct inode *inode)
++ {
+       struct buffer_head * dir_block;
+       struct ext4_dir_entry_2 * de;
+-      int err, retries = 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 +
+-                                      2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+-      if (IS_ERR(handle))
+-              return PTR_ERR(handle);
+-
+-      if (IS_DIRSYNC(dir))
+-              handle->h_sync = 1;
+-
+-      inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+-      err = PTR_ERR(inode);
+-      if (IS_ERR(inode))
+-              goto out_stop;
++      int err = 0;
+       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)
+-              goto out_clear_inode;
++      if (!dir_block) {
++              clear_nlink(inode);
++              ext4_mark_inode_dirty(handle, inode);
++              iput (inode);
++              goto get_out;
++      }
+       BUFFER_TRACE(dir_block, "get_write_access");
+       ext4_journal_get_write_access(handle, dir_block);
+       de = (struct ext4_dir_entry_2 *) dir_block->b_data;
+@@ -1907,7 +1917,7 @@ retry:
+       de = ext4_next_entry(de);
+       de->inode = cpu_to_le32(dir->i_ino);
+       de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
+-                                              EXT4_DIR_REC_LEN(1));
++                                            EXT4_DIR_REC_LEN(1));
+       de->name_len = 2;
+       strcpy (de->name, "..");
+       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+@@ -1916,9 +1926,41 @@ retry:
+       ext4_journal_dirty_metadata(handle, dir_block);
+       brelse (dir_block);
+       ext4_mark_inode_dirty(handle, inode);
++get_out:
++      return err;
++}
++EXPORT_SYMBOL(ext4_add_dot_dotdot);
++
++static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
++{
++      handle_t *handle;
++      struct inode * inode;
++      int err, retries = 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 +
++                                      2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
++      if (IS_ERR(handle))
++              return PTR_ERR(handle);
++
++      if (IS_DIRSYNC(dir))
++              handle->h_sync = 1;
++
++      inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
++      err = PTR_ERR(inode);
++      if (IS_ERR(inode))
++              goto out_stop;
++
++      err = ext4_add_dot_dotdot(handle, dir, inode);
++      if (err)
++              goto out_stop;
++
+       err = ext4_add_entry (handle, dentry, inode);
+       if (err) {
+-out_clear_inode:
+               clear_nlink(inode);
+               ext4_mark_inode_dirty(handle, inode);
+               iput (inode);
+
diff --git a/ldiskfs/kernel_patches/patches/ext4-pdir-fix.patch b/ldiskfs/kernel_patches/patches/ext4-pdir-fix.patch
new file mode 100644 (file)
index 0000000..b9db2ed
--- /dev/null
@@ -0,0 +1,59 @@
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/ext4_i.h linux-2.6.27.21-0.1_2//fs/ext4/ext4_i.h
+--- linux-2.6.27.21-0.1_1//fs/ext4/ext4_i.h    2009-08-24 13:00:59.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/ext4_i.h    2009-08-24 13:01:25.000000000 +0530
+@@ -16,6 +16,7 @@
+ #ifndef _EXT4_I
+ #define _EXT4_I
++#include <linux/dynlocks.h>
+ #include <linux/rwsem.h>
+ #include <linux/rbtree.h>
+ #include <linux/seqlock.h>
+@@ -56,7 +57,9 @@ struct ext4_inode_info {
+       __u32   i_flags;
+       ext4_fsblk_t    i_file_acl;
+       __u32   i_dtime;
+-
++      /* following fields for parallel directory operations -bzzz */
++      struct dynlock   i_htree_lock;
++      struct semaphore i_append_sem;
+       /*
+        * i_block_group is the number of the block group which contains
+        * this file's inode.  Constant across the lifetime of the inode,
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/namei.c linux-2.6.27.21-0.1_2//fs/ext4/namei.c
+--- linux-2.6.27.21-0.1_1//fs/ext4/namei.c     2009-08-24 13:00:59.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/namei.c     2009-08-24 13:03:45.000000000 +0530
+@@ -55,6 +55,11 @@ static struct buffer_head *ext4_append(h
+                                       ext4_lblk_t *block, int *err)
+ {
+       struct buffer_head *bh;
++      struct ext4_inode_info *ei = EXT4_I(inode);
++
++      /* with parallel dir operations all appends
++      * have to be serialized -bzzz */
++      down(&ei->i_append_sem);
+       *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
+@@ -67,7 +72,9 @@ static struct buffer_head *ext4_append(h
+                       brelse(bh);
+                       bh = NULL;
+               }
++              ei->i_disksize = inode->i_size;
+       }
++      up(&ei->i_append_sem);
+       return bh;
+ }
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/super.c linux-2.6.27.21-0.1_2//fs/ext4/super.c
+--- linux-2.6.27.21-0.1_1//fs/ext4/super.c     2009-08-24 13:00:59.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/super.c     2009-08-24 13:01:25.000000000 +0530
+@@ -635,6 +635,8 @@ static struct inode *ext4_alloc_inode(st
+ #endif
+       ei->vfs_inode.i_version = 1;
+       ei->vfs_inode.i_data.writeback_index = 0;
++      dynlock_init(&ei->i_htree_lock);
++      sema_init(&ei->i_append_sem, 1);
+       memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
+       INIT_LIST_HEAD(&ei->i_prealloc_list);
+       spin_lock_init(&ei->i_prealloc_lock);
index 8606846..4e89ef8 100644 (file)
@@ -23,3 +23,9 @@ ext4-convert-group-lock-rhel5.patch
 ext4-force_over_8tb-rhel5.patch
 ext4_ext_search_right-fix.patch
 ext4-pa_lock-typo.patch
+ext4-pdir-fix.patch
+ext4-osd-iop-common.patch
+ext4-osd-iam-exports.patch
+ext4-dynlocks-common.patch
+ext4-dynlocks-2.6-rhel5.patch
+ext4-hash-indexed-dir-dotdot-update.patch
index 0257bce..2c55020 100644 (file)
@@ -26,4 +26,10 @@ ext3-journal-chksum-2.6.18-vanilla.patch
 ext3-get-raid-stripe-from-sb.patch
 ext3-big-endian-check-2.6-rhel5.patch
 alloc-policy-2.6-rhlel5.diff
-ext3-force_over_8tb-rhel5.patch 
+ext3-force_over_8tb-rhel5.patch
+ext3-pdir-fix.patch
+ext3-osd-iop-common.patch
+ext3-osd-iam-exports.patch
+ext3-dynlocks-common.patch
+ext3-dynlocks-2.6-rhel5.patch
+ext3-hash-indexed-dir-dotdot-update.patch
index b526868..885df46 100644 (file)
@@ -32,3 +32,9 @@ ext3-get-raid-stripe-from-sb.patch
 ext3-big-endian-check-2.6-sles10.patch
 alloc-policy-2.6-rhlel5.diff
 ext3-force_over_8tb-sles10.patch
+ext3-pdir-fix.patch
+ext3-osd-iop-common.patch
+ext3-osd-iam-exports.patch
+ext3-dynlocks-common.patch
+ext3-dynlocks-2.6-rhel5.patch
+ext3-hash-indexed-dir-dotdot-update.patch
index 2f35a0b..226eea2 100644 (file)
@@ -26,3 +26,9 @@ ext4-force_over_8tb-sles11.patch
 ext4-claim_inode-free_inode-race.patch
 ext4_ext_search_right-fix.patch
 ext4-pa_lock-typo.patch
+ext4-pdir-fix.patch
+ext4-osd-iop-common-sles11.patch
+ext4-osd-iam-exports.patch
+ext4-dynlocks-common-sles11.patch
+ext4-dynlocks-2.6-rhel5.patch
+ext4-hash-indexed-dir-dotdot-update.patch
index 7f369b2..71d312d 100644 (file)
@@ -10,10 +10,10 @@ linux_headers := $(wildcard @LINUX@/include/linux/@BACKFS@*.h)
 
 backfs_sources := $(filter-out %.mod.c,$(wildcard @LINUX@/fs/@BACKFS@/*.c))
 
-ext3_new_sources := iopen.c iopen.h extents.c mballoc.c group.h fiemap.h
-ext3_new_headers := ext3_extents.h 
+ext3_new_sources := iopen.c iopen.h extents.c mballoc.c group.h dynlocks.c fiemap.h
+ext3_new_headers := ext3_extents.h
 
-ext4_new_sources := iopen.c iopen.h fiemap.h
+ext4_new_sources := iopen.c iopen.h  dynlocks.c fiemap.h
 ext4_new_headers :=
 
 new_sources := $(@BACKFS@_new_sources)
index 13a9558..65d04a7 100644 (file)
@@ -62,6 +62,11 @@ endif
                        linux-stage/include/linux/@BACKFS@$$i \
                        > linux/ldiskfs$$i ; \
        done
+       sed $(strip $(ldiskfs_sed_flags)) \
+        linux-stage/include/linux/dynlocks.h \
+        > linux/dynlocks.h
+
+
        @echo
        touch sources