->getxattr(): pass dentry and inode as separate arguments
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 11 Apr 2016 04:48:00 +0000 (00:48 -0400)
committerJaehoon Chung <jh80.chung@samsung.com>
Tue, 29 Jan 2019 02:25:41 +0000 (11:25 +0900)
commit ce23e640133484eebc20ca7b7668388213e11327 upstream.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[sw0312.kim: backport from mainline to resolve smack getxattr during security_d_instantiate()]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Change-Id: I7fcd9edc3e3e543e35e173e8479906b6a7f81455

37 files changed:
Documentation/filesystems/porting
drivers/staging/lustre/lustre/llite/llite_internal.h
drivers/staging/lustre/lustre/llite/xattr.c
fs/bad_inode.c
fs/btrfs/xattr.c
fs/btrfs/xattr.h
fs/ceph/super.h
fs/ceph/xattr.c
fs/cifs/cifsfs.h
fs/cifs/xattr.c
fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/inode.c
fs/ecryptfs/mmap.c
fs/fuse/dir.c
fs/gfs2/inode.c
fs/hfs/attr.c
fs/hfs/hfs_fs.h
fs/jfs/jfs_xattr.h
fs/jfs/xattr.c
fs/kernfs/inode.c
fs/kernfs/kernfs-internal.h
fs/libfs.c
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c
fs/ubifs/ubifs.h
fs/ubifs/xattr.c
fs/xattr.c
include/linux/fs.h
include/linux/xattr.h
mm/shmem.c
net/socket.c
security/commoncap.c
security/integrity/evm/evm_main.c
security/selinux/hooks.c
security/smack/smack_lsm.c

index f24d1b8339576e96c46045f5da8f275ee9250056..d5f6834ed51ac9bffe7018f2d8da94dd045378ef 100644 (file)
@@ -504,3 +504,9 @@ in your dentry operations instead.
 [mandatory]
        __fd_install() & fd_install() can now sleep. Callers should not
        hold a spinlock or other resources that do not allow a schedule.
+--
+[mandatory]
+       ->getxattr() and xattr_handler.get() 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.
index c2d9b793759d0c7c2a49000ea8289e101547608c..c350b01feab71883f2c86ad30ac7e515a3a074e9 100644 (file)
@@ -1032,8 +1032,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);
-ssize_t ll_getxattr(struct dentry *dentry, const char *name,
-                   void *buffer, size_t size);
+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);
 int ll_removexattr(struct dentry *dentry, const char *name);
 
index 4b7eb33f7d0172d8f8c716c309e98b7fdce19b1a..8102740d39e46b443d7e841b789b3cc8979f0743 100644 (file)
@@ -449,11 +449,9 @@ out:
        return rc;
 }
 
-ssize_t ll_getxattr(struct dentry *dentry, const char *name,
-                   void *buffer, size_t size)
+ssize_t ll_getxattr(struct dentry *dentry, struct inode *inode,
+                   const char *name, void *buffer, size_t size)
 {
-       struct inode *inode = d_inode(dentry);
-
        LASSERT(inode);
        LASSERT(name);
 
index 861b1e1c477710faced77767a0327c1d6e6b79c5..86df8d475d1fd3f65046d5ad51abff2e09652c74 100644 (file)
@@ -106,8 +106,8 @@ static int bad_inode_setxattr(struct dentry *dentry, const char *name,
        return -EIO;
 }
 
-static ssize_t bad_inode_getxattr(struct dentry *dentry, const char *name,
-                       void *buffer, size_t size)
+static ssize_t bad_inode_getxattr(struct dentry *dentry, struct inode *inode,
+                       const char *name, void *buffer, size_t size)
 {
        return -EIO;
 }
index 1fcd7b6e7564defa675b3abe12589473a58e937d..a58622a2130b4224f0765770fce953fc14a8a033 100644 (file)
@@ -397,8 +397,8 @@ static int btrfs_is_valid_xattr(const char *name)
        return 0;
 }
 
-ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
-                      void *buffer, size_t size)
+ssize_t btrfs_getxattr(struct dentry *dentry, struct inode *inode,
+                      const char *name, void *buffer, size_t size)
 {
        int ret;
 
@@ -408,12 +408,12 @@ ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
         * for it via sb->s_xattr.
         */
        if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
-               return generic_getxattr(dentry, name, buffer, size);
+               return generic_getxattr(dentry, inode, name, buffer, size);
 
        ret = btrfs_is_valid_xattr(name);
        if (ret)
                return ret;
-       return __btrfs_getxattr(d_inode(dentry), name, buffer, size);
+       return __btrfs_getxattr(inode, name, buffer, size);
 }
 
 int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
index 5049608d13889e1e647cdb447851a6b30319990d..8ee432942e326df62b5956eeb3b41e7763ecb4c3 100644 (file)
@@ -28,8 +28,8 @@ extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
 extern int __btrfs_setxattr(struct btrfs_trans_handle *trans,
                            struct inode *inode, const char *name,
                            const void *value, size_t size, int flags);
-extern ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
-               void *buffer, size_t size);
+extern ssize_t btrfs_getxattr(struct dentry *dentry, struct inode *inode,
+                             const char *name, void *buffer, size_t size);
 extern int btrfs_setxattr(struct dentry *dentry, const char *name,
                const void *value, size_t size, int flags);
 extern int btrfs_removexattr(struct dentry *dentry, const char *name);
index 8c8cb8fe3d32f90e6ff61dd2b980e5405d544c88..2793ae2c0ff6389c0d1a3e904b8c8d2b09295f36 100644 (file)
@@ -799,7 +799,7 @@ extern int ceph_setxattr(struct dentry *, const char *, const void *,
 int __ceph_setxattr(struct dentry *, const char *, const void *, size_t, int);
 ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t);
 int __ceph_removexattr(struct dentry *, const char *);
-extern ssize_t ceph_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ceph_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
 extern ssize_t ceph_listxattr(struct dentry *, char *, size_t);
 extern int ceph_removexattr(struct dentry *, const char *);
 extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);
index b24275ef97f74d0d49f0f6f32ed4c32c9c3a6f8c..4e4d0b7df85a3486be41c93f616ab40002d0c10e 100644 (file)
@@ -773,13 +773,13 @@ out:
        return err;
 }
 
-ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value,
-                     size_t size)
+ssize_t ceph_getxattr(struct dentry *dentry, struct inode *inode,
+                     const char *name, void *value, size_t size)
 {
        if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
-               return generic_getxattr(dentry, name, value, size);
+               return generic_getxattr(dentry, inode, name, value, size);
 
-       return __ceph_getxattr(d_inode(dentry), name, value, size);
+       return __ceph_getxattr(inode, name, value, size);
 }
 
 ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
index 44b3d4280abb85c8dd8bfe86a2090659e75c0e17..39c380cd0b90e732dd32a41ee506573205f484ed 100644 (file)
@@ -124,7 +124,7 @@ extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
 extern int     cifs_removexattr(struct dentry *, const char *);
 extern int     cifs_setxattr(struct dentry *, const char *, const void *,
                        size_t, int);
-extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t cifs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
 extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 
index ff9e1f8b16a4872158c05f688a9761a9a7a8781d..0de08cd2e56141ef793b388fdfbc0ddbd18f7942 100644 (file)
@@ -232,8 +232,8 @@ set_ea_exit:
        return rc;
 }
 
-ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
-       void *ea_value, size_t buf_size)
+ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode,
+       const char *ea_name, void *ea_value, size_t buf_size)
 {
        ssize_t rc = -EOPNOTSUPP;
 #ifdef CONFIG_CIFS_XATTR
@@ -324,7 +324,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                goto get_ea_exit; /* rc already EOPNOTSUPP */
 
                        pacl = pTcon->ses->server->ops->get_acl(cifs_sb,
-                                       d_inode(direntry), full_path, &acllen);
+                                       inode, full_path, &acllen);
                        if (IS_ERR(pacl)) {
                                rc = PTR_ERR(pacl);
                                cifs_dbg(VFS, "%s: error %zd getting sec desc\n",
index 80d6901493cf5e0867cd2572885cc16f66ff59c5..81701fdedbebef6d2d0345b1eacf17afb9a2b51e 100644 (file)
@@ -1376,7 +1376,9 @@ int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode)
        ssize_t size;
        int rc = 0;
 
-       size = ecryptfs_getxattr_lower(lower_dentry, ECRYPTFS_XATTR_NAME,
+       size = ecryptfs_getxattr_lower(lower_dentry,
+                                      ecryptfs_inode_to_lower(ecryptfs_inode),
+                                      ECRYPTFS_XATTR_NAME,
                                       page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE);
        if (size < 0) {
                if (unlikely(ecryptfs_verbosity > 0))
@@ -1398,6 +1400,7 @@ int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry,
        int rc;
 
        rc = ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry),
+                                    ecryptfs_inode_to_lower(inode),
                                     ECRYPTFS_XATTR_NAME, file_size,
                                     ECRYPTFS_SIZE_AND_MARKER_BYTES);
        if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
index eae9cdb8af46faaeaa29325368459e6569bd64f8..7d2e3933ec92aa243df1fe2c7a102d60d4a0d3d1 100644 (file)
@@ -618,8 +618,8 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
                          unsigned char *src, struct dentry *ecryptfs_dentry);
 int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
 ssize_t
-ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
-                       void *value, size_t size);
+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);
index 844d0c4da84fade09872a3f43d72ec74273bdcb8..6447a9d61ab866e58b111c82297982cb0c5d7868 100644 (file)
@@ -1032,29 +1032,30 @@ out:
 }
 
 ssize_t
-ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
-                       void *value, size_t size)
+ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
+                       const char *name, void *value, size_t size)
 {
        int rc = 0;
 
-       if (!d_inode(lower_dentry)->i_op->getxattr) {
+       if (!lower_inode->i_op->getxattr) {
                rc = -EOPNOTSUPP;
                goto out;
        }
-       mutex_lock(&d_inode(lower_dentry)->i_mutex);
-       rc = d_inode(lower_dentry)->i_op->getxattr(lower_dentry, name, value,
-                                                  size);
-       mutex_unlock(&d_inode(lower_dentry)->i_mutex);
+       mutex_lock(&lower_inode->i_mutex);
+       rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
+                                        name, value, size);
+       mutex_unlock(&lower_inode->i_mutex);
 out:
        return rc;
 }
 
 static ssize_t
-ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
-                 size_t size)
+ecryptfs_getxattr(struct dentry *dentry, struct inode *inode,
+                 const char *name, void *value, size_t size)
 {
-       return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), name,
-                                      value, size);
+       return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry),
+                                      ecryptfs_inode_to_lower(inode),
+                                      name, value, size);
 }
 
 static ssize_t
index caba848ac76335ef0f897cb7cb27c1bbf520c1de..f8863df50ff7fa89bb77a3444c8c8ba20dd52633 100644 (file)
@@ -437,7 +437,8 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
                goto out;
        }
        mutex_lock(&lower_inode->i_mutex);
-       size = lower_inode->i_op->getxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
+       size = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
+                                          ECRYPTFS_XATTR_NAME,
                                           xattr_virt, PAGE_CACHE_SIZE);
        if (size < 0)
                size = 8;
index 49b7b40f75987119b772ed50be529bc27caef2ba..8c6ad17285fd3960023bea0b31d8461eee093e49 100644 (file)
@@ -1799,10 +1799,9 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
        return err;
 }
 
-static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
-                            void *value, size_t size)
+static ssize_t fuse_getxattr(struct dentry *entry, struct inode *inode,
+                            const char *name, void *value, size_t size)
 {
-       struct inode *inode = d_inode(entry);
        struct fuse_conn *fc = get_fuse_conn(inode);
        FUSE_ARGS(args);
        struct fuse_getxattr_in inarg;
index 063fdfcf82758a0c77f4cc44fe7b1f873b3cbb21..eefef81ae3bad580c14aff3a7affc3453c0cb430 100644 (file)
@@ -2011,22 +2011,21 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name,
        return ret;
 }
 
-static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
-                            void *data, size_t size)
+static ssize_t gfs2_getxattr(struct dentry *dentry, struct inode *inode,
+                            const char *name, void *data, size_t size)
 {
-       struct inode *inode = d_inode(dentry);
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_holder gh;
        int ret;
 
        /* For selinux during lookup */
        if (gfs2_glock_is_locked_by_me(ip->i_gl))
-               return generic_getxattr(dentry, name, data, size);
+               return generic_getxattr(dentry, inode, name, data, size);
 
        gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
        ret = gfs2_glock_nq(&gh);
        if (ret == 0) {
-               ret = generic_getxattr(dentry, name, data, size);
+               ret = generic_getxattr(dentry, inode, name, data, size);
                gfs2_glock_dq(&gh);
        }
        gfs2_holder_uninit(&gh);
index 8d931b157bbef8bfd382d9c6878fbdb8d53da481..064f92f17efc8c1a1f7110e1986bced67911700f 100644 (file)
@@ -56,10 +56,9 @@ out:
        return res;
 }
 
-ssize_t hfs_getxattr(struct dentry *dentry, const char *name,
-                        void *value, size_t size)
+ssize_t hfs_getxattr(struct dentry *unused, struct inode *inode,
+                    const char *name, void *value, size_t size)
 {
-       struct inode *inode = d_inode(dentry);
        struct hfs_find_data fd;
        hfs_cat_rec rec;
        struct hfs_cat_file *file;
index 1f1c7dcbcc2ff4066fef329828af148f7c058662..79daa097929a58510b2c4e8a3745cbe267777e8c 100644 (file)
@@ -213,8 +213,8 @@ extern void hfs_delete_inode(struct inode *);
 /* attr.c */
 extern int hfs_setxattr(struct dentry *dentry, const char *name,
                        const void *value, size_t size, int flags);
-extern ssize_t hfs_getxattr(struct dentry *dentry, const char *name,
-                           void *value, size_t size);
+extern ssize_t hfs_getxattr(struct dentry *dentry, struct inode *inode,
+                           const char *name, void *value, size_t size);
 extern ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 
 /* mdb.c */
index e8d717dabca3eb5a2e3bcff902c34b8376b8450d..e69e14f3777b3e7957a1692e604d8a563d0b3204 100644 (file)
@@ -57,7 +57,7 @@ extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *,
 extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
                        int);
 extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
-extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t jfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
 extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
 extern int jfs_removexattr(struct dentry *, const char *);
 
index 40a26a542341de148a29885a6321ad7735261183..77e6c1a5377bb1387959a57b5f1499841fc6e565 100644 (file)
@@ -935,8 +935,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
        return size;
 }
 
-ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
-                    size_t buf_size)
+ssize_t jfs_getxattr(struct dentry *dentry, struct inode *inode,
+                    const char *name, void *data, size_t buf_size)
 {
        int err;
 
@@ -946,7 +946,7 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
         * for it via sb->s_xattr.
         */
        if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
-               return generic_getxattr(dentry, name, data, buf_size);
+               return generic_getxattr(dentry, inode, name, data, buf_size);
 
        if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
                /*
@@ -961,7 +961,7 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
                        return -EOPNOTSUPP;
        }
 
-       err = __jfs_getxattr(d_inode(dentry), name, data, buf_size);
+       err = __jfs_getxattr(inode, name, data, buf_size);
 
        return err;
 }
index 756dd56aaf60acd337fb251fb287cbd382d57740..4c643c128c22f6789ec805922bacc31878e6b25a 100644 (file)
@@ -208,10 +208,10 @@ int kernfs_iop_removexattr(struct dentry *dentry, const char *name)
        return simple_xattr_remove(&attrs->xattrs, name);
 }
 
-ssize_t kernfs_iop_getxattr(struct dentry *dentry, const char *name, void *buf,
-                           size_t size)
+ssize_t kernfs_iop_getxattr(struct dentry *unused, struct inode *inode,
+                           const char *name, void *buf, size_t size)
 {
-       struct kernfs_node *kn = dentry->d_fsdata;
+       struct kernfs_node *kn = inode->i_private;
        struct kernfs_iattrs *attrs;
 
        attrs = kernfs_iattrs(kn);
index 6762bfbd82071a64946eb5335d746e81bc51c9c6..45c9192c276e4544621dc393da03d76b088d86f3 100644 (file)
@@ -84,8 +84,8 @@ int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry,
 int kernfs_iop_setxattr(struct dentry *dentry, 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, const char *name, void *buf,
-                           size_t size);
+ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode,
+                           const char *name, void *buf, size_t size);
 ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size);
 
 /*
index c7cbfb092e9467db1795145816faa91e1eda731f..18804a8ea5cadb858dc158f81c0867ee76a17d3e 100644 (file)
@@ -1131,8 +1131,8 @@ static int empty_dir_setxattr(struct dentry *dentry, const char *name,
        return -EOPNOTSUPP;
 }
 
-static ssize_t empty_dir_getxattr(struct dentry *dentry, const char *name,
-                                 void *value, size_t size)
+static ssize_t empty_dir_getxattr(struct dentry *dentry, struct inode *inode,
+                                 const char *name, void *value, size_t size)
 {
        return -EOPNOTSUPP;
 }
index 985a4cdae06dd72b9a6d00789ca0e20d452b7c75..e3a0dafdf9ac7471fcb0945ce1e121db2143feaf 100644 (file)
@@ -260,8 +260,8 @@ static bool ovl_need_xattr_filter(struct dentry *dentry,
                return false;
 }
 
-ssize_t ovl_getxattr(struct dentry *dentry, const char *name,
-                    void *value, size_t size)
+ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
+                    const char *name, void *value, size_t size)
 {
        struct path realpath;
        enum ovl_path_type type = ovl_path_real(dentry, &realpath);
index 27a42975d7cd3eb4a0735d362e2ed2f285f64082..837b7dc80cc5c9d2e0f201e31d24ae594e978ef8 100644 (file)
@@ -173,8 +173,8 @@ 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);
-ssize_t ovl_getxattr(struct dentry *dentry, const char *name,
-                    void *value, size_t size);
+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);
 int ovl_removexattr(struct dentry *dentry, const char *name);
 struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
index fa20c95bd45695a2d16fa346a046d7548c4e20fd..f9693cb7623643ad07a77aad793b6fb173377923 100644 (file)
@@ -264,7 +264,7 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
        if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr)
                return false;
 
-       res = inode->i_op->getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
+       res = inode->i_op->getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1);
        if (res == 1 && val == 'y')
                return true;
 
index a5697de763f516f659b7f69e42e5eba4ad94efec..f2115158214f24ea2a56ecac9d90b5bae3d7d0e6 100644 (file)
@@ -1758,8 +1758,8 @@ int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 /* xattr.c */
 int ubifs_setxattr(struct dentry *dentry, const char *name,
                   const void *value, size_t size, int flags);
-ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
-                      size_t size);
+ssize_t ubifs_getxattr(struct dentry *dentry, struct inode *host,
+                      const char *name, void *buf, size_t size);
 ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 int ubifs_removexattr(struct dentry *dentry, const char *name);
 int ubifs_init_security(struct inode *dentry, struct inode *inode,
index b5bf23b34241820a3c26551baa5f97062b8d76b8..c2f0e5735a400b5686aa4234beb3203f8f525826 100644 (file)
@@ -374,10 +374,10 @@ int ubifs_setxattr(struct dentry *dentry, const char *name,
        return setxattr(d_inode(dentry), name, value, size, flags);
 }
 
-ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
-                      size_t size)
+ssize_t ubifs_getxattr(struct dentry *dentry, struct inode *host,
+                      const char *name, void *buf, size_t size)
 {
-       struct inode *inode, *host = d_inode(dentry);
+       struct inode *inode;
        struct ubifs_info *c = host->i_sb->s_fs_info;
        struct qstr nm = QSTR_INIT(name, strlen(name));
        struct ubifs_inode *ui;
index f3a02287d29801ed58df75601712d4c4e7c25cdb..ba4fe80f8ba770252a02f9473885a9b3aa16bc99 100644 (file)
@@ -192,7 +192,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
        if (!inode->i_op->getxattr)
                return -EOPNOTSUPP;
 
-       error = inode->i_op->getxattr(dentry, name, NULL, 0);
+       error = inode->i_op->getxattr(dentry, inode, name, NULL, 0);
        if (error < 0)
                return error;
 
@@ -203,7 +203,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
                memset(value, 0, error + 1);
        }
 
-       error = inode->i_op->getxattr(dentry, name, value, error);
+       error = inode->i_op->getxattr(dentry, inode, name, value, error);
        *xattr_value = value;
        return error;
 }
@@ -255,7 +255,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
        }
 nolsm:
        if (inode->i_op->getxattr)
-               error = inode->i_op->getxattr(dentry, name, value, size);
+               error = inode->i_op->getxattr(dentry, inode, name, value, size);
        else
                error = -EOPNOTSUPP;
 
@@ -713,14 +713,15 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
  * Find the handler for the prefix and dispatch its get() operation.
  */
 ssize_t
-generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size)
+generic_getxattr(struct dentry *dentry, struct inode *inode,
+                const char *name, void *buffer, size_t size)
 {
        const struct xattr_handler *handler;
 
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (!handler)
                return -EOPNOTSUPP;
-       return handler->get(handler, dentry, d_inode(dentry),
+       return handler->get(handler, dentry, inode,
                            name, buffer, size);
 }
 
index 13277d2715df0778932781a602ea638305b6c297..34d63032bfb7053d444ca95cb1408c7defa9fb19 100644 (file)
@@ -1698,7 +1698,8 @@ struct inode_operations {
        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);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+       ssize_t (*getxattr) (struct dentry *, struct inode *,
+                            const char *, void *, size_t);
        ssize_t (*listxattr) (struct dentry *, char *, size_t);
        int (*removexattr) (struct dentry *, const char *);
        int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
index e79e7c95182c74aa49f10e8193c7665cb5c5d1fe..7b23333c8d6ca9be5b878df215a7b11eaea8f4b1 100644 (file)
@@ -48,7 +48,7 @@ int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, i
 int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
 int vfs_removexattr(struct dentry *, const char *);
 
-ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
+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_removexattr(struct dentry *dentry, const char *name);
index d902b413941aa16ee33a46c9e782f2fb4fc655d0..f03c71f268bb8592d0c8ee39261fe6b4fe69e294 100644 (file)
@@ -2582,10 +2582,10 @@ static int shmem_xattr_validate(const char *name)
        return -EOPNOTSUPP;
 }
 
-static ssize_t shmem_getxattr(struct dentry *dentry, const char *name,
-                             void *buffer, size_t size)
+static ssize_t shmem_getxattr(struct dentry *dentry, struct inode *inode,
+                             const char *name, void *buffer, size_t size)
 {
-       struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
+       struct shmem_inode_info *info = SHMEM_I(inode);
        int err;
 
        /*
@@ -2594,7 +2594,7 @@ static ssize_t shmem_getxattr(struct dentry *dentry, const char *name,
         * for it via sb->s_xattr.
         */
        if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
-               return generic_getxattr(dentry, name, buffer, size);
+               return generic_getxattr(dentry, inode, name, buffer, size);
 
        err = shmem_xattr_validate(name);
        if (err)
index 96133777d17c2ede233f0451bcef9ac8ffe7d331..a4a5342c2f71a19fc9a3d762c0aa29ca00762970 100644 (file)
@@ -467,7 +467,7 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
 #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
 #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
 #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
-static ssize_t sockfs_getxattr(struct dentry *dentry,
+static ssize_t sockfs_getxattr(struct dentry *dentry, struct inode *inode,
                               const char *name, void *value, size_t size)
 {
        const char *proto_name;
index 48071ed7c445d025fa4ae57c12f032bfa916521f..a042077312a55f7109d254fe25264e49daa12701 100644 (file)
@@ -313,7 +313,7 @@ int cap_inode_need_killpriv(struct dentry *dentry)
        if (!inode->i_op->getxattr)
               return 0;
 
-       error = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, NULL, 0);
+       error = inode->i_op->getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
        if (error <= 0)
                return 0;
        return 1;
@@ -397,8 +397,8 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
        if (!inode || !inode->i_op->getxattr)
                return -ENODATA;
 
-       size = inode->i_op->getxattr((struct dentry *)dentry, XATTR_NAME_CAPS, &caps,
-                                  XATTR_CAPS_SZ);
+       size = inode->i_op->getxattr((struct dentry *)dentry, inode,
+                                    XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ);
        if (size == -ENODATA || size == -EOPNOTSUPP)
                /* no data, that's ok */
                return -ENODATA;
index 3d145a3ffccff3a417a40321e66b11a838c13e53..7662c2c790c6b005e3ce9a53a64fd26bd0385a76 100644 (file)
@@ -82,7 +82,7 @@ static int evm_find_protected_xattrs(struct dentry *dentry)
                return -EOPNOTSUPP;
 
        for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
-               error = inode->i_op->getxattr(dentry, *xattr, NULL, 0);
+               error = inode->i_op->getxattr(dentry, inode, *xattr, NULL, 0);
                if (error < 0) {
                        if (error == -ENODATA)
                                continue;
index 99212ff6a568f3b9c868bb9ca6d73abe7a606f6c..87ea542eda5ff9fe989fb44fb63a75c0e5e1cc67 100644 (file)
@@ -430,7 +430,8 @@ static int sb_finish_set_opts(struct super_block *sb)
                        rc = -EOPNOTSUPP;
                        goto out;
                }
-               rc = root_inode->i_op->getxattr(root, XATTR_NAME_SELINUX, NULL, 0);
+               rc = root_inode->i_op->getxattr(root, root_inode,
+                                               XATTR_NAME_SELINUX, NULL, 0);
                if (rc < 0 && rc != -ENODATA) {
                        if (rc == -EOPNOTSUPP)
                                printk(KERN_WARNING "SELinux: (dev %s, type "
@@ -1335,13 +1336,13 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                        goto out_unlock;
                }
                context[len] = '\0';
-               rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
+               rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX,
                                           context, len);
                if (rc == -ERANGE) {
                        kfree(context);
 
                        /* Need a larger buffer.  Query for the right size. */
-                       rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
+                       rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX,
                                                   NULL, 0);
                        if (rc < 0) {
                                dput(dentry);
@@ -1355,7 +1356,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                                goto out_unlock;
                        }
                        context[len] = '\0';
-                       rc = inode->i_op->getxattr(dentry,
+                       rc = inode->i_op->getxattr(dentry, inode,
                                                   XATTR_NAME_SELINUX,
                                                   context, len);
                }
index 645abf26bc5fbb92e6b916c64b499cb8119ca537..9d55924f72883cc6c306075a53aa2bf508f0ddca 100644 (file)
@@ -272,7 +272,7 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
        if (buffer == NULL)
                return ERR_PTR(-ENOMEM);
 
-       rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
+       rc = ip->i_op->getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
        if (rc < 0)
                skp = ERR_PTR(rc);
        else if (rc == 0)
@@ -3541,7 +3541,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
                                        TRANS_TRUE, TRANS_TRUE_SIZE,
                                        0);
                        } else {
-                               rc = inode->i_op->getxattr(dp,
+                               rc = inode->i_op->getxattr(dp, inode,
                                        XATTR_NAME_SMACKTRANSMUTE, trattr,
                                        TRANS_TRUE_SIZE);
                                if (rc >= 0 && strncmp(trattr, TRANS_TRUE,