]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2016 00:14:05 +0000 (17:14 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2016 00:14:05 +0000 (17:14 -0700)
Pull vfs fixes from Al Viro:
 "Followups to the parallel lookup work:

   - update docs

   - restore killability of the places that used to take ->i_mutex
     killably now that we have down_write_killable() merged

   - Additionally, it turns out that I missed a prerequisite for
     security_d_instantiate() stuff - ->getxattr() wasn't the only thing
     that could be called before dentry is attached to inode; with smack
     we needed the same treatment applied to ->setxattr() as well"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  switch ->setxattr() to passing dentry and inode separately
  switch xattr_handler->set() to passing dentry and inode separately
  restore killability of old mutex_lock_killable(&inode->i_mutex) users
  add down_write_killable_nested()
  update D/f/directory-locking

58 files changed:
Documentation/filesystems/directory-locking
Documentation/filesystems/porting
drivers/staging/lustre/lustre/llite/llite_internal.h
drivers/staging/lustre/lustre/llite/xattr.c
fs/9p/acl.c
fs/9p/xattr.c
fs/bad_inode.c
fs/btrfs/ioctl.c
fs/btrfs/xattr.c
fs/ceph/xattr.c
fs/cifs/xattr.c
fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/inode.c
fs/ecryptfs/mmap.c
fs/ext2/xattr_security.c
fs/ext2/xattr_trusted.c
fs/ext2/xattr_user.c
fs/ext4/xattr_security.c
fs/ext4/xattr_trusted.c
fs/ext4/xattr_user.c
fs/f2fs/xattr.c
fs/fuse/dir.c
fs/gfs2/xattr.c
fs/hfs/attr.c
fs/hfs/hfs_fs.h
fs/hfsplus/xattr.c
fs/hfsplus/xattr.h
fs/hfsplus/xattr_security.c
fs/hfsplus/xattr_trusted.c
fs/hfsplus/xattr_user.c
fs/jffs2/security.c
fs/jffs2/xattr_trusted.c
fs/jffs2/xattr_user.c
fs/jfs/xattr.c
fs/kernfs/inode.c
fs/kernfs/kernfs-internal.h
fs/libfs.c
fs/nfs/nfs4proc.c
fs/ocfs2/xattr.c
fs/orangefs/xattr.c
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/overlayfs/readdir.c
fs/posix_acl.c
fs/readdir.c
fs/reiserfs/xattr_security.c
fs/reiserfs/xattr_trusted.c
fs/reiserfs/xattr_user.c
fs/ubifs/xattr.c
fs/xattr.c
fs/xfs/xfs_xattr.c
include/linux/fs.h
include/linux/rwsem.h
include/linux/xattr.h
kernel/locking/rwsem.c
mm/shmem.c
security/smack/smack_lsm.c

index 09bbf9a54f808363b72b78e89e2284cb60157a7f..c314badbcfc63c94b49f56a49dda4105f58b2d69 100644 (file)
@@ -1,30 +1,37 @@
        Locking scheme used for directory operations is based on two
-kinds of locks - per-inode (->i_mutex) and per-filesystem
+kinds of locks - per-inode (->i_rwsem) and per-filesystem
 (->s_vfs_rename_mutex).
 
-       When taking the i_mutex on multiple non-directory objects, we
+       When taking the i_rwsem on multiple non-directory objects, we
 always acquire the locks in order by increasing address.  We'll call
 that "inode pointer" order in the following.
 
        For our purposes all operations fall in 5 classes:
 
 1) read access.  Locking rules: caller locks directory we are accessing.
+The lock is taken shared.
 
-2) object creation.  Locking rules: same as above.
+2) object creation.  Locking rules: same as above, but the lock is taken
+exclusive.
 
 3) object removal.  Locking rules: caller locks parent, finds victim,
-locks victim and calls the method.
+locks victim and calls the method.  Locks are exclusive.
 
 4) rename() that is _not_ cross-directory.  Locking rules: caller locks
-the parent and finds source and target.  If target already exists, lock
-it.  If source is a non-directory, lock it.  If that means we need to
-lock both, lock them in inode pointer order.
+the parent and finds source and target.  In case of exchange (with
+RENAME_EXCHANGE in rename2() flags argument) lock both.  In any case,
+if the target already exists, lock it.  If the source is a non-directory,
+lock it.  If we need to lock both, lock them in inode pointer order.
+Then call the method.  All locks are exclusive.
+NB: we might get away with locking the the source (and target in exchange
+case) shared.
 
 5) link creation.  Locking rules:
        * lock parent
        * check that source is not a directory
        * lock source
        * call the method.
+All locks are exclusive.
 
 6) cross-directory rename.  The trickiest in the whole bunch.  Locking
 rules:
@@ -35,11 +42,12 @@ rules:
                fail with -ENOTEMPTY
        * if new parent is equal to or is a descendent of source
                fail with -ELOOP
-       * If target exists, lock it.  If source is a non-directory, lock
-         it.  In case that means we need to lock both source and target,
-         do so in inode pointer order.
+       * If it's an exchange, lock both the source and the target.
+       * If the target exists, lock it.  If the source is a non-directory,
+         lock it.  If we need to lock both, do so in inode pointer order.
        * call the method.
-
+All ->i_rwsem are taken exclusive.  Again, we might get away with locking
+the the source (and target in exchange case) shared.
 
 The rules above obviously guarantee that all directories that are going to be
 read, modified or removed by method will be locked by caller.
@@ -73,7 +81,7 @@ objects - A < B iff A is an ancestor of B.
 attempt to acquire some lock and already holds at least one lock.  Let's
 consider the set of contended locks.  First of all, filesystem lock is
 not contended, since any process blocked on it is not holding any locks.
-Thus all processes are blocked on ->i_mutex.
+Thus all processes are blocked on ->i_rwsem.
 
        By (3), any process holding a non-directory lock can only be
 waiting on another non-directory lock with a larger address.  Therefore
index 46f3bb7a02f5fc783327b724227926b774d432dd..a5fb89cac615c1c3fe0091b602932dcf29c9dc9d 100644 (file)
@@ -578,3 +578,10 @@ in your dentry operations instead.
 --
 [mandatory]
        ->atomic_open() calls without O_CREAT may happen in parallel.
+--
+[mandatory]
+       ->setxattr() and xattr_handler.set() get dentry and inode passed separately.
+       dentry might be yet to be attached to inode, so do _not_ use its ->d_inode
+       in the instances.  Rationale: !@#!@# security_d_instantiate() needs to be
+       called before we attach dentry to inode and !@#!@##!@$!$#!@#$!@$!@$ smack
+       ->d_instantiate() uses not just ->getxattr() but ->setxattr() as well.
index ce1f949430f1aeca2e43f5f26e24629d595032a9..3f2f30b6542c727cc17e56b534f3f12317ddb2e2 100644 (file)
@@ -976,8 +976,8 @@ static inline __u64 ll_file_maxbytes(struct inode *inode)
 }
 
 /* llite/xattr.c */
-int ll_setxattr(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags);
+int ll_setxattr(struct dentry *dentry, struct inode *inode,
+               const char *name, const void *value, size_t size, int flags);
 ssize_t ll_getxattr(struct dentry *dentry, struct inode *inode,
                    const char *name, void *buffer, size_t size);
 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
index ed4de04381c3fbf438266bd9618b31a4bc7bad66..608014b0dbcd6e33415680349e73fd6dbff54e03 100644 (file)
@@ -211,11 +211,9 @@ int ll_setxattr_common(struct inode *inode, const char *name,
        return 0;
 }
 
-int ll_setxattr(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags)
+int ll_setxattr(struct dentry *dentry, struct inode *inode,
+               const char *name, const void *value, size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
-
        LASSERT(inode);
        LASSERT(name);
 
index eb3589edf485c0e165790f68c6def83ceab8dac2..0576eaeb60b952341f8b739db4e458128aab757c 100644 (file)
@@ -239,13 +239,13 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
 }
 
 static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
-                             struct dentry *dentry, const char *name,
-                             const void *value, size_t size, int flags)
+                             struct dentry *dentry, struct inode *inode,
+                             const char *name, const void *value,
+                             size_t size, int flags)
 {
        int retval;
        struct posix_acl *acl;
        struct v9fs_session_info *v9ses;
-       struct inode *inode = d_inode(dentry);
 
        v9ses = v9fs_dentry2v9ses(dentry);
        /*
index 18c62bae95917d40653e1ffc5c62e372c3b99456..a6bd349bab23ef02b7b46ccbba320c7191305879 100644 (file)
@@ -147,8 +147,9 @@ static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
 }
 
 static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
-                                 struct dentry *dentry, const char *name,
-                                 const void *value, size_t size, int flags)
+                                 struct dentry *dentry, struct inode *inode,
+                                 const char *name, const void *value,
+                                 size_t size, int flags)
 {
        const char *full_name = xattr_full_name(handler, name);
 
index 72e35b721608e6a1e8468656acf6478a58440b64..3ba385eaa26ee0131e5e3eaf7bfed77290222942 100644 (file)
@@ -100,8 +100,8 @@ static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs)
        return -EIO;
 }
 
-static int bad_inode_setxattr(struct dentry *dentry, const char *name,
-               const void *value, size_t size, int flags)
+static int bad_inode_setxattr(struct dentry *dentry, struct inode *inode,
+               const char *name, const void *value, size_t size, int flags)
 {
        return -EIO;
 }
index 001c111e56276ca91aa7b1b497a396cd55103cd2..05173563e4a6b9068b6c02f62b4dfd400b325ca5 100644 (file)
@@ -846,11 +846,9 @@ static noinline int btrfs_mksubvol(struct path *parent,
        struct dentry *dentry;
        int error;
 
-       inode_lock_nested(dir, I_MUTEX_PARENT);
-       // XXX: should've been
-       // mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT);
-       // if (error == -EINTR)
-       //      return error;
+       error = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT);
+       if (error == -EINTR)
+               return error;
 
        dentry = lookup_one_len(name, parent->dentry, namelen);
        error = PTR_ERR(dentry);
@@ -2377,11 +2375,9 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                goto out;
 
 
-       inode_lock_nested(dir, I_MUTEX_PARENT);
-       // XXX: should've been
-       // err = mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT);
-       // if (err == -EINTR)
-       //      goto out_drop_write;
+       err = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT);
+       if (err == -EINTR)
+               goto out_drop_write;
        dentry = lookup_one_len(vol_args->name, parent, namelen);
        if (IS_ERR(dentry)) {
                err = PTR_ERR(dentry);
@@ -2571,7 +2567,7 @@ out_dput:
        dput(dentry);
 out_unlock_dir:
        inode_unlock(dir);
-//out_drop_write:
+out_drop_write:
        mnt_drop_write_file(file);
 out:
        kfree(vol_args);
index 3bfb252206c7c678f5da79333543fa3ce0af8659..d1a177a3dbe89e29f0d9356b765549334d829d64 100644 (file)
@@ -380,23 +380,21 @@ static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
 }
 
 static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
-                                  struct dentry *dentry, const char *name,
-                                  const void *buffer, size_t size,
-                                  int flags)
+                                  struct dentry *unused, struct inode *inode,
+                                  const char *name, const void *buffer,
+                                  size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
-
        name = xattr_full_name(handler, name);
        return __btrfs_setxattr(NULL, inode, name, buffer, size, flags);
 }
 
 static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
-                                       struct dentry *dentry,
+                                       struct dentry *unused, struct inode *inode,
                                        const char *name, const void *value,
                                        size_t size, int flags)
 {
        name = xattr_full_name(handler, name);
-       return btrfs_set_prop(d_inode(dentry), name, value, size, flags);
+       return btrfs_set_prop(inode, name, value, size, flags);
 }
 
 static const struct xattr_handler btrfs_security_xattr_handler = {
index dacc1bd8562974022befe05446db1b50afc0f6ad..4870b29df22460dcf1617e32fe04a7283de96a07 100644 (file)
@@ -1056,12 +1056,13 @@ static int ceph_get_xattr_handler(const struct xattr_handler *handler,
 }
 
 static int ceph_set_xattr_handler(const struct xattr_handler *handler,
-                                 struct dentry *dentry, const char *name,
-                                 const void *value, size_t size, int flags)
+                                 struct dentry *unused, struct inode *inode,
+                                 const char *name, const void *value,
+                                 size_t size, int flags)
 {
        if (!ceph_is_valid_xattr(name))
                return -EOPNOTSUPP;
-       return __ceph_setxattr(d_inode(dentry), name, value, size, flags);
+       return __ceph_setxattr(inode, name, value, size, flags);
 }
 
 const struct xattr_handler ceph_other_xattr_handler = {
index c8b77aa24a1dbaac372c5107b1540a2dcde70ccf..5e23f64c0804ba647017cfa82808c4da85ff4760 100644 (file)
@@ -39,8 +39,9 @@
 enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT };
 
 static int cifs_xattr_set(const struct xattr_handler *handler,
-                         struct dentry *dentry, const char *name,
-                         const void *value, size_t size, int flags)
+                         struct dentry *dentry, struct inode *inode,
+                         const char *name, const void *value,
+                         size_t size, int flags)
 {
        int rc = -EOPNOTSUPP;
        unsigned int xid;
@@ -99,12 +100,12 @@ static int cifs_xattr_set(const struct xattr_handler *handler,
                        if (value &&
                            pTcon->ses->server->ops->set_acl)
                                rc = pTcon->ses->server->ops->set_acl(pacl,
-                                               size, d_inode(dentry),
+                                               size, inode,
                                                full_path, CIFS_ACL_DACL);
                        else
                                rc = -EOPNOTSUPP;
                        if (rc == 0) /* force revalidate of the inode */
-                               CIFS_I(d_inode(dentry))->time = 0;
+                               CIFS_I(inode)->time = 0;
                        kfree(pacl);
                }
 #endif /* CONFIG_CIFS_ACL */
index ebd40f46ed4c455ef48a0dc8008127a98e956a6d..0d8eb3455b34d68cde59a48b5b46da9b67498445 100644 (file)
@@ -1141,12 +1141,13 @@ ecryptfs_write_metadata_to_contents(struct inode *ecryptfs_inode,
 
 static int
 ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
+                                struct inode *ecryptfs_inode,
                                 char *page_virt, size_t size)
 {
        int rc;
 
-       rc = ecryptfs_setxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME, page_virt,
-                              size, 0);
+       rc = ecryptfs_setxattr(ecryptfs_dentry, ecryptfs_inode,
+                              ECRYPTFS_XATTR_NAME, page_virt, size, 0);
        return rc;
 }
 
@@ -1215,8 +1216,8 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
                goto out_free;
        }
        if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-               rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt,
-                                                     size);
+               rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, ecryptfs_inode,
+                                                     virt, size);
        else
                rc = ecryptfs_write_metadata_to_contents(ecryptfs_inode, virt,
                                                         virt_len);
index 3ec495db7e827b0d865e32152952ed046995ab4f..4ba1547bb9adc861c0598ad3ff200f110d3f4614 100644 (file)
@@ -609,8 +609,8 @@ ssize_t
 ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
                        const char *name, void *value, size_t size);
 int
-ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
-                 size_t size, int flags);
+ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
+                 const void *value, size_t size, int flags);
 int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
 #ifdef CONFIG_ECRYPT_FS_MESSAGING
 int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
index 318b04689d769b5da80d6ee39f6ded153a08e725..9d153b6a1d72308ae7130233697082b7028a3e51 100644 (file)
@@ -1001,7 +1001,8 @@ static int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 }
 
 int
-ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
+                 const char *name, const void *value,
                  size_t size, int flags)
 {
        int rc = 0;
@@ -1014,8 +1015,8 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
        }
 
        rc = vfs_setxattr(lower_dentry, name, value, size, flags);
-       if (!rc && d_really_is_positive(dentry))
-               fsstack_copy_attr_all(d_inode(dentry), d_inode(lower_dentry));
+       if (!rc && inode)
+               fsstack_copy_attr_all(inode, d_inode(lower_dentry));
 out:
        return rc;
 }
index 148d11b514fb4f04435993086bee782de361f5ad..9c3437c8a5b12ae107978266e067bd8ef35f815f 100644 (file)
@@ -442,7 +442,8 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
        if (size < 0)
                size = 8;
        put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
-       rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
+       rc = lower_inode->i_op->setxattr(lower_dentry, lower_inode,
+                                        ECRYPTFS_XATTR_NAME,
                                         xattr_virt, size, 0);
        inode_unlock(lower_inode);
        if (rc)
index 7fd3b867ce65fec8d7310fa021fba9821e238c14..7b9e9c1842d5232ceb20f2aeebda31cacb5855fd 100644 (file)
@@ -18,10 +18,11 @@ ext2_xattr_security_get(const struct xattr_handler *handler,
 
 static int
 ext2_xattr_security_set(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags)
+                       struct dentry *unused, struct inode *inode,
+                       const char *name, const void *value,
+                       size_t size, int flags)
 {
-       return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name,
+       return ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY, name,
                              value, size, flags);
 }
 
index 0f85705ff519860b86e278a57152a9708d8d1d17..65049b71af137d7f75f162f81ebd808b5fc3c0d0 100644 (file)
@@ -25,10 +25,11 @@ ext2_xattr_trusted_get(const struct xattr_handler *handler,
 
 static int
 ext2_xattr_trusted_set(const struct xattr_handler *handler,
-                      struct dentry *dentry, const char *name,
-                      const void *value, size_t size, int flags)
+                      struct dentry *unused, struct inode *inode,
+                      const char *name, const void *value,
+                      size_t size, int flags)
 {
-       return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name,
+       return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name,
                              value, size, flags);
 }
 
index 1fafd27037ccd72a5c7a59cfb3afa1eb9ef356ca..fb2f992ae763a59c3081713d6d95c93c035d83f9 100644 (file)
@@ -29,13 +29,14 @@ ext2_xattr_user_get(const struct xattr_handler *handler,
 
 static int
 ext2_xattr_user_set(const struct xattr_handler *handler,
-                   struct dentry *dentry, const char *name,
-                   const void *value, size_t size, int flags)
+                   struct dentry *unused, struct inode *inode,
+                   const char *name, const void *value,
+                   size_t size, int flags)
 {
-       if (!test_opt(dentry->d_sb, XATTR_USER))
+       if (!test_opt(inode->i_sb, XATTR_USER))
                return -EOPNOTSUPP;
 
-       return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_USER,
+       return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER,
                              name, value, size, flags);
 }
 
index 123a7d010efeb9f3db00c1c448a53321fa4f8855..a8921112030d31f00bd28e9cdd32d3f04c6f806c 100644 (file)
@@ -22,10 +22,11 @@ ext4_xattr_security_get(const struct xattr_handler *handler,
 
 static int
 ext4_xattr_security_set(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags)
+                       struct dentry *unused, struct inode *inode,
+                       const char *name, const void *value,
+                       size_t size, int flags)
 {
-       return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY,
+       return ext4_xattr_set(inode, EXT4_XATTR_INDEX_SECURITY,
                              name, value, size, flags);
 }
 
index 60652fa24cbced4a6b6bb7e4a1a17fd95b677130..c7765c73571446b2f9296fea7cb9e9e1086bd474 100644 (file)
@@ -29,10 +29,11 @@ ext4_xattr_trusted_get(const struct xattr_handler *handler,
 
 static int
 ext4_xattr_trusted_set(const struct xattr_handler *handler,
-                      struct dentry *dentry, const char *name,
-                      const void *value, size_t size, int flags)
+                      struct dentry *unused, struct inode *inode,
+                      const char *name, const void *value,
+                      size_t size, int flags)
 {
-       return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED,
+       return ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED,
                              name, value, size, flags);
 }
 
index 17a446ffecd30c1ace66c1a2f2fb349f0a24211c..ca20e423034bf48a8e6e237cff0f3f3896d5280b 100644 (file)
@@ -30,12 +30,13 @@ ext4_xattr_user_get(const struct xattr_handler *handler,
 
 static int
 ext4_xattr_user_set(const struct xattr_handler *handler,
-                   struct dentry *dentry, const char *name,
-                   const void *value, size_t size, int flags)
+                   struct dentry *unused, struct inode *inode,
+                   const char *name, const void *value,
+                   size_t size, int flags)
 {
-       if (!test_opt(dentry->d_sb, XATTR_USER))
+       if (!test_opt(inode->i_sb, XATTR_USER))
                return -EOPNOTSUPP;
-       return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_USER,
+       return ext4_xattr_set(inode, EXT4_XATTR_INDEX_USER,
                              name, value, size, flags);
 }
 
index 00ea567972580fe5ae4be2f27257852a8dd409e0..e3decae3acfbba671f9324c5cdc030d4b0400d2f 100644 (file)
@@ -50,10 +50,11 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
 }
 
 static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
-               struct dentry *dentry, const char *name, const void *value,
+               struct dentry *unused, struct inode *inode,
+               const char *name, const void *value,
                size_t size, int flags)
 {
-       struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
 
        switch (handler->flags) {
        case F2FS_XATTR_INDEX_USER:
@@ -69,7 +70,7 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
        default:
                return -EINVAL;
        }
-       return f2fs_setxattr(d_inode(dentry), handler->flags, name,
+       return f2fs_setxattr(inode, handler->flags, name,
                                        value, size, NULL, flags);
 }
 
@@ -95,11 +96,10 @@ static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
 }
 
 static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
-               struct dentry *dentry, const char *name, const void *value,
+               struct dentry *unused, struct inode *inode,
+               const char *name, const void *value,
                size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
-
        if (!inode_owner_or_capable(inode))
                return -EPERM;
        if (value == NULL)
index b9419058108fabe3cd05d170dc24db8455b6d643..ccd4971cc6c1ac787ede8998d73f3e68f3a1294a 100644 (file)
@@ -1719,10 +1719,10 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
        return fuse_update_attributes(inode, stat, NULL, NULL);
 }
 
-static int fuse_setxattr(struct dentry *entry, const char *name,
-                        const void *value, size_t size, int flags)
+static int fuse_setxattr(struct dentry *unused, struct inode *inode,
+                        const char *name, const void *value,
+                        size_t size, int flags)
 {
-       struct inode *inode = d_inode(entry);
        struct fuse_conn *fc = get_fuse_conn(inode);
        FUSE_ARGS(args);
        struct fuse_setxattr_in inarg;
index f42ab53bd30dcb84866cef014f151d8ac417ab34..3a28535040841151a9d246d104f7e145aa5b28f8 100644 (file)
@@ -1251,10 +1251,10 @@ int __gfs2_xattr_set(struct inode *inode, const char *name,
 }
 
 static int gfs2_xattr_set(const struct xattr_handler *handler,
-                         struct dentry *dentry, const char *name,
-                         const void *value, size_t size, int flags)
+                         struct dentry *unused, struct inode *inode,
+                         const char *name, const void *value,
+                         size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_holder gh;
        int ret;
index 064f92f17efc8c1a1f7110e1986bced67911700f..d9a86919fdf6e9d371b7d01d048acf100f0cc0a6 100644 (file)
 #include "hfs_fs.h"
 #include "btree.h"
 
-int hfs_setxattr(struct dentry *dentry, const char *name,
-                const void *value, size_t size, int flags)
+int hfs_setxattr(struct dentry *unused, struct inode *inode,
+                const char *name, const void *value,
+                size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
        struct hfs_find_data fd;
        hfs_cat_rec rec;
        struct hfs_cat_file *file;
index fa3eed86837cfc7308b6e22745eec65d41de981e..ee2f385811c820ce4fdff468b616cf378440f586 100644 (file)
@@ -212,7 +212,7 @@ extern void hfs_evict_inode(struct inode *);
 extern void hfs_delete_inode(struct inode *);
 
 /* attr.c */
-extern int hfs_setxattr(struct dentry *dentry, const char *name,
+extern int hfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
                        const void *value, size_t size, int flags);
 extern ssize_t hfs_getxattr(struct dentry *dentry, struct inode *inode,
                            const char *name, void *value, size_t size);
index 4f118d282a7ac1ad5bf1ba171e85229c7c553728..d37bb88dc746e6aed35e2b2307d88105c3b37b37 100644 (file)
@@ -424,7 +424,7 @@ static int copy_name(char *buffer, const char *xattr_name, int name_len)
        return len;
 }
 
-int hfsplus_setxattr(struct dentry *dentry, const char *name,
+int hfsplus_setxattr(struct inode *inode, const char *name,
                     const void *value, size_t size, int flags,
                     const char *prefix, size_t prefixlen)
 {
@@ -437,8 +437,7 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name,
                return -ENOMEM;
        strcpy(xattr_name, prefix);
        strcpy(xattr_name + prefixlen, name);
-       res = __hfsplus_setxattr(d_inode(dentry), xattr_name, value, size,
-                                flags);
+       res = __hfsplus_setxattr(inode, xattr_name, value, size, flags);
        kfree(xattr_name);
        return res;
 }
@@ -864,8 +863,9 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
 }
 
 static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
-                               struct dentry *dentry, const char *name,
-                               const void *buffer, size_t size, int flags)
+                               struct dentry *unused, struct inode *inode,
+                               const char *name, const void *buffer,
+                               size_t size, int flags)
 {
        /*
         * Don't allow setting properly prefixed attributes
@@ -880,7 +880,7 @@ static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
         * creates), so we pass the name through unmodified (after
         * ensuring it doesn't conflict with another namespace).
         */
-       return __hfsplus_setxattr(d_inode(dentry), name, buffer, size, flags);
+       return __hfsplus_setxattr(inode, name, buffer, size, flags);
 }
 
 const struct xattr_handler hfsplus_xattr_osx_handler = {
index d04ba6f58df284f7a0cd8d4f5d92cceba13bab58..68f6b539371f51632654574b6e5d8d9e668a2a02 100644 (file)
@@ -21,7 +21,7 @@ extern const struct xattr_handler *hfsplus_xattr_handlers[];
 int __hfsplus_setxattr(struct inode *inode, const char *name,
                        const void *value, size_t size, int flags);
 
-int hfsplus_setxattr(struct dentry *dentry, const char *name,
+int hfsplus_setxattr(struct inode *inode, const char *name,
                                   const void *value, size_t size, int flags,
                                   const char *prefix, size_t prefixlen);
 
index ae2ca8c2e3353428adb4b2fe09c43c470a736f81..37b3efa733ef246141034026550e5a94e521a107 100644 (file)
@@ -23,10 +23,11 @@ static int hfsplus_security_getxattr(const struct xattr_handler *handler,
 }
 
 static int hfsplus_security_setxattr(const struct xattr_handler *handler,
-                                    struct dentry *dentry, const char *name,
-                                    const void *buffer, size_t size, int flags)
+                                    struct dentry *unused, struct inode *inode,
+                                    const char *name, const void *buffer,
+                                    size_t size, int flags)
 {
-       return hfsplus_setxattr(dentry, name, buffer, size, flags,
+       return hfsplus_setxattr(inode, name, buffer, size, flags,
                                XATTR_SECURITY_PREFIX,
                                XATTR_SECURITY_PREFIX_LEN);
 }
index eae2947060aa1892f425dd4eb2377d035a9e06b2..94519d6c627df8b447cc468971520b5b73d05439 100644 (file)
@@ -21,10 +21,11 @@ static int hfsplus_trusted_getxattr(const struct xattr_handler *handler,
 }
 
 static int hfsplus_trusted_setxattr(const struct xattr_handler *handler,
-                                   struct dentry *dentry, const char *name,
-                                   const void *buffer, size_t size, int flags)
+                                   struct dentry *unused, struct inode *inode,
+                                   const char *name, const void *buffer,
+                                   size_t size, int flags)
 {
-       return hfsplus_setxattr(dentry, name, buffer, size, flags,
+       return hfsplus_setxattr(inode, name, buffer, size, flags,
                                XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
 }
 
index 3c9eec3e4c7befa138983c4bcec755308ebf1b1d..fae6c0ea00305f0e21a84f2489522187f279d550 100644 (file)
@@ -21,10 +21,11 @@ static int hfsplus_user_getxattr(const struct xattr_handler *handler,
 }
 
 static int hfsplus_user_setxattr(const struct xattr_handler *handler,
-                                struct dentry *dentry, const char *name,
-                                const void *buffer, size_t size, int flags)
+                                struct dentry *unused, struct inode *inode,
+                                const char *name, const void *buffer,
+                                size_t size, int flags)
 {
-       return hfsplus_setxattr(dentry, name, buffer, size, flags,
+       return hfsplus_setxattr(inode, name, buffer, size, flags,
                                XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
 }
 
index 3ed9a4b49778d8650168a7de1e62b3149827636d..c2332e30f218ae7f942e51a279d357ebd46fbf69 100644 (file)
@@ -57,10 +57,11 @@ static int jffs2_security_getxattr(const struct xattr_handler *handler,
 }
 
 static int jffs2_security_setxattr(const struct xattr_handler *handler,
-                                  struct dentry *dentry, const char *name,
-                                  const void *buffer, size_t size, int flags)
+                                  struct dentry *unused, struct inode *inode,
+                                  const char *name, const void *buffer,
+                                  size_t size, int flags)
 {
-       return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY,
+       return do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
                                 name, buffer, size, flags);
 }
 
index 4ebecff1d922441879010e4b77ced01e70ab970c..5d6030826c520487dc1967a517b8002ee70e7d69 100644 (file)
@@ -25,10 +25,11 @@ static int jffs2_trusted_getxattr(const struct xattr_handler *handler,
 }
 
 static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
-                                 struct dentry *dentry, const char *name,
-                                 const void *buffer, size_t size, int flags)
+                                 struct dentry *unused, struct inode *inode,
+                                 const char *name, const void *buffer,
+                                 size_t size, int flags)
 {
-       return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED,
+       return do_jffs2_setxattr(inode, JFFS2_XPREFIX_TRUSTED,
                                 name, buffer, size, flags);
 }
 
index bce249e1b277c1805c37cc64b808220691fb6765..9d027b4abcf993e7005f1a6ae66558fd8a2e099a 100644 (file)
@@ -25,10 +25,11 @@ static int jffs2_user_getxattr(const struct xattr_handler *handler,
 }
 
 static int jffs2_user_setxattr(const struct xattr_handler *handler,
-                              struct dentry *dentry, const char *name,
-                              const void *buffer, size_t size, int flags)
+                              struct dentry *unused, struct inode *inode,
+                              const char *name, const void *buffer,
+                              size_t size, int flags)
 {
-       return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_USER,
+       return do_jffs2_setxattr(inode, JFFS2_XPREFIX_USER,
                                 name, buffer, size, flags);
 }
 
index beb182b503b3b771d7dd20d38a3ebbf192d885a7..0bf3c33aedff9ecca4bbcaa11f04685b00671322 100644 (file)
@@ -943,11 +943,10 @@ static int jfs_xattr_get(const struct xattr_handler *handler,
 }
 
 static int jfs_xattr_set(const struct xattr_handler *handler,
-                        struct dentry *dentry, const char *name,
-                        const void *value, size_t size, int flags)
+                        struct dentry *unused, struct inode *inode,
+                        const char *name, const void *value,
+                        size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
-
        name = xattr_full_name(handler, name);
        return __jfs_xattr_set(inode, name, value, size, flags);
 }
@@ -962,11 +961,10 @@ static int jfs_xattr_get_os2(const struct xattr_handler *handler,
 }
 
 static int jfs_xattr_set_os2(const struct xattr_handler *handler,
-                            struct dentry *dentry, const char *name,
-                            const void *value, size_t size, int flags)
+                            struct dentry *unused, struct inode *inode,
+                            const char *name, const void *value,
+                            size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
-
        if (is_known_namespace(name))
                return -EOPNOTSUPP;
        return __jfs_xattr_set(inode, name, value, size, flags);
index 1719649d7ad78378d01df519a77888853e69adfe..63b925d5ba1e43c67a83dfc1c92f59325fc954ba 100644 (file)
@@ -160,10 +160,11 @@ static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata,
        return 0;
 }
 
-int kernfs_iop_setxattr(struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags)
+int kernfs_iop_setxattr(struct dentry *unused, struct inode *inode,
+                       const char *name, const void *value,
+                       size_t size, int flags)
 {
-       struct kernfs_node *kn = dentry->d_fsdata;
+       struct kernfs_node *kn = inode->i_private;
        struct kernfs_iattrs *attrs;
        void *secdata;
        int error;
@@ -175,11 +176,11 @@ int kernfs_iop_setxattr(struct dentry *dentry, const char *name,
 
        if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
                const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
-               error = security_inode_setsecurity(d_inode(dentry), suffix,
+               error = security_inode_setsecurity(inode, suffix,
                                                value, size, flags);
                if (error)
                        return error;
-               error = security_inode_getsecctx(d_inode(dentry),
+               error = security_inode_getsecctx(inode,
                                                &secdata, &secdata_len);
                if (error)
                        return error;
index 45c9192c276e4544621dc393da03d76b088d86f3..37159235ac10969db99278598724adfedda23889 100644 (file)
@@ -81,7 +81,8 @@ int kernfs_iop_permission(struct inode *inode, int mask);
 int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr);
 int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry,
                       struct kstat *stat);
-int kernfs_iop_setxattr(struct dentry *dentry, const char *name, const void *value,
+int kernfs_iop_setxattr(struct dentry *dentry, struct inode *inode,
+                       const char *name, const void *value,
                        size_t size, int flags);
 int kernfs_iop_removexattr(struct dentry *dentry, const char *name);
 ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode,
index 8765ff1adc07dcc63252615927dff818628649cd..3db2721144c27d133cc7f8652d269900c9865ea5 100644 (file)
@@ -1118,8 +1118,9 @@ static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
        return -EPERM;
 }
 
-static int empty_dir_setxattr(struct dentry *dentry, const char *name,
-                             const void *value, size_t size, int flags)
+static int empty_dir_setxattr(struct dentry *dentry, struct inode *inode,
+                             const char *name, const void *value,
+                             size_t size, int flags)
 {
        return -EOPNOTSUPP;
 }
index 223982eb38c943aa4fbde960b889eb9dbc4853c8..de97567795a52c523abfa5936829303a388560e8 100644 (file)
@@ -5015,12 +5015,11 @@ static int nfs4_do_set_security_label(struct inode *inode,
 }
 
 static int
-nfs4_set_security_label(struct dentry *dentry, const void *buf, size_t buflen)
+nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
 {
        struct nfs4_label ilabel, *olabel = NULL;
        struct nfs_fattr fattr;
        struct rpc_cred *cred;
-       struct inode *inode = d_inode(dentry);
        int status;
 
        if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
@@ -6281,11 +6280,11 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp)
 #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
 
 static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
-                                  struct dentry *dentry, const char *key,
-                                  const void *buf, size_t buflen,
-                                  int flags)
+                                  struct dentry *unused, struct inode *inode,
+                                  const char *key, const void *buf,
+                                  size_t buflen, int flags)
 {
-       return nfs4_proc_set_acl(d_inode(dentry), buf, buflen);
+       return nfs4_proc_set_acl(inode, buf, buflen);
 }
 
 static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
@@ -6303,12 +6302,12 @@ static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
 
 static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
-                                    struct dentry *dentry, const char *key,
-                                    const void *buf, size_t buflen,
-                                    int flags)
+                                    struct dentry *unused, struct inode *inode,
+                                    const char *key, const void *buf,
+                                    size_t buflen, int flags)
 {
        if (security_ismaclabel(key))
-               return nfs4_set_security_label(dentry, buf, buflen);
+               return nfs4_set_security_label(inode, buf, buflen);
 
        return -EOPNOTSUPP;
 }
index ad16995c9e7aa8a62f50aed95c1e33e1be5b40a0..d2053853951e04182bed402df1817fac262f67da 100644 (file)
@@ -7254,10 +7254,11 @@ static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
 }
 
 static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
-                                   struct dentry *dentry, const char *name,
-                                   const void *value, size_t size, int flags)
+                                   struct dentry *unused, struct inode *inode,
+                                   const char *name, const void *value,
+                                   size_t size, int flags)
 {
-       return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY,
+       return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
                               name, value, size, flags);
 }
 
@@ -7325,10 +7326,11 @@ static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
 }
 
 static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler,
-                                  struct dentry *dentry, const char *name,
-                                  const void *value, size_t size, int flags)
+                                  struct dentry *unused, struct inode *inode,
+                                  const char *name, const void *value,
+                                  size_t size, int flags)
 {
-       return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED,
+       return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_TRUSTED,
                               name, value, size, flags);
 }
 
@@ -7354,15 +7356,16 @@ static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
 }
 
 static int ocfs2_xattr_user_set(const struct xattr_handler *handler,
-                               struct dentry *dentry, const char *name,
-                               const void *value, size_t size, int flags)
+                               struct dentry *unused, struct inode *inode,
+                               const char *name, const void *value,
+                               size_t size, int flags)
 {
-       struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
                return -EOPNOTSUPP;
 
-       return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_USER,
+       return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_USER,
                               name, value, size, flags);
 }
 
index 99c19545752c23316c08ec6cafc6753c53f6cc27..5893ddde0e4b6ad8680f5481ea3f61611060b307 100644 (file)
@@ -448,13 +448,14 @@ out_unlock:
 }
 
 static int orangefs_xattr_set_default(const struct xattr_handler *handler,
-                                     struct dentry *dentry,
+                                     struct dentry *unused,
+                                     struct inode *inode,
                                      const char *name,
                                      const void *buffer,
                                      size_t size,
                                      int flags)
 {
-       return orangefs_inode_setxattr(dentry->d_inode,
+       return orangefs_inode_setxattr(inode,
                                    ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
                                    name,
                                    buffer,
@@ -478,13 +479,14 @@ static int orangefs_xattr_get_default(const struct xattr_handler *handler,
 }
 
 static int orangefs_xattr_set_trusted(const struct xattr_handler *handler,
-                                    struct dentry *dentry,
+                                    struct dentry *unused,
+                                    struct inode *inode,
                                     const char *name,
                                     const void *buffer,
                                     size_t size,
                                     int flags)
 {
-       return orangefs_inode_setxattr(dentry->d_inode,
+       return orangefs_inode_setxattr(inode,
                                    ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
                                    name,
                                    buffer,
index c7b31a03dc9cf9926a4f32669b05438b158a8a66..0ed7c40124378cc9dce12d73e3c22449d2348909 100644 (file)
@@ -210,8 +210,9 @@ static bool ovl_is_private_xattr(const char *name)
        return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
 }
 
-int ovl_setxattr(struct dentry *dentry, const char *name,
-                const void *value, size_t size, int flags)
+int ovl_setxattr(struct dentry *dentry, struct inode *inode,
+                const char *name, const void *value,
+                size_t size, int flags)
 {
        int err;
        struct dentry *upperdentry;
index 724f5fcb4e249314ab2359b221c3c4fd56cd3d74..4bd9b5ba8f42008b7f72cf271fac89c67b7eca6d 100644 (file)
@@ -172,8 +172,9 @@ int ovl_check_d_type_supported(struct path *realpath);
 /* inode.c */
 int ovl_setattr(struct dentry *dentry, struct iattr *attr);
 int ovl_permission(struct inode *inode, int mask);
-int ovl_setxattr(struct dentry *dentry, const char *name,
-                const void *value, size_t size, int flags);
+int ovl_setxattr(struct dentry *dentry, struct inode *inode,
+                const char *name, const void *value,
+                size_t size, int flags);
 ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
                     const char *name, void *value, size_t size);
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
index d11ae826bcbc94215abc441a4c1d53434691e5c4..cf37fc76fc9fc02f00caf5a64bd632f20942a528 100644 (file)
@@ -210,9 +210,7 @@ static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
 
        old_cred = ovl_override_creds(rdd->dentry->d_sb);
 
-       inode_lock(dir->d_inode);
-       err = 0;
-       // XXX: err = mutex_lock_killable(&dir->d_inode->i_mutex);
+       err = down_write_killable(&dir->d_inode->i_rwsem);
        if (!err) {
                while (rdd->first_maybe_whiteout) {
                        p = rdd->first_maybe_whiteout;
index 2c60f17e7d923f654c3cd8e4aec1cbdc61ba386f..8a4a266beff39dda0be9ca39df74bc847fd0a2d3 100644 (file)
@@ -822,10 +822,10 @@ posix_acl_xattr_get(const struct xattr_handler *handler,
 
 static int
 posix_acl_xattr_set(const struct xattr_handler *handler,
-                   struct dentry *dentry, const char *name,
-                   const void *value, size_t size, int flags)
+                   struct dentry *unused, struct inode *inode,
+                   const char *name, const void *value,
+                   size_t size, int flags)
 {
-       struct inode *inode = d_backing_inode(dentry);
        struct posix_acl *acl = NULL;
        int ret;
 
index 68ef06efe6bc4a530133d54e57833330a1b40470..9d0212c374d6db316dcafcd278e5b511a1eec6d2 100644 (file)
@@ -35,13 +35,13 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
        if (res)
                goto out;
 
-       if (shared)
+       if (shared) {
                inode_lock_shared(inode);
-       else
-               inode_lock(inode);
-       // res = mutex_lock_killable(&inode->i_mutex);
-       // if (res)
-       //      goto out;
+       } else {
+               res = down_write_killable(&inode->i_rwsem);
+               if (res)
+                       goto out;
+       }
 
        res = -ENOENT;
        if (!IS_DEADDIR(inode)) {
index 86aeb9dd805a9189073fe4e605d01d8103da36c4..e4cbb7719906308a461b1a93b307201eca3faad3 100644 (file)
@@ -20,13 +20,14 @@ security_get(const struct xattr_handler *handler, struct dentry *unused,
 }
 
 static int
-security_set(const struct xattr_handler *handler, struct dentry *dentry,
-            const char *name, const void *buffer, size_t size, int flags)
+security_set(const struct xattr_handler *handler, struct dentry *unused,
+            struct inode *inode, const char *name, const void *buffer,
+            size_t size, int flags)
 {
-       if (IS_PRIVATE(d_inode(dentry)))
+       if (IS_PRIVATE(inode))
                return -EPERM;
 
-       return reiserfs_xattr_set(d_inode(dentry),
+       return reiserfs_xattr_set(inode,
                                  xattr_full_name(handler, name),
                                  buffer, size, flags);
 }
index 31837f031f597d4f71b2a428058b20cd3024abca..f15a5f9e84ce1a83e2052b7852a21bff727f105c 100644 (file)
@@ -19,13 +19,14 @@ trusted_get(const struct xattr_handler *handler, struct dentry *unused,
 }
 
 static int
-trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
-           const char *name, const void *buffer, size_t size, int flags)
+trusted_set(const struct xattr_handler *handler, struct dentry *unused,
+           struct inode *inode, const char *name, const void *buffer,
+           size_t size, int flags)
 {
-       if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
+       if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
                return -EPERM;
 
-       return reiserfs_xattr_set(d_inode(dentry),
+       return reiserfs_xattr_set(inode,
                                  xattr_full_name(handler, name),
                                  buffer, size, flags);
 }
index f7c39731684bcf9cb39ff8b54f68981ab2aa440a..dc59df43b2dbfb2dab5729a69d5ac302e0873ed3 100644 (file)
@@ -17,12 +17,13 @@ user_get(const struct xattr_handler *handler, struct dentry *unused,
 }
 
 static int
-user_set(const struct xattr_handler *handler, struct dentry *dentry,
-        const char *name, const void *buffer, size_t size, int flags)
+user_set(const struct xattr_handler *handler, struct dentry *unused,
+        struct inode *inode, const char *name, const void *buffer,
+        size_t size, int flags)
 {
-       if (!reiserfs_xattrs_user(dentry->d_sb))
+       if (!reiserfs_xattrs_user(inode->i_sb))
                return -EOPNOTSUPP;
-       return reiserfs_xattr_set(d_inode(dentry),
+       return reiserfs_xattr_set(inode,
                                  xattr_full_name(handler, name),
                                  buffer, size, flags);
 }
index 6c277eb6aef943787a1fd98e74a8ab8f57c63d4b..b5fc27969e9d31bc0a9e951cc50a83c66d9c1352 100644 (file)
@@ -579,11 +579,10 @@ static int ubifs_xattr_get(const struct xattr_handler *handler,
 }
 
 static int ubifs_xattr_set(const struct xattr_handler *handler,
-                          struct dentry *dentry, const char *name,
-                          const void *value, size_t size, int flags)
+                          struct dentry *dentry, struct inode *inode,
+                          const char *name, const void *value,
+                          size_t size, int flags)
 {
-       struct inode *inode = d_inode(dentry);
-
        dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
                name, inode->i_ino, dentry, size);
 
index fc81e771488a670ebeac9606cc815dab1ded6446..4beafc43daa58bff015f0839c78b5a65f8b8d2ab 100644 (file)
@@ -100,7 +100,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
        if (issec)
                inode->i_flags &= ~S_NOSEC;
        if (inode->i_op->setxattr) {
-               error = inode->i_op->setxattr(dentry, name, value, size, flags);
+               error = inode->i_op->setxattr(dentry, inode, name, value, size, flags);
                if (!error) {
                        fsnotify_xattr(dentry);
                        security_inode_post_setxattr(dentry, name, value,
@@ -745,7 +745,8 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
  * Find the handler for the prefix and dispatch its set() operation.
  */
 int
-generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
+generic_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
+                const void *value, size_t size, int flags)
 {
        const struct xattr_handler *handler;
 
@@ -754,7 +755,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (IS_ERR(handler))
                return PTR_ERR(handler);
-       return handler->set(handler, dentry, name, value, size, flags);
+       return handler->set(handler, dentry, inode, name, value, size, flags);
 }
 
 /*
@@ -769,7 +770,8 @@ generic_removexattr(struct dentry *dentry, const char *name)
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (IS_ERR(handler))
                return PTR_ERR(handler);
-       return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
+       return handler->set(handler, dentry, d_inode(dentry), name, NULL,
+                           0, XATTR_REPLACE);
 }
 
 EXPORT_SYMBOL(generic_getxattr);
index ec58ff094b1dfbfcd634f5aad4b0fae2da8cc086..ea62245fee263d8f38e51b4d6ff6bad0e2b05b02 100644 (file)
@@ -74,11 +74,12 @@ xfs_forget_acl(
 }
 
 static int
-xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry,
-               const char *name, const void *value, size_t size, int flags)
+xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
+               struct inode *inode, const char *name, const void *value,
+               size_t size, int flags)
 {
        int                     xflags = handler->flags;
-       struct xfs_inode        *ip = XFS_I(d_inode(dentry));
+       struct xfs_inode        *ip = XFS_I(inode);
        int                     error;
 
        /* Convert Linux syscall to XFS internal ATTR flags */
@@ -92,7 +93,7 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry,
        error = xfs_attr_set(ip, (unsigned char *)name,
                                (void *)value, size, xflags);
        if (!error)
-               xfs_forget_acl(d_inode(dentry), name, xflags);
+               xfs_forget_acl(inode, name, xflags);
 
        return error;
 }
index 9ace7f745bcdeef15b7b3e7beed2ed8b18bb991e..dd288148a6b15f2ea958441e628f5ed2a729faff 100644 (file)
@@ -1729,7 +1729,8 @@ struct inode_operations {
                        struct inode *, struct dentry *, unsigned int);
        int (*setattr) (struct dentry *, struct iattr *);
        int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
-       int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
+       int (*setxattr) (struct dentry *, struct inode *,
+                        const char *, const void *, size_t, int);
        ssize_t (*getxattr) (struct dentry *, struct inode *,
                             const char *, void *, size_t);
        ssize_t (*listxattr) (struct dentry *, char *, size_t);
index d1c12d160ace1491ad097477a03aa6820d304046..d37fbb34d06fed4494b3152300d71aba23663f63 100644 (file)
@@ -156,6 +156,7 @@ extern void downgrade_write(struct rw_semaphore *sem);
  */
 extern void down_read_nested(struct rw_semaphore *sem, int subclass);
 extern void down_write_nested(struct rw_semaphore *sem, int subclass);
+extern int down_write_killable_nested(struct rw_semaphore *sem, int subclass);
 extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock);
 
 # define down_write_nest_lock(sem, nest_lock)                  \
@@ -176,6 +177,7 @@ extern void up_read_non_owner(struct rw_semaphore *sem);
 # define down_read_nested(sem, subclass)               down_read(sem)
 # define down_write_nest_lock(sem, nest_lock)  down_write(sem)
 # define down_write_nested(sem, subclass)      down_write(sem)
+# define down_write_killable_nested(sem, subclass)     down_write_killable(sem)
 # define down_read_non_owner(sem)              down_read(sem)
 # define up_read_non_owner(sem)                        up_read(sem)
 #endif
index 1cc4c578deb910dbae0e3ca36186d28af8a506e1..94079bab92434d928f839a59b124e1bb739c4145 100644 (file)
@@ -33,8 +33,8 @@ struct xattr_handler {
                   struct inode *inode, const char *name, void *buffer,
                   size_t size);
        int (*set)(const struct xattr_handler *, struct dentry *dentry,
-                  const char *name, const void *buffer, size_t size,
-                  int flags);
+                  struct inode *inode, const char *name, const void *buffer,
+                  size_t size, int flags);
 };
 
 const char *xattr_full_name(const struct xattr_handler *, const char *);
@@ -54,7 +54,8 @@ int vfs_removexattr(struct dentry *, const char *);
 
 ssize_t generic_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size);
 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
-int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
+int generic_setxattr(struct dentry *dentry, struct inode *inode,
+                    const char *name, const void *value, size_t size, int flags);
 int generic_removexattr(struct dentry *dentry, const char *name);
 ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
                           char **xattr_value, size_t size, gfp_t flags);
index c817216c161521b92cc64ef90e1da1c54e936839..2e853ad93a3a0f27ac3ce676ebe637ad8e03199e 100644 (file)
@@ -173,6 +173,22 @@ void down_write_nested(struct rw_semaphore *sem, int subclass)
 
 EXPORT_SYMBOL(down_write_nested);
 
+int __sched down_write_killable_nested(struct rw_semaphore *sem, int subclass)
+{
+       might_sleep();
+       rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
+
+       if (LOCK_CONTENDED_RETURN(sem, __down_write_trylock, __down_write_killable)) {
+               rwsem_release(&sem->dep_map, 1, _RET_IP_);
+               return -EINTR;
+       }
+
+       rwsem_set_owner(sem);
+       return 0;
+}
+
+EXPORT_SYMBOL(down_write_killable_nested);
+
 void up_read_non_owner(struct rw_semaphore *sem)
 {
        __up_read(sem);
index e418a995427d67b4e386c366da4dd427dc27c889..a36144909b2840213c087f3eb32fbd10d7c880ee 100644 (file)
@@ -2645,10 +2645,11 @@ static int shmem_xattr_handler_get(const struct xattr_handler *handler,
 }
 
 static int shmem_xattr_handler_set(const struct xattr_handler *handler,
-                                  struct dentry *dentry, const char *name,
-                                  const void *value, size_t size, int flags)
+                                  struct dentry *unused, struct inode *inode,
+                                  const char *name, const void *value,
+                                  size_t size, int flags)
 {
-       struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
+       struct shmem_inode_info *info = SHMEM_I(inode);
 
        name = xattr_full_name(handler, name);
        return simple_xattr_set(&info->xattrs, name, value, size, flags);
index ff2b8c3cf7a9cdbb0e120461fbf226aff4a5a063..6777295f4b2b75bd4edc385a60a09cdc4fdde0c0 100644 (file)
@@ -3514,7 +3514,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
                         */
                        if (isp->smk_flags & SMK_INODE_CHANGED) {
                                isp->smk_flags &= ~SMK_INODE_CHANGED;
-                               rc = inode->i_op->setxattr(dp,
+                               rc = inode->i_op->setxattr(dp, inode,
                                        XATTR_NAME_SMACKTRANSMUTE,
                                        TRANS_TRUE, TRANS_TRUE_SIZE,
                                        0);