]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.suse/reiserfs-journaled-xattrs.diff
Imported linux-2.6.27.39 suse/xen patches.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / reiserfs-journaled-xattrs.diff
diff --git a/src/patches/suse-2.6.27.31/patches.suse/reiserfs-journaled-xattrs.diff b/src/patches/suse-2.6.27.31/patches.suse/reiserfs-journaled-xattrs.diff
deleted file mode 100644 (file)
index de58d89..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-From: Jeff Mahoney <jeffm@suse.com>
-Subject: reiserfs: journaled xattrs
-
- Deadlocks are possible in the xattr code between the journal lock and the
- xattr sems.
-
- This patch implements journalling for xattr operations. The benefit is
- twofold:
- * It gets rid of the deadlock possibility by always ensuring that xattr
-   write operations are initiated inside a transaction.
- * It corrects the problem where xattr backing files aren't considered any
-   differently than normal files, despite the fact they are metadata.
-
- I discussed the added journal load with Chris Mason, and we decided that
- since xattrs (versus other journal activity) is fairly rare, the introduction
- of larger transactions to support journaled xattrs wouldn't be too big a deal.
-
-Signed-off-by: Jeff Mahoney <jeffm@suse.com>
-
---
- fs/reiserfs/inode.c            |    3 -
- fs/reiserfs/namei.c            |   14 +----
- fs/reiserfs/xattr.c            |   39 +++++++++++----
- fs/reiserfs/xattr_acl.c        |  105 +++++++++++++++++++++++++++++++----------
- include/linux/reiserfs_acl.h   |    3 -
- include/linux/reiserfs_fs.h    |    4 +
- include/linux/reiserfs_xattr.h |   40 ++++++++++++++-
- 7 files changed, 159 insertions(+), 49 deletions(-)
-
---- a/fs/reiserfs/inode.c
-+++ b/fs/reiserfs/inode.c
-@@ -1919,9 +1919,8 @@ int reiserfs_new_inode(struct reiserfs_t
-               goto out_inserted_sd;
-       }
--      /* XXX CHECK THIS */
-       if (reiserfs_posixacl(inode->i_sb)) {
--              retval = reiserfs_inherit_default_acl(dir, dentry, inode);
-+              retval = reiserfs_inherit_default_acl(th, dir, dentry, inode);
-               if (retval) {
-                       err = retval;
-                       reiserfs_check_path(&path_to_key);
---- a/fs/reiserfs/namei.c
-+++ b/fs/reiserfs/namei.c
-@@ -607,15 +607,13 @@ static int reiserfs_create(struct inode 
-           2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
-                REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
-       struct reiserfs_transaction_handle th;
--      int locked;
-       if (!(inode = new_inode(dir->i_sb))) {
-               return -ENOMEM;
-       }
-       new_inode_init(inode, dir, mode);
--      locked = reiserfs_cache_default_acl(dir);
--
-+      jbegin_count += reiserfs_cache_default_acl(dir);
-       reiserfs_write_lock(dir->i_sb);
-       retval = journal_begin(&th, dir->i_sb, jbegin_count);
-@@ -669,7 +667,6 @@ static int reiserfs_mknod(struct inode *
-           JOURNAL_PER_BALANCE_CNT * 3 +
-           2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
-                REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
--      int locked;
-       if (!new_valid_dev(rdev))
-               return -EINVAL;
-@@ -679,8 +676,7 @@ static int reiserfs_mknod(struct inode *
-       }
-       new_inode_init(inode, dir, mode);
--      locked = reiserfs_cache_default_acl(dir);
--
-+      jbegin_count += reiserfs_cache_default_acl(dir);
-       reiserfs_write_lock(dir->i_sb);
-       retval = journal_begin(&th, dir->i_sb, jbegin_count);
-@@ -737,7 +733,6 @@ static int reiserfs_mkdir(struct inode *
-           JOURNAL_PER_BALANCE_CNT * 3 +
-           2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
-                REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
--      int locked;
- #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-       /* set flag that new packing locality created and new blocks for the content     * of that directory are not displaced yet */
-@@ -749,8 +744,7 @@ static int reiserfs_mkdir(struct inode *
-       }
-       new_inode_init(inode, dir, mode);
--      locked = reiserfs_cache_default_acl(dir);
--
-+      jbegin_count += reiserfs_cache_default_acl(dir);
-       reiserfs_write_lock(dir->i_sb);
-       retval = journal_begin(&th, dir->i_sb, jbegin_count);
-@@ -1037,8 +1031,6 @@ static int reiserfs_symlink(struct inode
-       memcpy(name, symname, strlen(symname));
-       padd_item(name, item_len, strlen(symname));
--      /* We would inherit the default ACL here, but symlinks don't get ACLs */
--
-       retval = journal_begin(&th, parent_dir->i_sb, jbegin_count);
-       if (retval) {
-               drop_new_inode(inode);
---- a/fs/reiserfs/xattr_acl.c
-+++ b/fs/reiserfs/xattr_acl.c
-@@ -10,15 +10,17 @@
- #include <linux/reiserfs_acl.h>
- #include <asm/uaccess.h>
--static int reiserfs_set_acl(struct inode *inode, int type,
-+static int reiserfs_set_acl(struct reiserfs_transaction_handle *th,
-+                          struct inode *inode, int type,
-                           struct posix_acl *acl);
- static int
- xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
- {
-       struct posix_acl *acl;
--      int error;
--
-+      int error, error2;
-+      struct reiserfs_transaction_handle th;
-+      size_t jcreate_blocks;
-       if (!reiserfs_posixacl(inode->i_sb))
-               return -EOPNOTSUPP;
-       if (!is_owner_or_cap(inode))
-@@ -36,7 +38,21 @@ xattr_set_acl(struct inode *inode, int t
-       } else
-               acl = NULL;
--      error = reiserfs_set_acl(inode, type, acl);
-+      /* Pessimism: We can't assume that anything from the xattr root up
-+       * has been created. */
-+
-+      jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) +
-+                       reiserfs_xattr_nblocks(inode, size) * 2;
-+
-+      reiserfs_write_lock(inode->i_sb);
-+      error = journal_begin(&th, inode->i_sb, jcreate_blocks);
-+      if (error == 0) {
-+              error = reiserfs_set_acl(&th, inode, type, acl);
-+              error2 = journal_end(&th, inode->i_sb, jcreate_blocks);
-+              if (error2)
-+                      error = error2;
-+      }
-+      reiserfs_write_unlock(inode->i_sb);
-       release_and_out:
-       posix_acl_release(acl);
-@@ -266,7 +282,8 @@ struct posix_acl *reiserfs_get_acl(struc
-  * BKL held [before 2.5.x]
-  */
- static int
--reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
-+reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
-+               int type, struct posix_acl *acl)
- {
-       char *name;
-       void *value = NULL;
-@@ -310,7 +327,7 @@ reiserfs_set_acl(struct inode *inode, in
-                       return (int)PTR_ERR(value);
-       }
--      error = __reiserfs_xattr_set(inode, name, value, size, 0);
-+      error = reiserfs_xattr_set_handle(th, inode, name, value, size, 0);
-       /*
-        * Ensure that the inode gets dirtied if we're only using
-@@ -337,7 +354,8 @@ reiserfs_set_acl(struct inode *inode, in
- /* dir->i_mutex: locked,
-  * inode is new and not released into the wild yet */
- int
--reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
-+reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
-+                           struct inode *dir, struct dentry *dentry,
-                            struct inode *inode)
- {
-       struct posix_acl *acl;
-@@ -374,7 +392,8 @@ reiserfs_inherit_default_acl(struct inod
-               /* Copy the default ACL to the default ACL of a new directory */
-               if (S_ISDIR(inode->i_mode)) {
--                      err = reiserfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
-+                      err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT,
-+                                             acl);
-                       if (err)
-                               goto cleanup;
-               }
-@@ -395,9 +414,9 @@ reiserfs_inherit_default_acl(struct inod
-                       /* If we need an ACL.. */
-                       if (need_acl > 0) {
--                              err =
--                                  reiserfs_set_acl(inode, ACL_TYPE_ACCESS,
--                                                   acl_copy);
-+                              err = reiserfs_set_acl(th, inode,
-+                                                     ACL_TYPE_ACCESS,
-+                                                     acl_copy);
-                               if (err)
-                                       goto cleanup_copy;
-                       }
-@@ -415,21 +434,45 @@ reiserfs_inherit_default_acl(struct inod
-       return err;
- }
--/* Looks up and caches the result of the default ACL.
-- * We do this so that we don't need to carry the xattr_sem into
-- * reiserfs_new_inode if we don't need to */
-+/* This is used to cache the default acl before a new object is created.
-+ * The biggest reason for this is to get an idea of how many blocks will
-+ * actually be required for the create operation if we must inherit an ACL.
-+ * An ACL write can add up to 3 object creations and an additional file write
-+ * so we'd prefer not to reserve that many blocks in the journal if we can.
-+ * It also has the advantage of not loading the ACL with a transaction open,
-+ * this may seem silly, but if the owner of the directory is doing the
-+ * creation, the ACL may not be loaded since the permissions wouldn't require
-+ * it.
-+ * We return the number of blocks required for the transaction.
-+ */
- int reiserfs_cache_default_acl(struct inode *inode)
- {
--      int ret = 0;
--      if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) {
--              struct posix_acl *acl;
--              acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
--              ret = (acl && !IS_ERR(acl));
--              if (ret)
--                      posix_acl_release(acl);
-+      struct posix_acl *acl;
-+      int nblocks = 0;
-+
-+      if (IS_PRIVATE(inode))
-+              return 0;
-+
-+      acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
-+
-+      if (acl && !IS_ERR(acl)) {
-+              int size = reiserfs_acl_size(acl->a_count);
-+
-+              /* Other xattrs can be created during inode creation. We don't
-+               * want to claim too many blocks, so we check to see if we
-+               * we need to create the tree to the xattrs, and then we
-+               * just want two files. */
-+              nblocks = reiserfs_xattr_jcreate_nblocks(inode);
-+              nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
-+
-+              REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
-+
-+              /* We need to account for writes + bitmaps for two files */
-+              nblocks += reiserfs_xattr_nblocks(inode, size) * 4;
-+              posix_acl_release(acl);
-       }
--      return ret;
-+      return nblocks;
- }
- int reiserfs_acl_chmod(struct inode *inode)
-@@ -455,8 +498,22 @@ int reiserfs_acl_chmod(struct inode *ino
-       if (!clone)
-               return -ENOMEM;
-       error = posix_acl_chmod_masq(clone, inode->i_mode);
--      if (!error)
--              error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
-+      if (!error) {
-+              struct reiserfs_transaction_handle th;
-+              size_t size = reiserfs_xattr_nblocks(inode,
-+                                           reiserfs_acl_size(clone->a_count));
-+              reiserfs_write_lock(inode->i_sb);
-+              error = journal_begin(&th, inode->i_sb, size * 2);
-+              if (!error) {
-+                      int error2;
-+                      error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS,
-+                                               clone);
-+                      error2 = journal_end(&th, inode->i_sb, size * 2);
-+                      if (error2)
-+                              error = error2;
-+              }
-+              reiserfs_write_unlock(inode->i_sb);
-+      }
-       posix_acl_release(clone);
-       return error;
- }
---- a/fs/reiserfs/xattr.c
-+++ b/fs/reiserfs/xattr.c
-@@ -632,8 +632,9 @@ out_dput:
-  * inode->i_mutex: down
-  */
- int
--__reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
--                   size_t buffer_size, int flags)
-+reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
-+                        struct inode *inode, const char *name,
-+                        const void *buffer, size_t buffer_size, int flags)
- {
-       int err = 0;
-       struct dentry *dentry;
-@@ -723,14 +724,34 @@ out_unlock:
-       return err;
- }
--int
--reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
--                   size_t buffer_size, int flags)
-+/* We need to start a transaction to maintain lock ordering */
-+int reiserfs_xattr_set(struct inode *inode, const char *name,
-+                     const void *buffer, size_t buffer_size, int flags)
- {
--      int err = __reiserfs_xattr_set(inode, name, buffer, buffer_size, flags);
--      if (err == -ENODATA)
--              err = 0;
--      return err;
-+
-+      struct reiserfs_transaction_handle th;
-+      int error, error2;
-+      size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size);
-+
-+      if (!(flags & XATTR_REPLACE))
-+              jbegin_count += reiserfs_xattr_jcreate_nblocks(inode);
-+
-+      reiserfs_write_lock(inode->i_sb);
-+      error = journal_begin(&th, inode->i_sb, jbegin_count);
-+      if (error) {
-+              reiserfs_write_unlock(inode->i_sb);
-+              return error;
-+      }
-+
-+      error = reiserfs_xattr_set_handle(&th, inode, name,
-+                                        buffer, buffer_size, flags);
-+
-+      error2 = journal_end(&th, inode->i_sb, jbegin_count);
-+      if (error == 0)
-+              error = error2;
-+      reiserfs_write_unlock(inode->i_sb);
-+
-+      return error;
- }
- /*
---- a/include/linux/reiserfs_acl.h
-+++ b/include/linux/reiserfs_acl.h
-@@ -49,7 +49,8 @@ static inline int reiserfs_acl_count(siz
- #ifdef CONFIG_REISERFS_FS_POSIX_ACL
- struct posix_acl *reiserfs_get_acl(struct inode *inode, int type);
- int reiserfs_acl_chmod(struct inode *inode);
--int reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
-+int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
-+                               struct inode *dir, struct dentry *dentry,
-                                struct inode *inode);
- int reiserfs_cache_default_acl(struct inode *dir);
- extern struct xattr_handler reiserfs_posix_acl_default_handler;
---- a/include/linux/reiserfs_fs.h
-+++ b/include/linux/reiserfs_fs.h
-@@ -1615,6 +1615,10 @@ struct reiserfs_journal_header {
- #define JOURNAL_MAX_COMMIT_AGE 30
- #define JOURNAL_MAX_TRANS_AGE 30
- #define JOURNAL_PER_BALANCE_CNT (3 * (MAX_HEIGHT-2) + 9)
-+#define JOURNAL_BLOCKS_PER_OBJECT(sb)  (JOURNAL_PER_BALANCE_CNT * 3 + \
-+                                       2 * (REISERFS_QUOTA_INIT_BLOCKS(sb) + \
-+                                            REISERFS_QUOTA_TRANS_BLOCKS(sb)))
-+
- #ifdef CONFIG_QUOTA
- /* We need to update data and inode (atime) */
- #define REISERFS_QUOTA_TRANS_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<<REISERFS_QUOTA) ? 2 : 0)
---- a/include/linux/reiserfs_xattr.h
-+++ b/include/linux/reiserfs_xattr.h
-@@ -46,14 +46,50 @@ int reiserfs_removexattr(struct dentry *
- int reiserfs_permission(struct inode *inode, int mask);
- int reiserfs_xattr_get(struct inode *, const char *, void *, size_t);
--int __reiserfs_xattr_set(struct inode *, const char *, const void *,
--                       size_t, int);
- int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int);
-+int reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *,
-+                            struct inode *, const char *, const void *,
-+                            size_t, int);
- extern struct xattr_handler reiserfs_xattr_user_handler;
- extern struct xattr_handler reiserfs_xattr_trusted_handler;
- extern struct xattr_handler reiserfs_xattr_security_handler;
-+#define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header))
-+static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size)
-+{
-+      loff_t ret = 0;
-+      if (reiserfs_file_data_log(inode)) {
-+              ret = _ROUND_UP(xattr_size(size), inode->i_sb->s_blocksize);
-+              ret >>= inode->i_sb->s_blocksize_bits;
-+      }
-+      return ret;
-+}
-+
-+/* We may have to create up to 3 objects: xattr root, xattr dir, xattr file.
-+ * Let's try to be smart about it.
-+ * xattr root: We cache it. If it's not cached, we may need to create it.
-+ * xattr dir: If anything has been loaded for this inode, we can set a flag
-+ *            saying so.
-+ * xattr file: Since we don't cache xattrs, we can't tell. We always include
-+ *             blocks for it.
-+ *
-+ * However, since root and dir can be created between calls - YOU MUST SAVE
-+ * THIS VALUE.
-+ */
-+static inline size_t reiserfs_xattr_jcreate_nblocks(struct inode *inode)
-+{
-+      size_t nblocks = JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
-+
-+      if ((REISERFS_I(inode)->i_flags & i_has_xattr_dir) == 0) {
-+              nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
-+              if (REISERFS_SB(inode->i_sb)->xattr_root == NULL)
-+                      nblocks += JOURNAL_BLOCKS_PER_OBJECT(inode->i_sb);
-+      }
-+
-+      return nblocks;
-+}
-+
- static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
- {
-       init_rwsem(&REISERFS_I(inode)->i_xattr_sem);