소스 검색

Merge getxattr prototype change into work.lookups

The rest of work.xattr stuff isn't needed for this branch
Al Viro 9 년 전
부모
커밋
84695ffee7
100개의 변경된 파일394개의 추가작업 그리고 439개의 파일을 삭제
  1. 6 0
      Documentation/filesystems/porting
  2. 2 2
      drivers/staging/lustre/lustre/llite/llite_internal.h
  3. 2 4
      drivers/staging/lustre/lustre/llite/xattr.c
  4. 4 4
      fs/9p/acl.c
  5. 1 1
      fs/9p/vfs_inode.c
  6. 2 2
      fs/9p/xattr.c
  7. 2 2
      fs/bad_inode.c
  8. 0 3
      fs/btrfs/acl.c
  9. 3 3
      fs/btrfs/tree-log.c
  10. 2 4
      fs/btrfs/xattr.c
  11. 2 0
      fs/ceph/acl.c
  12. 1 1
      fs/ceph/super.h
  13. 4 4
      fs/ceph/xattr.c
  14. 1 1
      fs/cifs/cifs_dfs_ref.c
  15. 1 1
      fs/cifs/cifsfs.h
  16. 1 2
      fs/cifs/inode.c
  17. 1 1
      fs/cifs/readdir.c
  18. 9 47
      fs/cifs/xattr.c
  19. 4 1
      fs/ecryptfs/crypto.c
  20. 2 2
      fs/ecryptfs/ecryptfs_kernel.h
  21. 12 11
      fs/ecryptfs/inode.c
  22. 2 1
      fs/ecryptfs/mmap.c
  23. 1 1
      fs/efs/namei.c
  24. 1 1
      fs/exofs/super.c
  25. 0 3
      fs/ext2/acl.c
  26. 1 1
      fs/ext2/namei.c
  27. 3 3
      fs/ext2/xattr_security.c
  28. 3 3
      fs/ext2/xattr_trusted.c
  29. 4 4
      fs/ext2/xattr_user.c
  30. 0 3
      fs/ext4/acl.c
  31. 2 2
      fs/ext4/namei.c
  32. 3 3
      fs/ext4/xattr_security.c
  33. 3 3
      fs/ext4/xattr_trusted.c
  34. 4 4
      fs/ext4/xattr_user.c
  35. 0 3
      fs/f2fs/acl.c
  36. 1 1
      fs/f2fs/namei.c
  37. 6 8
      fs/f2fs/xattr.c
  38. 2 3
      fs/fuse/dir.c
  39. 4 5
      fs/gfs2/inode.c
  40. 1 1
      fs/gfs2/ops_fstype.c
  41. 1 1
      fs/gfs2/super.c
  42. 3 3
      fs/gfs2/xattr.c
  43. 2 3
      fs/hfs/attr.c
  44. 2 2
      fs/hfs/hfs_fs.h
  45. 0 3
      fs/hfsplus/posix_acl.c
  46. 5 5
      fs/hfsplus/xattr.c
  47. 1 1
      fs/hfsplus/xattr.h
  48. 3 3
      fs/hfsplus/xattr_security.c
  49. 3 3
      fs/hfsplus/xattr_trusted.c
  50. 3 3
      fs/hfsplus/xattr_user.c
  51. 2 2
      fs/inode.c
  52. 0 2
      fs/jffs2/acl.c
  53. 1 1
      fs/jffs2/dir.c
  54. 3 3
      fs/jffs2/security.c
  55. 1 1
      fs/jffs2/super.c
  56. 3 3
      fs/jffs2/xattr_trusted.c
  57. 3 3
      fs/jffs2/xattr_user.c
  58. 0 6
      fs/jfs/acl.c
  59. 1 1
      fs/jfs/jfs_xattr.h
  60. 1 1
      fs/jfs/namei.c
  61. 4 4
      fs/jfs/xattr.c
  62. 3 3
      fs/kernfs/inode.c
  63. 2 2
      fs/kernfs/kernfs-internal.h
  64. 2 2
      fs/libfs.c
  65. 3 3
      fs/namei.c
  66. 1 1
      fs/nfs/direct.c
  67. 41 2
      fs/nfs/nfs3acl.c
  68. 6 6
      fs/nfs/nfs4proc.c
  69. 2 2
      fs/nfsd/nfs3proc.c
  70. 1 1
      fs/nfsd/nfs3xdr.c
  71. 1 1
      fs/nfsd/nfsfh.c
  72. 1 1
      fs/nilfs2/namei.c
  73. 3 0
      fs/ocfs2/dlmglue.c
  74. 1 1
      fs/ocfs2/file.c
  75. 10 10
      fs/ocfs2/xattr.c
  76. 6 4
      fs/orangefs/xattr.c
  77. 2 2
      fs/overlayfs/inode.c
  78. 2 2
      fs/overlayfs/overlayfs.h
  79. 1 1
      fs/overlayfs/super.c
  80. 75 41
      fs/posix_acl.c
  81. 3 3
      fs/reiserfs/file.c
  82. 9 9
      fs/reiserfs/namei.c
  83. 0 54
      fs/reiserfs/xattr.c
  84. 1 8
      fs/reiserfs/xattr.h
  85. 2 6
      fs/reiserfs/xattr_acl.c
  86. 8 11
      fs/reiserfs/xattr_security.c
  87. 8 11
      fs/reiserfs/xattr_trusted.c
  88. 8 11
      fs/reiserfs/xattr_user.c
  89. 4 2
      fs/squashfs/xattr.c
  90. 2 2
      fs/ubifs/ubifs.h
  91. 3 3
      fs/ubifs/xattr.c
  92. 1 1
      fs/udf/namei.c
  93. 1 1
      fs/ufs/super.c
  94. 7 5
      fs/xattr.c
  95. 6 14
      fs/xfs/xfs_acl.c
  96. 3 3
      fs/xfs/xfs_xattr.c
  97. 14 1
      include/linux/fs.h
  98. 0 1
      include/linux/posix_acl.h
  99. 3 2
      include/linux/xattr.h
  100. 3 3
      include/trace/events/ext4.h

+ 6 - 0
Documentation/filesystems/porting

@@ -525,3 +525,9 @@ in your dentry operations instead.
 	set_delayed_call() where it used to set *cookie.
 	set_delayed_call() where it used to set *cookie.
 	->put_link() is gone - just give the destructor to set_delayed_call()
 	->put_link() is gone - just give the destructor to set_delayed_call()
 	in ->get_link().
 	in ->get_link().
+--
+[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.

+ 2 - 2
drivers/staging/lustre/lustre/llite/llite_internal.h

@@ -1042,8 +1042,8 @@ static inline __u64 ll_file_maxbytes(struct inode *inode)
 /* llite/xattr.c */
 /* llite/xattr.c */
 int ll_setxattr(struct dentry *dentry, const char *name,
 int ll_setxattr(struct dentry *dentry, const char *name,
 		const void *value, size_t size, int flags);
 		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);
 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
 int ll_removexattr(struct dentry *dentry, const char *name);
 int ll_removexattr(struct dentry *dentry, const char *name);
 
 

+ 2 - 4
drivers/staging/lustre/lustre/llite/xattr.c

@@ -451,11 +451,9 @@ out:
 	return rc;
 	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(inode);
 	LASSERT(name);
 	LASSERT(name);
 
 

+ 4 - 4
fs/9p/acl.c

@@ -93,7 +93,7 @@ static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type)
 	 * instantiating the inode (v9fs_inode_from_fid)
 	 * instantiating the inode (v9fs_inode_from_fid)
 	 */
 	 */
 	acl = get_cached_acl(inode, type);
 	acl = get_cached_acl(inode, type);
-	BUG_ON(acl == ACL_NOT_CACHED);
+	BUG_ON(is_uncached_acl(acl));
 	return acl;
 	return acl;
 }
 }
 
 
@@ -213,8 +213,8 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep,
 }
 }
 
 
 static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
 static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
-			      struct dentry *dentry, const char *name,
-			      void *buffer, size_t size)
+			      struct dentry *dentry, struct inode *inode,
+			      const char *name, void *buffer, size_t size)
 {
 {
 	struct v9fs_session_info *v9ses;
 	struct v9fs_session_info *v9ses;
 	struct posix_acl *acl;
 	struct posix_acl *acl;
@@ -227,7 +227,7 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
 	if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
 	if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
 		return v9fs_xattr_get(dentry, handler->name, buffer, size);
 		return v9fs_xattr_get(dentry, handler->name, buffer, size);
 
 
-	acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags);
+	acl = v9fs_get_cached_acl(inode, handler->flags);
 	if (IS_ERR(acl))
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
 		return PTR_ERR(acl);
 	if (acl == NULL)
 	if (acl == NULL)

+ 1 - 1
fs/9p/vfs_inode.c

@@ -1071,7 +1071,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 	if (IS_ERR(st))
 	if (IS_ERR(st))
 		return PTR_ERR(st);
 		return PTR_ERR(st);
 
 
-	v9fs_stat2inode(st, d_inode(dentry), d_inode(dentry)->i_sb);
+	v9fs_stat2inode(st, d_inode(dentry), dentry->d_sb);
 	generic_fillattr(d_inode(dentry), stat);
 	generic_fillattr(d_inode(dentry), stat);
 
 
 	p9stat_free(st);
 	p9stat_free(st);

+ 2 - 2
fs/9p/xattr.c

@@ -138,8 +138,8 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
 }
 }
 
 
 static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
 static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
-				  struct dentry *dentry, const char *name,
-				  void *buffer, size_t size)
+				  struct dentry *dentry, struct inode *inode,
+				  const char *name, void *buffer, size_t size)
 {
 {
 	const char *full_name = xattr_full_name(handler, name);
 	const char *full_name = xattr_full_name(handler, name);
 
 

+ 2 - 2
fs/bad_inode.c

@@ -106,8 +106,8 @@ static int bad_inode_setxattr(struct dentry *dentry, const char *name,
 	return -EIO;
 	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;
 	return -EIO;
 }
 }

+ 0 - 3
fs/btrfs/acl.c

@@ -63,9 +63,6 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
 	}
 	}
 	kfree(value);
 	kfree(value);
 
 
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
-
 	return acl;
 	return acl;
 }
 }
 
 

+ 3 - 3
fs/btrfs/tree-log.c

@@ -4988,7 +4988,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
 			goto out;
 			goto out;
 
 
 	if (!S_ISDIR(inode->i_mode)) {
 	if (!S_ISDIR(inode->i_mode)) {
-		if (!parent || d_really_is_negative(parent) || sb != d_inode(parent)->i_sb)
+		if (!parent || d_really_is_negative(parent) || sb != parent->d_sb)
 			goto out;
 			goto out;
 		inode = d_inode(parent);
 		inode = d_inode(parent);
 	}
 	}
@@ -5009,7 +5009,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
 			break;
 			break;
 		}
 		}
 
 
-		if (!parent || d_really_is_negative(parent) || sb != d_inode(parent)->i_sb)
+		if (!parent || d_really_is_negative(parent) || sb != parent->d_sb)
 			break;
 			break;
 
 
 		if (IS_ROOT(parent))
 		if (IS_ROOT(parent))
@@ -5422,7 +5422,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
 	}
 	}
 
 
 	while (1) {
 	while (1) {
-		if (!parent || d_really_is_negative(parent) || sb != d_inode(parent)->i_sb)
+		if (!parent || d_really_is_negative(parent) || sb != parent->d_sb)
 			break;
 			break;
 
 
 		inode = d_inode(parent);
 		inode = d_inode(parent);

+ 2 - 4
fs/btrfs/xattr.c

@@ -369,11 +369,9 @@ err:
 }
 }
 
 
 static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
 static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
-				   struct dentry *dentry, const char *name,
-				   void *buffer, size_t size)
+				   struct dentry *unused, struct inode *inode,
+				   const char *name, void *buffer, size_t size)
 {
 {
-	struct inode *inode = d_inode(dentry);
-
 	name = xattr_full_name(handler, name);
 	name = xattr_full_name(handler, name);
 	return __btrfs_getxattr(inode, name, buffer, size);
 	return __btrfs_getxattr(inode, name, buffer, size);
 }
 }

+ 2 - 0
fs/ceph/acl.c

@@ -37,6 +37,8 @@ static inline void ceph_set_cached_acl(struct inode *inode,
 	spin_lock(&ci->i_ceph_lock);
 	spin_lock(&ci->i_ceph_lock);
 	if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 0))
 	if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 0))
 		set_cached_acl(inode, type, acl);
 		set_cached_acl(inode, type, acl);
+	else
+		forget_cached_acl(inode, type);
 	spin_unlock(&ci->i_ceph_lock);
 	spin_unlock(&ci->i_ceph_lock);
 }
 }
 
 

+ 1 - 1
fs/ceph/super.h

@@ -795,7 +795,7 @@ extern int ceph_setxattr(struct dentry *, const char *, const void *,
 int __ceph_setxattr(struct dentry *, const char *, const void *, size_t, int);
 int __ceph_setxattr(struct dentry *, const char *, const void *, size_t, int);
 ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t);
 ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t);
 int __ceph_removexattr(struct dentry *, const char *);
 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 ssize_t ceph_listxattr(struct dentry *, char *, size_t);
 extern int ceph_removexattr(struct dentry *, const char *);
 extern int ceph_removexattr(struct dentry *, const char *);
 extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);
 extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);

+ 4 - 4
fs/ceph/xattr.c

@@ -804,13 +804,13 @@ out:
 	return err;
 	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))
 	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)
 ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)

+ 1 - 1
fs/cifs/cifs_dfs_ref.c

@@ -302,7 +302,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
 	if (full_path == NULL)
 	if (full_path == NULL)
 		goto cdda_exit;
 		goto cdda_exit;
 
 
-	cifs_sb = CIFS_SB(d_inode(mntpt)->i_sb);
+	cifs_sb = CIFS_SB(mntpt->d_sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink)) {
 	if (IS_ERR(tlink)) {
 		mnt = ERR_CAST(tlink);
 		mnt = ERR_CAST(tlink);

+ 1 - 1
fs/cifs/cifsfs.h

@@ -123,7 +123,7 @@ extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
 extern int	cifs_removexattr(struct dentry *, const char *);
 extern int	cifs_removexattr(struct dentry *, const char *);
 extern int	cifs_setxattr(struct dentry *, const char *, const void *,
 extern int	cifs_setxattr(struct dentry *, const char *, const void *,
 			size_t, int);
 			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 ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
 extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 #ifdef CONFIG_CIFS_NFSD_EXPORT
 #ifdef CONFIG_CIFS_NFSD_EXPORT

+ 1 - 2
fs/cifs/inode.c

@@ -2418,8 +2418,7 @@ cifs_setattr_exit:
 int
 int
 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 {
 {
-	struct inode *inode = d_inode(direntry);
-	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
 	struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
 	struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
 
 
 	if (pTcon->unix_ext)
 	if (pTcon->unix_ext)

+ 1 - 1
fs/cifs/readdir.c

@@ -78,7 +78,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
 {
 {
 	struct dentry *dentry, *alias;
 	struct dentry *dentry, *alias;
 	struct inode *inode;
 	struct inode *inode;
-	struct super_block *sb = d_inode(parent)->i_sb;
+	struct super_block *sb = parent->d_sb;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 
 
 	cifs_dbg(FYI, "%s: for %s\n", __func__, name->name);
 	cifs_dbg(FYI, "%s: for %s\n", __func__, name->name);

+ 9 - 47
fs/cifs/xattr.c

@@ -42,21 +42,11 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
 	int rc = -EOPNOTSUPP;
 	int rc = -EOPNOTSUPP;
 #ifdef CONFIG_CIFS_XATTR
 #ifdef CONFIG_CIFS_XATTR
 	unsigned int xid;
 	unsigned int xid;
-	struct cifs_sb_info *cifs_sb;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
 	struct tcon_link *tlink;
 	struct tcon_link *tlink;
 	struct cifs_tcon *pTcon;
 	struct cifs_tcon *pTcon;
-	struct super_block *sb;
 	char *full_path = NULL;
 	char *full_path = NULL;
 
 
-	if (direntry == NULL)
-		return -EIO;
-	if (d_really_is_negative(direntry))
-		return -EIO;
-	sb = d_inode(direntry)->i_sb;
-	if (sb == NULL)
-		return -EIO;
-
-	cifs_sb = CIFS_SB(sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink))
 	if (IS_ERR(tlink))
 		return PTR_ERR(tlink);
 		return PTR_ERR(tlink);
@@ -103,21 +93,12 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
 	int rc = -EOPNOTSUPP;
 	int rc = -EOPNOTSUPP;
 #ifdef CONFIG_CIFS_XATTR
 #ifdef CONFIG_CIFS_XATTR
 	unsigned int xid;
 	unsigned int xid;
-	struct cifs_sb_info *cifs_sb;
+	struct super_block *sb = direntry->d_sb;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 	struct tcon_link *tlink;
 	struct tcon_link *tlink;
 	struct cifs_tcon *pTcon;
 	struct cifs_tcon *pTcon;
-	struct super_block *sb;
 	char *full_path;
 	char *full_path;
 
 
-	if (direntry == NULL)
-		return -EIO;
-	if (d_really_is_negative(direntry))
-		return -EIO;
-	sb = d_inode(direntry)->i_sb;
-	if (sb == NULL)
-		return -EIO;
-
-	cifs_sb = CIFS_SB(sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink))
 	if (IS_ERR(tlink))
 		return PTR_ERR(tlink);
 		return PTR_ERR(tlink);
@@ -232,27 +213,18 @@ set_ea_exit:
 	return rc;
 	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;
 	ssize_t rc = -EOPNOTSUPP;
 #ifdef CONFIG_CIFS_XATTR
 #ifdef CONFIG_CIFS_XATTR
 	unsigned int xid;
 	unsigned int xid;
-	struct cifs_sb_info *cifs_sb;
+	struct super_block *sb = direntry->d_sb;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 	struct tcon_link *tlink;
 	struct tcon_link *tlink;
 	struct cifs_tcon *pTcon;
 	struct cifs_tcon *pTcon;
-	struct super_block *sb;
 	char *full_path;
 	char *full_path;
 
 
-	if (direntry == NULL)
-		return -EIO;
-	if (d_really_is_negative(direntry))
-		return -EIO;
-	sb = d_inode(direntry)->i_sb;
-	if (sb == NULL)
-		return -EIO;
-
-	cifs_sb = CIFS_SB(sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink))
 	if (IS_ERR(tlink))
 		return PTR_ERR(tlink);
 		return PTR_ERR(tlink);
@@ -324,7 +296,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
 				goto get_ea_exit; /* rc already EOPNOTSUPP */
 				goto get_ea_exit; /* rc already EOPNOTSUPP */
 
 
 			pacl = pTcon->ses->server->ops->get_acl(cifs_sb,
 			pacl = pTcon->ses->server->ops->get_acl(cifs_sb,
-					d_inode(direntry), full_path, &acllen);
+					inode, full_path, &acllen);
 			if (IS_ERR(pacl)) {
 			if (IS_ERR(pacl)) {
 				rc = PTR_ERR(pacl);
 				rc = PTR_ERR(pacl);
 				cifs_dbg(VFS, "%s: error %zd getting sec desc\n",
 				cifs_dbg(VFS, "%s: error %zd getting sec desc\n",
@@ -374,21 +346,11 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
 	ssize_t rc = -EOPNOTSUPP;
 	ssize_t rc = -EOPNOTSUPP;
 #ifdef CONFIG_CIFS_XATTR
 #ifdef CONFIG_CIFS_XATTR
 	unsigned int xid;
 	unsigned int xid;
-	struct cifs_sb_info *cifs_sb;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
 	struct tcon_link *tlink;
 	struct tcon_link *tlink;
 	struct cifs_tcon *pTcon;
 	struct cifs_tcon *pTcon;
-	struct super_block *sb;
 	char *full_path;
 	char *full_path;
 
 
-	if (direntry == NULL)
-		return -EIO;
-	if (d_really_is_negative(direntry))
-		return -EIO;
-	sb = d_inode(direntry)->i_sb;
-	if (sb == NULL)
-		return -EIO;
-
-	cifs_sb = CIFS_SB(sb);
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 
 

+ 4 - 1
fs/ecryptfs/crypto.c

@@ -1369,7 +1369,9 @@ int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode)
 	ssize_t size;
 	ssize_t size;
 	int rc = 0;
 	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);
 				       page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE);
 	if (size < 0) {
 	if (size < 0) {
 		if (unlikely(ecryptfs_verbosity > 0))
 		if (unlikely(ecryptfs_verbosity > 0))
@@ -1391,6 +1393,7 @@ int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry,
 	int rc;
 	int rc;
 
 
 	rc = ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry),
 	rc = ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry),
+				     ecryptfs_inode_to_lower(inode),
 				     ECRYPTFS_XATTR_NAME, file_size,
 				     ECRYPTFS_XATTR_NAME, file_size,
 				     ECRYPTFS_SIZE_AND_MARKER_BYTES);
 				     ECRYPTFS_SIZE_AND_MARKER_BYTES);
 	if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
 	if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)

+ 2 - 2
fs/ecryptfs/ecryptfs_kernel.h

@@ -607,8 +607,8 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
 			  unsigned char *src, struct dentry *ecryptfs_dentry);
 			  unsigned char *src, struct dentry *ecryptfs_dentry);
 int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
 int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
 ssize_t
 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
 int
 ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 		  size_t size, int flags);
 		  size_t size, int flags);

+ 12 - 11
fs/ecryptfs/inode.c

@@ -1033,29 +1033,30 @@ out:
 }
 }
 
 
 ssize_t
 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;
 	int rc = 0;
 
 
-	if (!d_inode(lower_dentry)->i_op->getxattr) {
+	if (!lower_inode->i_op->getxattr) {
 		rc = -EOPNOTSUPP;
 		rc = -EOPNOTSUPP;
 		goto out;
 		goto out;
 	}
 	}
-	inode_lock(d_inode(lower_dentry));
-	rc = d_inode(lower_dentry)->i_op->getxattr(lower_dentry, name, value,
-						   size);
-	inode_unlock(d_inode(lower_dentry));
+	inode_lock(lower_inode);
+	rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
+					 name, value, size);
+	inode_unlock(lower_inode);
 out:
 out:
 	return rc;
 	return rc;
 }
 }
 
 
 static ssize_t
 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
 static ssize_t

+ 2 - 1
fs/ecryptfs/mmap.c

@@ -436,7 +436,8 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
 		goto out;
 		goto out;
 	}
 	}
 	inode_lock(lower_inode);
 	inode_lock(lower_inode);
-	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_SIZE);
 					   xattr_virt, PAGE_SIZE);
 	if (size < 0)
 	if (size < 0)
 		size = 8;
 		size = 8;

+ 1 - 1
fs/efs/namei.c

@@ -113,7 +113,7 @@ struct dentry *efs_get_parent(struct dentry *child)
 
 
 	ino = efs_find_entry(d_inode(child), "..", 2);
 	ino = efs_find_entry(d_inode(child), "..", 2);
 	if (ino)
 	if (ino)
-		parent = d_obtain_alias(efs_iget(d_inode(child)->i_sb, ino));
+		parent = d_obtain_alias(efs_iget(child->d_sb, ino));
 
 
 	return parent;
 	return parent;
 }
 }

+ 1 - 1
fs/exofs/super.c

@@ -958,7 +958,7 @@ static struct dentry *exofs_get_parent(struct dentry *child)
 	if (!ino)
 	if (!ino)
 		return ERR_PTR(-ESTALE);
 		return ERR_PTR(-ESTALE);
 
 
-	return d_obtain_alias(exofs_iget(d_inode(child)->i_sb, ino));
+	return d_obtain_alias(exofs_iget(child->d_sb, ino));
 }
 }
 
 
 static struct inode *exofs_nfs_get_inode(struct super_block *sb,
 static struct inode *exofs_nfs_get_inode(struct super_block *sb,

+ 0 - 3
fs/ext2/acl.c

@@ -172,9 +172,6 @@ ext2_get_acl(struct inode *inode, int type)
 		acl = ERR_PTR(retval);
 		acl = ERR_PTR(retval);
 	kfree(value);
 	kfree(value);
 
 
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
-
 	return acl;
 	return acl;
 }
 }
 
 

+ 1 - 1
fs/ext2/namei.c

@@ -82,7 +82,7 @@ struct dentry *ext2_get_parent(struct dentry *child)
 	unsigned long ino = ext2_inode_by_name(d_inode(child), &dotdot);
 	unsigned long ino = ext2_inode_by_name(d_inode(child), &dotdot);
 	if (!ino)
 	if (!ino)
 		return ERR_PTR(-ENOENT);
 		return ERR_PTR(-ENOENT);
-	return d_obtain_alias(ext2_iget(d_inode(child)->i_sb, ino));
+	return d_obtain_alias(ext2_iget(child->d_sb, ino));
 } 
 } 
 
 
 /*
 /*

+ 3 - 3
fs/ext2/xattr_security.c

@@ -9,10 +9,10 @@
 
 
 static int
 static int
 ext2_xattr_security_get(const struct xattr_handler *handler,
 ext2_xattr_security_get(const struct xattr_handler *handler,
-			struct dentry *dentry, const char *name,
-			void *buffer, size_t size)
+			struct dentry *unused, struct inode *inode,
+			const char *name, void *buffer, size_t size)
 {
 {
-	return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name,
+	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_SECURITY, name,
 			      buffer, size);
 			      buffer, size);
 }
 }
 
 

+ 3 - 3
fs/ext2/xattr_trusted.c

@@ -16,10 +16,10 @@ ext2_xattr_trusted_list(struct dentry *dentry)
 
 
 static int
 static int
 ext2_xattr_trusted_get(const struct xattr_handler *handler,
 ext2_xattr_trusted_get(const struct xattr_handler *handler,
-		       struct dentry *dentry, const char *name,
-		       void *buffer, size_t size)
+		       struct dentry *unused, struct inode *inode,
+		       const char *name, void *buffer, size_t size)
 {
 {
-	return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name,
+	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name,
 			      buffer, size);
 			      buffer, size);
 }
 }
 
 

+ 4 - 4
fs/ext2/xattr_user.c

@@ -18,12 +18,12 @@ ext2_xattr_user_list(struct dentry *dentry)
 
 
 static int
 static int
 ext2_xattr_user_get(const struct xattr_handler *handler,
 ext2_xattr_user_get(const struct xattr_handler *handler,
-		    struct dentry *dentry, const char *name,
-		    void *buffer, size_t size)
+		    struct dentry *unused, struct inode *inode,
+		    const char *name, void *buffer, size_t size)
 {
 {
-	if (!test_opt(dentry->d_sb, XATTR_USER))
+	if (!test_opt(inode->i_sb, XATTR_USER))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
-	return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_USER,
+	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER,
 			      name, buffer, size);
 			      name, buffer, size);
 }
 }
 
 

+ 0 - 3
fs/ext4/acl.c

@@ -172,9 +172,6 @@ ext4_get_acl(struct inode *inode, int type)
 		acl = ERR_PTR(retval);
 		acl = ERR_PTR(retval);
 	kfree(value);
 	kfree(value);
 
 
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
-
 	return acl;
 	return acl;
 }
 }
 
 

+ 2 - 2
fs/ext4/namei.c

@@ -1638,13 +1638,13 @@ struct dentry *ext4_get_parent(struct dentry *child)
 	ino = le32_to_cpu(de->inode);
 	ino = le32_to_cpu(de->inode);
 	brelse(bh);
 	brelse(bh);
 
 
-	if (!ext4_valid_inum(d_inode(child)->i_sb, ino)) {
+	if (!ext4_valid_inum(child->d_sb, ino)) {
 		EXT4_ERROR_INODE(d_inode(child),
 		EXT4_ERROR_INODE(d_inode(child),
 				 "bad parent inode number: %u", ino);
 				 "bad parent inode number: %u", ino);
 		return ERR_PTR(-EFSCORRUPTED);
 		return ERR_PTR(-EFSCORRUPTED);
 	}
 	}
 
 
-	return d_obtain_alias(ext4_iget_normal(d_inode(child)->i_sb, ino));
+	return d_obtain_alias(ext4_iget_normal(child->d_sb, ino));
 }
 }
 
 
 /*
 /*

+ 3 - 3
fs/ext4/xattr_security.c

@@ -13,10 +13,10 @@
 
 
 static int
 static int
 ext4_xattr_security_get(const struct xattr_handler *handler,
 ext4_xattr_security_get(const struct xattr_handler *handler,
-			struct dentry *dentry, const char *name,
-			void *buffer, size_t size)
+			struct dentry *unused, struct inode *inode,
+			const char *name, void *buffer, size_t size)
 {
 {
-	return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY,
+	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_SECURITY,
 			      name, buffer, size);
 			      name, buffer, size);
 }
 }
 
 

+ 3 - 3
fs/ext4/xattr_trusted.c

@@ -20,10 +20,10 @@ ext4_xattr_trusted_list(struct dentry *dentry)
 
 
 static int
 static int
 ext4_xattr_trusted_get(const struct xattr_handler *handler,
 ext4_xattr_trusted_get(const struct xattr_handler *handler,
-		       struct dentry *dentry, const char *name, void *buffer,
-		       size_t size)
+		       struct dentry *unused, struct inode *inode,
+		       const char *name, void *buffer, size_t size)
 {
 {
-	return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED,
+	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED,
 			      name, buffer, size);
 			      name, buffer, size);
 }
 }
 
 

+ 4 - 4
fs/ext4/xattr_user.c

@@ -19,12 +19,12 @@ ext4_xattr_user_list(struct dentry *dentry)
 
 
 static int
 static int
 ext4_xattr_user_get(const struct xattr_handler *handler,
 ext4_xattr_user_get(const struct xattr_handler *handler,
-		    struct dentry *dentry, const char *name,
-		    void *buffer, size_t size)
+		    struct dentry *unused, struct inode *inode,
+		    const char *name, void *buffer, size_t size)
 {
 {
-	if (!test_opt(dentry->d_sb, XATTR_USER))
+	if (!test_opt(inode->i_sb, XATTR_USER))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
-	return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_USER,
+	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_USER,
 			      name, buffer, size);
 			      name, buffer, size);
 }
 }
 
 

+ 0 - 3
fs/f2fs/acl.c

@@ -190,9 +190,6 @@ static struct posix_acl *__f2fs_get_acl(struct inode *inode, int type,
 		acl = ERR_PTR(retval);
 		acl = ERR_PTR(retval);
 	kfree(value);
 	kfree(value);
 
 
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
-
 	return acl;
 	return acl;
 }
 }
 
 

+ 1 - 1
fs/f2fs/namei.c

@@ -202,7 +202,7 @@ struct dentry *f2fs_get_parent(struct dentry *child)
 	unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot);
 	unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot);
 	if (!ino)
 	if (!ino)
 		return ERR_PTR(-ENOENT);
 		return ERR_PTR(-ENOENT);
-	return d_obtain_alias(f2fs_iget(d_inode(child)->i_sb, ino));
+	return d_obtain_alias(f2fs_iget(child->d_sb, ino));
 }
 }
 
 
 static int __recover_dot_dentries(struct inode *dir, nid_t pino)
 static int __recover_dot_dentries(struct inode *dir, nid_t pino)

+ 6 - 8
fs/f2fs/xattr.c

@@ -26,10 +26,10 @@
 #include "xattr.h"
 #include "xattr.h"
 
 
 static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
 static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
-		struct dentry *dentry, const char *name, void *buffer,
-		size_t size)
+		struct dentry *unused, struct inode *inode,
+		const char *name, void *buffer, size_t size)
 {
 {
-	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
+	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
 
 
 	switch (handler->flags) {
 	switch (handler->flags) {
 	case F2FS_XATTR_INDEX_USER:
 	case F2FS_XATTR_INDEX_USER:
@@ -45,7 +45,7 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	return f2fs_getxattr(d_inode(dentry), handler->flags, name,
+	return f2fs_getxattr(inode, handler->flags, name,
 			     buffer, size, NULL);
 			     buffer, size, NULL);
 }
 }
 
 
@@ -86,11 +86,9 @@ static bool f2fs_xattr_trusted_list(struct dentry *dentry)
 }
 }
 
 
 static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
 static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
-		struct dentry *dentry, const char *name, void *buffer,
-		size_t size)
+		struct dentry *unused, struct inode *inode,
+		const char *name, void *buffer, size_t size)
 {
 {
-	struct inode *inode = d_inode(dentry);
-
 	if (buffer)
 	if (buffer)
 		*((char *)buffer) = F2FS_I(inode)->i_advise;
 		*((char *)buffer) = F2FS_I(inode)->i_advise;
 	return sizeof(char);
 	return sizeof(char);

+ 2 - 3
fs/fuse/dir.c

@@ -1759,10 +1759,9 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
 	return err;
 	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);
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	FUSE_ARGS(args);
 	FUSE_ARGS(args);
 	struct fuse_getxattr_in inarg;
 	struct fuse_getxattr_in inarg;

+ 4 - 5
fs/gfs2/inode.c

@@ -1968,22 +1968,21 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name,
 	return ret;
 	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_inode *ip = GFS2_I(inode);
 	struct gfs2_holder gh;
 	struct gfs2_holder gh;
 	int ret;
 	int ret;
 
 
 	/* For selinux during lookup */
 	/* For selinux during lookup */
 	if (gfs2_glock_is_locked_by_me(ip->i_gl))
 	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);
 	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
 	ret = gfs2_glock_nq(&gh);
 	ret = gfs2_glock_nq(&gh);
 	if (ret == 0) {
 	if (ret == 0) {
-		ret = generic_getxattr(dentry, name, data, size);
+		ret = generic_getxattr(dentry, inode, name, data, size);
 		gfs2_glock_dq(&gh);
 		gfs2_glock_dq(&gh);
 	}
 	}
 	gfs2_holder_uninit(&gh);
 	gfs2_holder_uninit(&gh);

+ 1 - 1
fs/gfs2/ops_fstype.c

@@ -1360,7 +1360,7 @@ static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type,
 		return ERR_PTR(error);
 		return ERR_PTR(error);
 	}
 	}
 	s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, flags,
 	s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, flags,
-		 d_inode(path.dentry)->i_sb->s_bdev);
+		 path.dentry->d_sb->s_bdev);
 	path_put(&path);
 	path_put(&path);
 	if (IS_ERR(s)) {
 	if (IS_ERR(s)) {
 		pr_warn("gfs2 mount does not exist\n");
 		pr_warn("gfs2 mount does not exist\n");

+ 1 - 1
fs/gfs2/super.c

@@ -1176,7 +1176,7 @@ static int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *s
 
 
 static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
 static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
 {
-	struct super_block *sb = d_inode(dentry)->i_sb;
+	struct super_block *sb = dentry->d_sb;
 	struct gfs2_sbd *sdp = sb->s_fs_info;
 	struct gfs2_sbd *sdp = sb->s_fs_info;
 	struct gfs2_statfs_change_host sc;
 	struct gfs2_statfs_change_host sc;
 	int error;
 	int error;

+ 3 - 3
fs/gfs2/xattr.c

@@ -584,10 +584,10 @@ out:
  * Returns: actual size of data on success, -errno on error
  * Returns: actual size of data on success, -errno on error
  */
  */
 static int gfs2_xattr_get(const struct xattr_handler *handler,
 static int gfs2_xattr_get(const struct xattr_handler *handler,
-			  struct dentry *dentry, const char *name,
-			  void *buffer, size_t size)
+			  struct dentry *unused, struct inode *inode,
+			  const char *name, void *buffer, size_t size)
 {
 {
-	struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
+	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_ea_location el;
 	struct gfs2_ea_location el;
 	int type = handler->flags;
 	int type = handler->flags;
 	int error;
 	int error;

+ 2 - 3
fs/hfs/attr.c

@@ -56,10 +56,9 @@ out:
 	return res;
 	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;
 	struct hfs_find_data fd;
 	hfs_cat_rec rec;
 	hfs_cat_rec rec;
 	struct hfs_cat_file *file;
 	struct hfs_cat_file *file;

+ 2 - 2
fs/hfs/hfs_fs.h

@@ -213,8 +213,8 @@ extern void hfs_delete_inode(struct inode *);
 /* attr.c */
 /* attr.c */
 extern int hfs_setxattr(struct dentry *dentry, const char *name,
 extern int hfs_setxattr(struct dentry *dentry, const char *name,
 			const void *value, size_t size, int flags);
 			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);
 extern ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 
 
 /* mdb.c */
 /* mdb.c */

+ 0 - 3
fs/hfsplus/posix_acl.c

@@ -48,9 +48,6 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
 
 
 	hfsplus_destroy_attr_entry((hfsplus_attr_entry *)value);
 	hfsplus_destroy_attr_entry((hfsplus_attr_entry *)value);
 
 
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
-
 	return acl;
 	return acl;
 }
 }
 
 

+ 5 - 5
fs/hfsplus/xattr.c

@@ -579,7 +579,7 @@ failed_getxattr_init:
 	return res;
 	return res;
 }
 }
 
 
-ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name,
+ssize_t hfsplus_getxattr(struct inode *inode, const char *name,
 			 void *value, size_t size,
 			 void *value, size_t size,
 			 const char *prefix, size_t prefixlen)
 			 const char *prefix, size_t prefixlen)
 {
 {
@@ -594,7 +594,7 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name,
 	strcpy(xattr_name, prefix);
 	strcpy(xattr_name, prefix);
 	strcpy(xattr_name + prefixlen, name);
 	strcpy(xattr_name + prefixlen, name);
 
 
-	res = __hfsplus_getxattr(d_inode(dentry), xattr_name, value, size);
+	res = __hfsplus_getxattr(inode, xattr_name, value, size);
 	kfree(xattr_name);
 	kfree(xattr_name);
 	return res;
 	return res;
 
 
@@ -844,8 +844,8 @@ end_removexattr:
 }
 }
 
 
 static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
 static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
-				struct dentry *dentry, const char *name,
-				void *buffer, size_t size)
+				struct dentry *unused, struct inode *inode,
+				const char *name, void *buffer, size_t size)
 {
 {
 	/*
 	/*
 	 * Don't allow retrieving properly prefixed attributes
 	 * Don't allow retrieving properly prefixed attributes
@@ -860,7 +860,7 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
 	 * creates), so we pass the name through unmodified (after
 	 * creates), so we pass the name through unmodified (after
 	 * ensuring it doesn't conflict with another namespace).
 	 * ensuring it doesn't conflict with another namespace).
 	 */
 	 */
-	return __hfsplus_getxattr(d_inode(dentry), name, buffer, size);
+	return __hfsplus_getxattr(inode, name, buffer, size);
 }
 }
 
 
 static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
 static int hfsplus_osx_setxattr(const struct xattr_handler *handler,

+ 1 - 1
fs/hfsplus/xattr.h

@@ -28,7 +28,7 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name,
 ssize_t __hfsplus_getxattr(struct inode *inode, const char *name,
 ssize_t __hfsplus_getxattr(struct inode *inode, const char *name,
 			   void *value, size_t size);
 			   void *value, size_t size);
 
 
-ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name,
+ssize_t hfsplus_getxattr(struct inode *inode, const char *name,
 			 void *value, size_t size,
 			 void *value, size_t size,
 			 const char *prefix, size_t prefixlen);
 			 const char *prefix, size_t prefixlen);
 
 

+ 3 - 3
fs/hfsplus/xattr_security.c

@@ -14,10 +14,10 @@
 #include "acl.h"
 #include "acl.h"
 
 
 static int hfsplus_security_getxattr(const struct xattr_handler *handler,
 static int hfsplus_security_getxattr(const struct xattr_handler *handler,
-				     struct dentry *dentry, const char *name,
-				     void *buffer, size_t size)
+				     struct dentry *unused, struct inode *inode,
+				     const char *name, void *buffer, size_t size)
 {
 {
-	return hfsplus_getxattr(dentry, name, buffer, size,
+	return hfsplus_getxattr(inode, name, buffer, size,
 				XATTR_SECURITY_PREFIX,
 				XATTR_SECURITY_PREFIX,
 				XATTR_SECURITY_PREFIX_LEN);
 				XATTR_SECURITY_PREFIX_LEN);
 }
 }

+ 3 - 3
fs/hfsplus/xattr_trusted.c

@@ -12,10 +12,10 @@
 #include "xattr.h"
 #include "xattr.h"
 
 
 static int hfsplus_trusted_getxattr(const struct xattr_handler *handler,
 static int hfsplus_trusted_getxattr(const struct xattr_handler *handler,
-				    struct dentry *dentry, const char *name,
-				    void *buffer, size_t size)
+				    struct dentry *unused, struct inode *inode,
+				    const char *name, void *buffer, size_t size)
 {
 {
-	return hfsplus_getxattr(dentry, name, buffer, size,
+	return hfsplus_getxattr(inode, name, buffer, size,
 				XATTR_TRUSTED_PREFIX,
 				XATTR_TRUSTED_PREFIX,
 				XATTR_TRUSTED_PREFIX_LEN);
 				XATTR_TRUSTED_PREFIX_LEN);
 }
 }

+ 3 - 3
fs/hfsplus/xattr_user.c

@@ -12,11 +12,11 @@
 #include "xattr.h"
 #include "xattr.h"
 
 
 static int hfsplus_user_getxattr(const struct xattr_handler *handler,
 static int hfsplus_user_getxattr(const struct xattr_handler *handler,
-				 struct dentry *dentry, const char *name,
-				 void *buffer, size_t size)
+				 struct dentry *unused, struct inode *inode,
+				 const char *name, void *buffer, size_t size)
 {
 {
 
 
-	return hfsplus_getxattr(dentry, name, buffer, size,
+	return hfsplus_getxattr(inode, name, buffer, size,
 				XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
 				XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
 }
 }
 
 

+ 2 - 2
fs/inode.c

@@ -238,9 +238,9 @@ void __destroy_inode(struct inode *inode)
 	}
 	}
 
 
 #ifdef CONFIG_FS_POSIX_ACL
 #ifdef CONFIG_FS_POSIX_ACL
-	if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED)
+	if (inode->i_acl && !is_uncached_acl(inode->i_acl))
 		posix_acl_release(inode->i_acl);
 		posix_acl_release(inode->i_acl);
-	if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED)
+	if (inode->i_default_acl && !is_uncached_acl(inode->i_default_acl))
 		posix_acl_release(inode->i_default_acl);
 		posix_acl_release(inode->i_default_acl);
 #endif
 #endif
 	this_cpu_dec(nr_inodes);
 	this_cpu_dec(nr_inodes);

+ 0 - 2
fs/jffs2/acl.c

@@ -203,8 +203,6 @@ struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
 		acl = ERR_PTR(rc);
 		acl = ERR_PTR(rc);
 	}
 	}
 	kfree(value);
 	kfree(value);
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
 	return acl;
 	return acl;
 }
 }
 
 

+ 1 - 1
fs/jffs2/dir.c

@@ -241,7 +241,7 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
 
 
 static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
 static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
 {
 {
-	struct jffs2_sb_info *c = JFFS2_SB_INFO(d_inode(old_dentry)->i_sb);
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_sb);
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(old_dentry));
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(old_dentry));
 	struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
 	struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
 	int ret;
 	int ret;

+ 3 - 3
fs/jffs2/security.c

@@ -49,10 +49,10 @@ int jffs2_init_security(struct inode *inode, struct inode *dir,
 
 
 /* ---- XATTR Handler for "security.*" ----------------- */
 /* ---- XATTR Handler for "security.*" ----------------- */
 static int jffs2_security_getxattr(const struct xattr_handler *handler,
 static int jffs2_security_getxattr(const struct xattr_handler *handler,
-				   struct dentry *dentry, const char *name,
-				   void *buffer, size_t size)
+				   struct dentry *unused, struct inode *inode,
+				   const char *name, void *buffer, size_t size)
 {
 {
-	return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY,
+	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY,
 				 name, buffer, size);
 				 name, buffer, size);
 }
 }
 
 

+ 1 - 1
fs/jffs2/super.c

@@ -147,7 +147,7 @@ static struct dentry *jffs2_get_parent(struct dentry *child)
 	JFFS2_DEBUG("Parent of directory ino #%u is #%u\n",
 	JFFS2_DEBUG("Parent of directory ino #%u is #%u\n",
 		    f->inocache->ino, pino);
 		    f->inocache->ino, pino);
 
 
-	return d_obtain_alias(jffs2_iget(d_inode(child)->i_sb, pino));
+	return d_obtain_alias(jffs2_iget(child->d_sb, pino));
 }
 }
 
 
 static const struct export_operations jffs2_export_ops = {
 static const struct export_operations jffs2_export_ops = {

+ 3 - 3
fs/jffs2/xattr_trusted.c

@@ -17,10 +17,10 @@
 #include "nodelist.h"
 #include "nodelist.h"
 
 
 static int jffs2_trusted_getxattr(const struct xattr_handler *handler,
 static int jffs2_trusted_getxattr(const struct xattr_handler *handler,
-				  struct dentry *dentry, const char *name,
-				  void *buffer, size_t size)
+				  struct dentry *unused, struct inode *inode,
+				  const char *name, void *buffer, size_t size)
 {
 {
-	return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED,
+	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED,
 				 name, buffer, size);
 				 name, buffer, size);
 }
 }
 
 

+ 3 - 3
fs/jffs2/xattr_user.c

@@ -17,10 +17,10 @@
 #include "nodelist.h"
 #include "nodelist.h"
 
 
 static int jffs2_user_getxattr(const struct xattr_handler *handler,
 static int jffs2_user_getxattr(const struct xattr_handler *handler,
-			       struct dentry *dentry, const char *name,
-			       void *buffer, size_t size)
+			       struct dentry *unused, struct inode *inode,
+			       const char *name, void *buffer, size_t size)
 {
 {
-	return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_USER,
+	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER,
 				 name, buffer, size);
 				 name, buffer, size);
 }
 }
 
 

+ 0 - 6
fs/jfs/acl.c

@@ -34,10 +34,6 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type)
 	int size;
 	int size;
 	char *value = NULL;
 	char *value = NULL;
 
 
-	acl = get_cached_acl(inode, type);
-	if (acl != ACL_NOT_CACHED)
-		return acl;
-
 	switch(type) {
 	switch(type) {
 		case ACL_TYPE_ACCESS:
 		case ACL_TYPE_ACCESS:
 			ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
 			ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
@@ -67,8 +63,6 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type)
 		acl = posix_acl_from_xattr(&init_user_ns, value, size);
 		acl = posix_acl_from_xattr(&init_user_ns, value, size);
 	}
 	}
 	kfree(value);
 	kfree(value);
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
 	return acl;
 	return acl;
 }
 }
 
 

+ 1 - 1
fs/jfs/jfs_xattr.h

@@ -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,
 extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
 			int);
 			int);
 extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
 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 ssize_t jfs_listxattr(struct dentry *, char *, size_t);
 extern int jfs_removexattr(struct dentry *, const char *);
 extern int jfs_removexattr(struct dentry *, const char *);
 
 

+ 1 - 1
fs/jfs/namei.c

@@ -1524,7 +1524,7 @@ struct dentry *jfs_get_parent(struct dentry *dentry)
 	parent_ino =
 	parent_ino =
 		le32_to_cpu(JFS_IP(d_inode(dentry))->i_dtroot.header.idotdot);
 		le32_to_cpu(JFS_IP(d_inode(dentry))->i_dtroot.header.idotdot);
 
 
-	return d_obtain_alias(jfs_iget(d_inode(dentry)->i_sb, parent_ino));
+	return d_obtain_alias(jfs_iget(dentry->d_sb, parent_ino));
 }
 }
 
 
 const struct inode_operations jfs_dir_inode_operations = {
 const struct inode_operations jfs_dir_inode_operations = {

+ 4 - 4
fs/jfs/xattr.c

@@ -933,8 +933,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
 	return size;
 	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;
 	int err;
 
 
@@ -944,7 +944,7 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
 	 * for it via sb->s_xattr.
 	 * for it via sb->s_xattr.
 	 */
 	 */
 	if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
 	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) {
 	if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
 		/*
 		/*
@@ -959,7 +959,7 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
 			return -EOPNOTSUPP;
 			return -EOPNOTSUPP;
 	}
 	}
 
 
-	err = __jfs_getxattr(d_inode(dentry), name, data, buf_size);
+	err = __jfs_getxattr(inode, name, data, buf_size);
 
 
 	return err;
 	return err;
 }
 }

+ 3 - 3
fs/kernfs/inode.c

@@ -208,10 +208,10 @@ int kernfs_iop_removexattr(struct dentry *dentry, const char *name)
 	return simple_xattr_set(&attrs->xattrs, name, NULL, 0, XATTR_REPLACE);
 	return simple_xattr_set(&attrs->xattrs, name, NULL, 0, XATTR_REPLACE);
 }
 }
 
 
-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;
 	struct kernfs_iattrs *attrs;
 
 
 	attrs = kernfs_iattrs(kn);
 	attrs = kernfs_iattrs(kn);

+ 2 - 2
fs/kernfs/kernfs-internal.h

@@ -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,
 int kernfs_iop_setxattr(struct dentry *dentry, const char *name, const void *value,
 			size_t size, int flags);
 			size_t size, int flags);
 int kernfs_iop_removexattr(struct dentry *dentry, const char *name);
 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);
 ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size);
 
 
 /*
 /*

+ 2 - 2
fs/libfs.c

@@ -1127,8 +1127,8 @@ static int empty_dir_setxattr(struct dentry *dentry, const char *name,
 	return -EOPNOTSUPP;
 	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;
 	return -EOPNOTSUPP;
 }
 }

+ 3 - 3
fs/namei.c

@@ -265,7 +265,7 @@ static int check_acl(struct inode *inode, int mask)
 	        if (!acl)
 	        if (!acl)
 	                return -EAGAIN;
 	                return -EAGAIN;
 		/* no ->get_acl() calls in RCU mode... */
 		/* no ->get_acl() calls in RCU mode... */
-		if (acl == ACL_NOT_CACHED)
+		if (is_uncached_acl(acl))
 			return -ECHILD;
 			return -ECHILD;
 	        return posix_acl_permission(inode, acl, mask & ~MAY_NOT_BLOCK);
 	        return posix_acl_permission(inode, acl, mask & ~MAY_NOT_BLOCK);
 	}
 	}
@@ -2655,7 +2655,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
 		return NULL;
 		return NULL;
 	}
 	}
 
 
-	mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
+	mutex_lock(&p1->d_sb->s_vfs_rename_mutex);
 
 
 	p = d_ancestor(p2, p1);
 	p = d_ancestor(p2, p1);
 	if (p) {
 	if (p) {
@@ -2682,7 +2682,7 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
 	inode_unlock(p1->d_inode);
 	inode_unlock(p1->d_inode);
 	if (p1 != p2) {
 	if (p1 != p2) {
 		inode_unlock(p2->d_inode);
 		inode_unlock(p2->d_inode);
-		mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
+		mutex_unlock(&p1->d_sb->s_vfs_rename_mutex);
 	}
 	}
 }
 }
 EXPORT_SYMBOL(unlock_rename);
 EXPORT_SYMBOL(unlock_rename);

+ 1 - 1
fs/nfs/direct.c

@@ -396,7 +396,7 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq, bool write)
 static void nfs_direct_readpage_release(struct nfs_page *req)
 static void nfs_direct_readpage_release(struct nfs_page *req)
 {
 {
 	dprintk("NFS: direct read done (%s/%llu %d@%lld)\n",
 	dprintk("NFS: direct read done (%s/%llu %d@%lld)\n",
-		d_inode(req->wb_context->dentry)->i_sb->s_id,
+		req->wb_context->dentry->d_sb->s_id,
 		(unsigned long long)NFS_FILEID(d_inode(req->wb_context->dentry)),
 		(unsigned long long)NFS_FILEID(d_inode(req->wb_context->dentry)),
 		req->wb_bytes,
 		req->wb_bytes,
 		(long long)req_offset(req));
 		(long long)req_offset(req));

+ 41 - 2
fs/nfs/nfs3acl.c

@@ -11,6 +11,38 @@
 
 
 #define NFSDBG_FACILITY	NFSDBG_PROC
 #define NFSDBG_FACILITY	NFSDBG_PROC
 
 
+/*
+ * nfs3_prepare_get_acl, nfs3_complete_get_acl, nfs3_abort_get_acl: Helpers for
+ * caching get_acl results in a race-free way.  See fs/posix_acl.c:get_acl()
+ * for explanations.
+ */
+static void nfs3_prepare_get_acl(struct posix_acl **p)
+{
+	struct posix_acl *sentinel = uncached_acl_sentinel(current);
+
+	if (cmpxchg(p, ACL_NOT_CACHED, sentinel) != ACL_NOT_CACHED) {
+		/* Not the first reader or sentinel already in place. */
+	}
+}
+
+static void nfs3_complete_get_acl(struct posix_acl **p, struct posix_acl *acl)
+{
+	struct posix_acl *sentinel = uncached_acl_sentinel(current);
+
+	/* Only cache the ACL if our sentinel is still in place. */
+	posix_acl_dup(acl);
+	if (cmpxchg(p, sentinel, acl) != sentinel)
+		posix_acl_release(acl);
+}
+
+static void nfs3_abort_get_acl(struct posix_acl **p)
+{
+	struct posix_acl *sentinel = uncached_acl_sentinel(current);
+
+	/* Remove our sentinel upon failure. */
+	cmpxchg(p, sentinel, ACL_NOT_CACHED);
+}
+
 struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
 struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
 {
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_server *server = NFS_SERVER(inode);
@@ -55,6 +87,11 @@ struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
 	if (res.fattr == NULL)
 	if (res.fattr == NULL)
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
 
 
+	if (args.mask & NFS_ACL)
+		nfs3_prepare_get_acl(&inode->i_acl);
+	if (args.mask & NFS_DFACL)
+		nfs3_prepare_get_acl(&inode->i_default_acl);
+
 	status = rpc_call_sync(server->client_acl, &msg, 0);
 	status = rpc_call_sync(server->client_acl, &msg, 0);
 	dprintk("NFS reply getacl: %d\n", status);
 	dprintk("NFS reply getacl: %d\n", status);
 
 
@@ -89,12 +126,12 @@ struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
 	}
 	}
 
 
 	if (res.mask & NFS_ACL)
 	if (res.mask & NFS_ACL)
-		set_cached_acl(inode, ACL_TYPE_ACCESS, res.acl_access);
+		nfs3_complete_get_acl(&inode->i_acl, res.acl_access);
 	else
 	else
 		forget_cached_acl(inode, ACL_TYPE_ACCESS);
 		forget_cached_acl(inode, ACL_TYPE_ACCESS);
 
 
 	if (res.mask & NFS_DFACL)
 	if (res.mask & NFS_DFACL)
-		set_cached_acl(inode, ACL_TYPE_DEFAULT, res.acl_default);
+		nfs3_complete_get_acl(&inode->i_default_acl, res.acl_default);
 	else
 	else
 		forget_cached_acl(inode, ACL_TYPE_DEFAULT);
 		forget_cached_acl(inode, ACL_TYPE_DEFAULT);
 
 
@@ -108,6 +145,8 @@ struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
 	}
 	}
 
 
 getout:
 getout:
+	nfs3_abort_get_acl(&inode->i_acl);
+	nfs3_abort_get_acl(&inode->i_default_acl);
 	posix_acl_release(res.acl_access);
 	posix_acl_release(res.acl_access);
 	posix_acl_release(res.acl_default);
 	posix_acl_release(res.acl_default);
 	nfs_free_fattr(res.fattr);
 	nfs_free_fattr(res.fattr);

+ 6 - 6
fs/nfs/nfs4proc.c

@@ -6263,10 +6263,10 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
 }
 }
 
 
 static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
 static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
-				   struct dentry *dentry, const char *key,
-				   void *buf, size_t buflen)
+				   struct dentry *unused, struct inode *inode,
+				   const char *key, void *buf, size_t buflen)
 {
 {
-	return nfs4_proc_get_acl(d_inode(dentry), buf, buflen);
+	return nfs4_proc_get_acl(inode, buf, buflen);
 }
 }
 
 
 static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
 static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
@@ -6288,11 +6288,11 @@ static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
 }
 }
 
 
 static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler,
 static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler,
-				     struct dentry *dentry, const char *key,
-				     void *buf, size_t buflen)
+				     struct dentry *unused, struct inode *inode,
+				     const char *key, void *buf, size_t buflen)
 {
 {
 	if (security_ismaclabel(key))
 	if (security_ismaclabel(key))
-		return nfs4_get_security_label(d_inode(dentry), buf, buflen);
+		return nfs4_get_security_label(inode, buf, buflen);
 	return -EOPNOTSUPP;
 	return -EOPNOTSUPP;
 }
 }
 
 

+ 2 - 2
fs/nfsd/nfs3proc.c

@@ -552,7 +552,7 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
 	 * different read/write sizes for file systems known to have
 	 * different read/write sizes for file systems known to have
 	 * problems with large blocks */
 	 * problems with large blocks */
 	if (nfserr == 0) {
 	if (nfserr == 0) {
-		struct super_block *sb = d_inode(argp->fh.fh_dentry)->i_sb;
+		struct super_block *sb = argp->fh.fh_dentry->d_sb;
 
 
 		/* Note that we don't care for remote fs's here */
 		/* Note that we don't care for remote fs's here */
 		if (sb->s_magic == MSDOS_SUPER_MAGIC) {
 		if (sb->s_magic == MSDOS_SUPER_MAGIC) {
@@ -588,7 +588,7 @@ nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle      *argp,
 	nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
 	nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
 
 
 	if (nfserr == 0) {
 	if (nfserr == 0) {
-		struct super_block *sb = d_inode(argp->fh.fh_dentry)->i_sb;
+		struct super_block *sb = argp->fh.fh_dentry->d_sb;
 
 
 		/* Note that we don't care for remote fs's here */
 		/* Note that we don't care for remote fs's here */
 		switch (sb->s_magic) {
 		switch (sb->s_magic) {

+ 1 - 1
fs/nfsd/nfs3xdr.c

@@ -146,7 +146,7 @@ static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
 	default:
 	default:
 	case FSIDSOURCE_DEV:
 	case FSIDSOURCE_DEV:
 		p = xdr_encode_hyper(p, (u64)huge_encode_dev
 		p = xdr_encode_hyper(p, (u64)huge_encode_dev
-				     (d_inode(fhp->fh_dentry)->i_sb->s_dev));
+				     (fhp->fh_dentry->d_sb->s_dev));
 		break;
 		break;
 	case FSIDSOURCE_FSID:
 	case FSIDSOURCE_FSID:
 		p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
 		p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);

+ 1 - 1
fs/nfsd/nfsfh.c

@@ -426,7 +426,7 @@ static bool is_root_export(struct svc_export *exp)
 
 
 static struct super_block *exp_sb(struct svc_export *exp)
 static struct super_block *exp_sb(struct svc_export *exp)
 {
 {
-	return d_inode(exp->ex_path.dentry)->i_sb;
+	return exp->ex_path.dentry->d_sb;
 }
 }
 
 
 static bool fsid_type_ok_for_exp(u8 fsid_type, struct svc_export *exp)
 static bool fsid_type_ok_for_exp(u8 fsid_type, struct svc_export *exp)

+ 1 - 1
fs/nilfs2/namei.c

@@ -457,7 +457,7 @@ static struct dentry *nilfs_get_parent(struct dentry *child)
 
 
 	root = NILFS_I(d_inode(child))->i_root;
 	root = NILFS_I(d_inode(child))->i_root;
 
 
-	inode = nilfs_iget(d_inode(child)->i_sb, root, ino);
+	inode = nilfs_iget(child->d_sb, root, ino);
 	if (IS_ERR(inode))
 	if (IS_ERR(inode))
 		return ERR_CAST(inode);
 		return ERR_CAST(inode);
 
 

+ 3 - 0
fs/ocfs2/dlmglue.c

@@ -54,6 +54,7 @@
 #include "uptodate.h"
 #include "uptodate.h"
 #include "quota.h"
 #include "quota.h"
 #include "refcounttree.h"
 #include "refcounttree.h"
+#include "acl.h"
 
 
 #include "buffer_head_io.h"
 #include "buffer_head_io.h"
 
 
@@ -3623,6 +3624,8 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
 		filemap_fdatawait(mapping);
 		filemap_fdatawait(mapping);
 	}
 	}
 
 
+	forget_all_cached_acls(inode);
+
 out:
 out:
 	return UNBLOCK_CONTINUE;
 	return UNBLOCK_CONTINUE;
 }
 }

+ 1 - 1
fs/ocfs2/file.c

@@ -1290,7 +1290,7 @@ int ocfs2_getattr(struct vfsmount *mnt,
 		  struct kstat *stat)
 		  struct kstat *stat)
 {
 {
 	struct inode *inode = d_inode(dentry);
 	struct inode *inode = d_inode(dentry);
-	struct super_block *sb = d_inode(dentry)->i_sb;
+	struct super_block *sb = dentry->d_sb;
 	struct ocfs2_super *osb = sb->s_fs_info;
 	struct ocfs2_super *osb = sb->s_fs_info;
 	int err;
 	int err;
 
 

+ 10 - 10
fs/ocfs2/xattr.c

@@ -7250,10 +7250,10 @@ leave:
  * 'security' attributes support
  * 'security' attributes support
  */
  */
 static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
 static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
-				    struct dentry *dentry, const char *name,
-				    void *buffer, size_t size)
+				    struct dentry *unused, struct inode *inode,
+				    const char *name, void *buffer, size_t size)
 {
 {
-	return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY,
+	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_SECURITY,
 			       name, buffer, size);
 			       name, buffer, size);
 }
 }
 
 
@@ -7321,10 +7321,10 @@ const struct xattr_handler ocfs2_xattr_security_handler = {
  * 'trusted' attributes support
  * 'trusted' attributes support
  */
  */
 static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
 static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
-				   struct dentry *dentry, const char *name,
-				   void *buffer, size_t size)
+				   struct dentry *unused, struct inode *inode,
+				   const char *name, void *buffer, size_t size)
 {
 {
-	return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED,
+	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_TRUSTED,
 			       name, buffer, size);
 			       name, buffer, size);
 }
 }
 
 
@@ -7346,14 +7346,14 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = {
  * 'user' attributes support
  * 'user' attributes support
  */
  */
 static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
 static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
-				struct dentry *dentry, const char *name,
-				void *buffer, size_t size)
+				struct dentry *unusde, struct inode *inode,
+				const char *name, void *buffer, size_t size)
 {
 {
-	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)
 	if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
-	return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_USER, name,
+	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_USER, name,
 			       buffer, size);
 			       buffer, size);
 }
 }
 
 

+ 6 - 4
fs/orangefs/xattr.c

@@ -463,12 +463,13 @@ static int orangefs_xattr_set_default(const struct xattr_handler *handler,
 }
 }
 
 
 static int orangefs_xattr_get_default(const struct xattr_handler *handler,
 static int orangefs_xattr_get_default(const struct xattr_handler *handler,
-				      struct dentry *dentry,
+				      struct dentry *unused,
+				      struct inode *inode,
 				      const char *name,
 				      const char *name,
 				      void *buffer,
 				      void *buffer,
 				      size_t size)
 				      size_t size)
 {
 {
-	return orangefs_inode_getxattr(dentry->d_inode,
+	return orangefs_inode_getxattr(inode,
 				    ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
 				    ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
 				    name,
 				    name,
 				    buffer,
 				    buffer,
@@ -492,12 +493,13 @@ static int orangefs_xattr_set_trusted(const struct xattr_handler *handler,
 }
 }
 
 
 static int orangefs_xattr_get_trusted(const struct xattr_handler *handler,
 static int orangefs_xattr_get_trusted(const struct xattr_handler *handler,
-				      struct dentry *dentry,
+				      struct dentry *unused,
+				      struct inode *inode,
 				      const char *name,
 				      const char *name,
 				      void *buffer,
 				      void *buffer,
 				      size_t size)
 				      size_t size)
 {
 {
-	return orangefs_inode_getxattr(dentry->d_inode,
+	return orangefs_inode_getxattr(inode,
 				    ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
 				    ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
 				    name,
 				    name,
 				    buffer,
 				    buffer,

+ 2 - 2
fs/overlayfs/inode.c

@@ -246,8 +246,8 @@ static bool ovl_need_xattr_filter(struct dentry *dentry,
 		return false;
 		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;
 	struct path realpath;
 	enum ovl_path_type type = ovl_path_real(dentry, &realpath);
 	enum ovl_path_type type = ovl_path_real(dentry, &realpath);

+ 2 - 2
fs/overlayfs/overlayfs.h

@@ -173,8 +173,8 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr);
 int ovl_permission(struct inode *inode, int mask);
 int ovl_permission(struct inode *inode, int mask);
 int ovl_setxattr(struct dentry *dentry, const char *name,
 int ovl_setxattr(struct dentry *dentry, const char *name,
 		 const void *value, size_t size, int flags);
 		 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);
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
 int ovl_removexattr(struct dentry *dentry, const char *name);
 int ovl_removexattr(struct dentry *dentry, const char *name);
 struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
 struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);

+ 1 - 1
fs/overlayfs/super.c

@@ -274,7 +274,7 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
 	if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr)
 	if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr)
 		return false;
 		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')
 	if (res == 1 && val == 'y')
 		return true;
 		return true;
 
 

+ 75 - 41
fs/posix_acl.c

@@ -21,7 +21,7 @@
 #include <linux/export.h>
 #include <linux/export.h>
 #include <linux/user_namespace.h>
 #include <linux/user_namespace.h>
 
 
-struct posix_acl **acl_by_type(struct inode *inode, int type)
+static struct posix_acl **acl_by_type(struct inode *inode, int type)
 {
 {
 	switch (type) {
 	switch (type) {
 	case ACL_TYPE_ACCESS:
 	case ACL_TYPE_ACCESS:
@@ -32,19 +32,22 @@ struct posix_acl **acl_by_type(struct inode *inode, int type)
 		BUG();
 		BUG();
 	}
 	}
 }
 }
-EXPORT_SYMBOL(acl_by_type);
 
 
 struct posix_acl *get_cached_acl(struct inode *inode, int type)
 struct posix_acl *get_cached_acl(struct inode *inode, int type)
 {
 {
 	struct posix_acl **p = acl_by_type(inode, type);
 	struct posix_acl **p = acl_by_type(inode, type);
-	struct posix_acl *acl = ACCESS_ONCE(*p);
-	if (acl) {
-		spin_lock(&inode->i_lock);
-		acl = *p;
-		if (acl != ACL_NOT_CACHED)
-			acl = posix_acl_dup(acl);
-		spin_unlock(&inode->i_lock);
+	struct posix_acl *acl;
+
+	for (;;) {
+		rcu_read_lock();
+		acl = rcu_dereference(*p);
+		if (!acl || is_uncached_acl(acl) ||
+		    atomic_inc_not_zero(&acl->a_refcount))
+			break;
+		rcu_read_unlock();
+		cpu_relax();
 	}
 	}
+	rcu_read_unlock();
 	return acl;
 	return acl;
 }
 }
 EXPORT_SYMBOL(get_cached_acl);
 EXPORT_SYMBOL(get_cached_acl);
@@ -59,58 +62,72 @@ void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl)
 {
 {
 	struct posix_acl **p = acl_by_type(inode, type);
 	struct posix_acl **p = acl_by_type(inode, type);
 	struct posix_acl *old;
 	struct posix_acl *old;
-	spin_lock(&inode->i_lock);
-	old = *p;
-	rcu_assign_pointer(*p, posix_acl_dup(acl));
-	spin_unlock(&inode->i_lock);
-	if (old != ACL_NOT_CACHED)
+
+	old = xchg(p, posix_acl_dup(acl));
+	if (!is_uncached_acl(old))
 		posix_acl_release(old);
 		posix_acl_release(old);
 }
 }
 EXPORT_SYMBOL(set_cached_acl);
 EXPORT_SYMBOL(set_cached_acl);
 
 
-void forget_cached_acl(struct inode *inode, int type)
+static void __forget_cached_acl(struct posix_acl **p)
 {
 {
-	struct posix_acl **p = acl_by_type(inode, type);
 	struct posix_acl *old;
 	struct posix_acl *old;
-	spin_lock(&inode->i_lock);
-	old = *p;
-	*p = ACL_NOT_CACHED;
-	spin_unlock(&inode->i_lock);
-	if (old != ACL_NOT_CACHED)
+
+	old = xchg(p, ACL_NOT_CACHED);
+	if (!is_uncached_acl(old))
 		posix_acl_release(old);
 		posix_acl_release(old);
 }
 }
+
+void forget_cached_acl(struct inode *inode, int type)
+{
+	__forget_cached_acl(acl_by_type(inode, type));
+}
 EXPORT_SYMBOL(forget_cached_acl);
 EXPORT_SYMBOL(forget_cached_acl);
 
 
 void forget_all_cached_acls(struct inode *inode)
 void forget_all_cached_acls(struct inode *inode)
 {
 {
-	struct posix_acl *old_access, *old_default;
-	spin_lock(&inode->i_lock);
-	old_access = inode->i_acl;
-	old_default = inode->i_default_acl;
-	inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
-	spin_unlock(&inode->i_lock);
-	if (old_access != ACL_NOT_CACHED)
-		posix_acl_release(old_access);
-	if (old_default != ACL_NOT_CACHED)
-		posix_acl_release(old_default);
+	__forget_cached_acl(&inode->i_acl);
+	__forget_cached_acl(&inode->i_default_acl);
 }
 }
 EXPORT_SYMBOL(forget_all_cached_acls);
 EXPORT_SYMBOL(forget_all_cached_acls);
 
 
 struct posix_acl *get_acl(struct inode *inode, int type)
 struct posix_acl *get_acl(struct inode *inode, int type)
 {
 {
+	void *sentinel;
+	struct posix_acl **p;
 	struct posix_acl *acl;
 	struct posix_acl *acl;
 
 
+	/*
+	 * The sentinel is used to detect when another operation like
+	 * set_cached_acl() or forget_cached_acl() races with get_acl().
+	 * It is guaranteed that is_uncached_acl(sentinel) is true.
+	 */
+
 	acl = get_cached_acl(inode, type);
 	acl = get_cached_acl(inode, type);
-	if (acl != ACL_NOT_CACHED)
+	if (!is_uncached_acl(acl))
 		return acl;
 		return acl;
 
 
 	if (!IS_POSIXACL(inode))
 	if (!IS_POSIXACL(inode))
 		return NULL;
 		return NULL;
 
 
+	sentinel = uncached_acl_sentinel(current);
+	p = acl_by_type(inode, type);
+
 	/*
 	/*
-	 * A filesystem can force a ACL callback by just never filling the
-	 * ACL cache. But normally you'd fill the cache either at inode
-	 * instantiation time, or on the first ->get_acl call.
+	 * If the ACL isn't being read yet, set our sentinel.  Otherwise, the
+	 * current value of the ACL will not be ACL_NOT_CACHED and so our own
+	 * sentinel will not be set; another task will update the cache.  We
+	 * could wait for that other task to complete its job, but it's easier
+	 * to just call ->get_acl to fetch the ACL ourself.  (This is going to
+	 * be an unlikely race.)
+	 */
+	if (cmpxchg(p, ACL_NOT_CACHED, sentinel) != ACL_NOT_CACHED)
+		/* fall through */ ;
+
+	/*
+	 * Normally, the ACL returned by ->get_acl will be cached.
+	 * A filesystem can prevent that by calling
+	 * forget_cached_acl(inode, type) in ->get_acl.
 	 *
 	 *
 	 * If the filesystem doesn't have a get_acl() function at all, we'll
 	 * If the filesystem doesn't have a get_acl() function at all, we'll
 	 * just create the negative cache entry.
 	 * just create the negative cache entry.
@@ -119,7 +136,24 @@ struct posix_acl *get_acl(struct inode *inode, int type)
 		set_cached_acl(inode, type, NULL);
 		set_cached_acl(inode, type, NULL);
 		return NULL;
 		return NULL;
 	}
 	}
-	return inode->i_op->get_acl(inode, type);
+	acl = inode->i_op->get_acl(inode, type);
+
+	if (IS_ERR(acl)) {
+		/*
+		 * Remove our sentinel so that we don't block future attempts
+		 * to cache the ACL.
+		 */
+		cmpxchg(p, sentinel, ACL_NOT_CACHED);
+		return acl;
+	}
+
+	/*
+	 * Cache the result, but only if our sentinel is still in place.
+	 */
+	posix_acl_dup(acl);
+	if (unlikely(cmpxchg(p, sentinel, acl) != sentinel))
+		posix_acl_release(acl);
+	return acl;
 }
 }
 EXPORT_SYMBOL(get_acl);
 EXPORT_SYMBOL(get_acl);
 
 
@@ -763,18 +797,18 @@ EXPORT_SYMBOL (posix_acl_to_xattr);
 
 
 static int
 static int
 posix_acl_xattr_get(const struct xattr_handler *handler,
 posix_acl_xattr_get(const struct xattr_handler *handler,
-		    struct dentry *dentry, const char *name,
-		    void *value, size_t size)
+		    struct dentry *unused, struct inode *inode,
+		    const char *name, void *value, size_t size)
 {
 {
 	struct posix_acl *acl;
 	struct posix_acl *acl;
 	int error;
 	int error;
 
 
-	if (!IS_POSIXACL(d_backing_inode(dentry)))
+	if (!IS_POSIXACL(inode))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
-	if (d_is_symlink(dentry))
+	if (S_ISLNK(inode->i_mode))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 
 
-	acl = get_acl(d_backing_inode(dentry), handler->flags);
+	acl = get_acl(inode, handler->flags);
 	if (IS_ERR(acl))
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
 		return PTR_ERR(acl);
 	if (acl == NULL)
 	if (acl == NULL)

+ 3 - 3
fs/reiserfs/file.c

@@ -260,10 +260,10 @@ const struct file_operations reiserfs_file_operations = {
 
 
 const struct inode_operations reiserfs_file_inode_operations = {
 const struct inode_operations reiserfs_file_inode_operations = {
 	.setattr = reiserfs_setattr,
 	.setattr = reiserfs_setattr,
-	.setxattr = reiserfs_setxattr,
-	.getxattr = reiserfs_getxattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = reiserfs_removexattr,
+	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 	.permission = reiserfs_permission,
 	.get_acl = reiserfs_get_acl,
 	.get_acl = reiserfs_get_acl,
 	.set_acl = reiserfs_set_acl,
 	.set_acl = reiserfs_set_acl,

+ 9 - 9
fs/reiserfs/namei.c

@@ -1650,10 +1650,10 @@ const struct inode_operations reiserfs_dir_inode_operations = {
 	.mknod = reiserfs_mknod,
 	.mknod = reiserfs_mknod,
 	.rename = reiserfs_rename,
 	.rename = reiserfs_rename,
 	.setattr = reiserfs_setattr,
 	.setattr = reiserfs_setattr,
-	.setxattr = reiserfs_setxattr,
-	.getxattr = reiserfs_getxattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = reiserfs_removexattr,
+	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 	.permission = reiserfs_permission,
 	.get_acl = reiserfs_get_acl,
 	.get_acl = reiserfs_get_acl,
 	.set_acl = reiserfs_set_acl,
 	.set_acl = reiserfs_set_acl,
@@ -1667,10 +1667,10 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
 	.readlink = generic_readlink,
 	.readlink = generic_readlink,
 	.get_link	= page_get_link,
 	.get_link	= page_get_link,
 	.setattr = reiserfs_setattr,
 	.setattr = reiserfs_setattr,
-	.setxattr = reiserfs_setxattr,
-	.getxattr = reiserfs_getxattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = reiserfs_removexattr,
+	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 	.permission = reiserfs_permission,
 };
 };
 
 
@@ -1679,10 +1679,10 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
  */
  */
 const struct inode_operations reiserfs_special_inode_operations = {
 const struct inode_operations reiserfs_special_inode_operations = {
 	.setattr = reiserfs_setattr,
 	.setattr = reiserfs_setattr,
-	.setxattr = reiserfs_setxattr,
-	.getxattr = reiserfs_getxattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = reiserfs_removexattr,
+	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 	.permission = reiserfs_permission,
 	.get_acl = reiserfs_get_acl,
 	.get_acl = reiserfs_get_acl,
 	.set_acl = reiserfs_set_acl,
 	.set_acl = reiserfs_set_acl,

+ 0 - 54
fs/reiserfs/xattr.c

@@ -764,60 +764,6 @@ find_xattr_handler_prefix(const struct xattr_handler **handlers,
 	return xah;
 	return xah;
 }
 }
 
 
-
-/*
- * Inode operation getxattr()
- */
-ssize_t
-reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
-		  size_t size)
-{
-	const struct xattr_handler *handler;
-
-	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name);
-
-	if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
-		return -EOPNOTSUPP;
-
-	return handler->get(handler, dentry, name, buffer, size);
-}
-
-/*
- * Inode operation setxattr()
- *
- * d_inode(dentry)->i_mutex down
- */
-int
-reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
-		  size_t size, int flags)
-{
-	const struct xattr_handler *handler;
-
-	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name);
-
-	if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
-		return -EOPNOTSUPP;
-
-	return handler->set(handler, dentry, name, value, size, flags);
-}
-
-/*
- * Inode operation removexattr()
- *
- * d_inode(dentry)->i_mutex down
- */
-int reiserfs_removexattr(struct dentry *dentry, const char *name)
-{
-	const struct xattr_handler *handler;
-
-	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name);
-
-	if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
-		return -EOPNOTSUPP;
-
-	return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
-}
-
 struct listxattr_buf {
 struct listxattr_buf {
 	struct dir_context ctx;
 	struct dir_context ctx;
 	size_t size;
 	size_t size;

+ 1 - 8
fs/reiserfs/xattr.h

@@ -2,6 +2,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/rwsem.h>
 #include <linux/rwsem.h>
+#include <linux/xattr.h>
 
 
 struct inode;
 struct inode;
 struct dentry;
 struct dentry;
@@ -18,12 +19,7 @@ int reiserfs_permission(struct inode *inode, int mask);
 
 
 #ifdef CONFIG_REISERFS_FS_XATTR
 #ifdef CONFIG_REISERFS_FS_XATTR
 #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)
 #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)
-ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name,
-			  void *buffer, size_t size);
-int reiserfs_setxattr(struct dentry *dentry, const char *name,
-		      const void *value, size_t size, int flags);
 ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
-int reiserfs_removexattr(struct dentry *dentry, const char *name);
 
 
 int reiserfs_xattr_get(struct inode *, const char *, void *, size_t);
 int reiserfs_xattr_get(struct inode *, const char *, void *, size_t);
 int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int);
 int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int);
@@ -92,10 +88,7 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
 
 
 #else
 #else
 
 
-#define reiserfs_getxattr NULL
-#define reiserfs_setxattr NULL
 #define reiserfs_listxattr NULL
 #define reiserfs_listxattr NULL
-#define reiserfs_removexattr NULL
 
 
 static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
 static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
 {
 {

+ 2 - 6
fs/reiserfs/xattr_acl.c

@@ -197,10 +197,8 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
 
 
 	size = reiserfs_xattr_get(inode, name, NULL, 0);
 	size = reiserfs_xattr_get(inode, name, NULL, 0);
 	if (size < 0) {
 	if (size < 0) {
-		if (size == -ENODATA || size == -ENOSYS) {
-			set_cached_acl(inode, type, NULL);
+		if (size == -ENODATA || size == -ENOSYS)
 			return NULL;
 			return NULL;
-		}
 		return ERR_PTR(size);
 		return ERR_PTR(size);
 	}
 	}
 
 
@@ -220,8 +218,6 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
 	} else {
 	} else {
 		acl = reiserfs_posix_acl_from_disk(value, retval);
 		acl = reiserfs_posix_acl_from_disk(value, retval);
 	}
 	}
-	if (!IS_ERR(acl))
-		set_cached_acl(inode, type, acl);
 
 
 	kfree(value);
 	kfree(value);
 	return acl;
 	return acl;
@@ -370,7 +366,7 @@ int reiserfs_cache_default_acl(struct inode *inode)
 	if (IS_PRIVATE(inode))
 	if (IS_PRIVATE(inode))
 		return 0;
 		return 0;
 
 
-	acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
+	acl = get_acl(inode, ACL_TYPE_DEFAULT);
 
 
 	if (acl && !IS_ERR(acl)) {
 	if (acl && !IS_ERR(acl)) {
 		int size = reiserfs_acl_size(acl->a_count);
 		int size = reiserfs_acl_size(acl->a_count);

+ 8 - 11
fs/reiserfs/xattr_security.c

@@ -9,29 +9,26 @@
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 
 
 static int
 static int
-security_get(const struct xattr_handler *handler, struct dentry *dentry,
-	     const char *name, void *buffer, size_t size)
+security_get(const struct xattr_handler *handler, struct dentry *unused,
+	     struct inode *inode, const char *name, void *buffer, size_t size)
 {
 {
-	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
-		return -EINVAL;
-
-	if (IS_PRIVATE(d_inode(dentry)))
+	if (IS_PRIVATE(inode))
 		return -EPERM;
 		return -EPERM;
 
 
-	return reiserfs_xattr_get(d_inode(dentry), name, buffer, size);
+	return reiserfs_xattr_get(inode, xattr_full_name(handler, name),
+				  buffer, size);
 }
 }
 
 
 static int
 static int
 security_set(const struct xattr_handler *handler, struct dentry *dentry,
 security_set(const struct xattr_handler *handler, struct dentry *dentry,
 	     const char *name, const void *buffer, size_t size, int flags)
 	     const char *name, const void *buffer, size_t size, int flags)
 {
 {
-	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
-		return -EINVAL;
-
 	if (IS_PRIVATE(d_inode(dentry)))
 	if (IS_PRIVATE(d_inode(dentry)))
 		return -EPERM;
 		return -EPERM;
 
 
-	return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
+	return reiserfs_xattr_set(d_inode(dentry),
+				  xattr_full_name(handler, name),
+				  buffer, size, flags);
 }
 }
 
 
 static bool security_list(struct dentry *dentry)
 static bool security_list(struct dentry *dentry)

+ 8 - 11
fs/reiserfs/xattr_trusted.c

@@ -8,29 +8,26 @@
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 
 
 static int
 static int
-trusted_get(const struct xattr_handler *handler, struct dentry *dentry,
-	    const char *name, void *buffer, size_t size)
+trusted_get(const struct xattr_handler *handler, struct dentry *unused,
+	    struct inode *inode, const char *name, void *buffer, size_t size)
 {
 {
-	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
-		return -EINVAL;
-
-	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
+	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
 		return -EPERM;
 		return -EPERM;
 
 
-	return reiserfs_xattr_get(d_inode(dentry), name, buffer, size);
+	return reiserfs_xattr_get(inode, xattr_full_name(handler, name),
+				  buffer, size);
 }
 }
 
 
 static int
 static int
 trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
 trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
 	    const char *name, const void *buffer, size_t size, int flags)
 	    const char *name, const void *buffer, size_t size, int flags)
 {
 {
-	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
-		return -EINVAL;
-
 	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
 	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
 		return -EPERM;
 		return -EPERM;
 
 
-	return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
+	return reiserfs_xattr_set(d_inode(dentry),
+				  xattr_full_name(handler, name),
+				  buffer, size, flags);
 }
 }
 
 
 static bool trusted_list(struct dentry *dentry)
 static bool trusted_list(struct dentry *dentry)

+ 8 - 11
fs/reiserfs/xattr_user.c

@@ -7,27 +7,24 @@
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 
 
 static int
 static int
-user_get(const struct xattr_handler *handler, struct dentry *dentry,
-	 const char *name, void *buffer, size_t size)
+user_get(const struct xattr_handler *handler, struct dentry *unused,
+	 struct inode *inode, const char *name, void *buffer, size_t size)
 {
 {
-
-	if (strlen(name) < sizeof(XATTR_USER_PREFIX))
-		return -EINVAL;
-	if (!reiserfs_xattrs_user(dentry->d_sb))
+	if (!reiserfs_xattrs_user(inode->i_sb))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
-	return reiserfs_xattr_get(d_inode(dentry), name, buffer, size);
+	return reiserfs_xattr_get(inode, xattr_full_name(handler, name),
+				  buffer, size);
 }
 }
 
 
 static int
 static int
 user_set(const struct xattr_handler *handler, struct dentry *dentry,
 user_set(const struct xattr_handler *handler, struct dentry *dentry,
 	 const char *name, const void *buffer, size_t size, int flags)
 	 const char *name, const void *buffer, size_t size, int flags)
 {
 {
-	if (strlen(name) < sizeof(XATTR_USER_PREFIX))
-		return -EINVAL;
-
 	if (!reiserfs_xattrs_user(dentry->d_sb))
 	if (!reiserfs_xattrs_user(dentry->d_sb))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
-	return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
+	return reiserfs_xattr_set(d_inode(dentry),
+				  xattr_full_name(handler, name),
+				  buffer, size, flags);
 }
 }
 
 
 static bool user_list(struct dentry *dentry)
 static bool user_list(struct dentry *dentry)

+ 4 - 2
fs/squashfs/xattr.c

@@ -214,10 +214,12 @@ failed:
 
 
 
 
 static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
 static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
-				      struct dentry *d, const char *name,
+				      struct dentry *unused,
+				      struct inode *inode,
+				      const char *name,
 				      void *buffer, size_t size)
 				      void *buffer, size_t size)
 {
 {
-	return squashfs_xattr_get(d_inode(d), handler->flags, name,
+	return squashfs_xattr_get(inode, handler->flags, name,
 		buffer, size);
 		buffer, size);
 }
 }
 
 

+ 2 - 2
fs/ubifs/ubifs.h

@@ -1734,8 +1734,8 @@ int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 /* xattr.c */
 /* xattr.c */
 int ubifs_setxattr(struct dentry *dentry, const char *name,
 int ubifs_setxattr(struct dentry *dentry, const char *name,
 		   const void *value, size_t size, int flags);
 		   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);
 ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 int ubifs_removexattr(struct dentry *dentry, const char *name);
 int ubifs_removexattr(struct dentry *dentry, const char *name);
 int ubifs_init_security(struct inode *dentry, struct inode *inode,
 int ubifs_init_security(struct inode *dentry, struct inode *inode,

+ 3 - 3
fs/ubifs/xattr.c

@@ -372,10 +372,10 @@ int ubifs_setxattr(struct dentry *dentry, const char *name,
 	return setxattr(d_inode(dentry), name, value, size, flags);
 	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 ubifs_info *c = host->i_sb->s_fs_info;
 	struct qstr nm = QSTR_INIT(name, strlen(name));
 	struct qstr nm = QSTR_INIT(name, strlen(name));
 	struct ubifs_inode *ui;
 	struct ubifs_inode *ui;

+ 1 - 1
fs/udf/namei.c

@@ -1250,7 +1250,7 @@ static struct dentry *udf_get_parent(struct dentry *child)
 	brelse(fibh.sbh);
 	brelse(fibh.sbh);
 
 
 	tloc = lelb_to_cpu(cfi.icb.extLocation);
 	tloc = lelb_to_cpu(cfi.icb.extLocation);
-	inode = udf_iget(d_inode(child)->i_sb, &tloc);
+	inode = udf_iget(child->d_sb, &tloc);
 	if (IS_ERR(inode))
 	if (IS_ERR(inode))
 		return ERR_CAST(inode);
 		return ERR_CAST(inode);
 
 

+ 1 - 1
fs/ufs/super.c

@@ -132,7 +132,7 @@ static struct dentry *ufs_get_parent(struct dentry *child)
 	ino = ufs_inode_by_name(d_inode(child), &dot_dot);
 	ino = ufs_inode_by_name(d_inode(child), &dot_dot);
 	if (!ino)
 	if (!ino)
 		return ERR_PTR(-ENOENT);
 		return ERR_PTR(-ENOENT);
-	return d_obtain_alias(ufs_iget(d_inode(child)->i_sb, ino));
+	return d_obtain_alias(ufs_iget(child->d_sb, ino));
 }
 }
 
 
 static const struct export_operations ufs_export_ops = {
 static const struct export_operations ufs_export_ops = {

+ 7 - 5
fs/xattr.c

@@ -192,7 +192,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
 	if (!inode->i_op->getxattr)
 	if (!inode->i_op->getxattr)
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 
 
-	error = inode->i_op->getxattr(dentry, name, NULL, 0);
+	error = inode->i_op->getxattr(dentry, inode, name, NULL, 0);
 	if (error < 0)
 	if (error < 0)
 		return error;
 		return error;
 
 
@@ -203,7 +203,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
 		memset(value, 0, error + 1);
 		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;
 	*xattr_value = value;
 	return error;
 	return error;
 }
 }
@@ -236,7 +236,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
 	}
 	}
 nolsm:
 nolsm:
 	if (inode->i_op->getxattr)
 	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
 	else
 		error = -EOPNOTSUPP;
 		error = -EOPNOTSUPP;
 
 
@@ -691,14 +691,16 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
  * Find the handler for the prefix and dispatch its get() operation.
  * Find the handler for the prefix and dispatch its get() operation.
  */
  */
 ssize_t
 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;
 	const struct xattr_handler *handler;
 
 
 	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
 	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
 	if (IS_ERR(handler))
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
 		return PTR_ERR(handler);
-	return handler->get(handler, dentry, name, buffer, size);
+	return handler->get(handler, dentry, inode,
+			    name, buffer, size);
 }
 }
 
 
 /*
 /*

+ 6 - 14
fs/xfs/xfs_acl.c

@@ -158,22 +158,14 @@ xfs_get_acl(struct inode *inode, int type)
 	if (error) {
 	if (error) {
 		/*
 		/*
 		 * If the attribute doesn't exist make sure we have a negative
 		 * If the attribute doesn't exist make sure we have a negative
-		 * cache entry, for any other error assume it is transient and
-		 * leave the cache entry as ACL_NOT_CACHED.
+		 * cache entry, for any other error assume it is transient.
 		 */
 		 */
-		if (error == -ENOATTR)
-			goto out_update_cache;
-		acl = ERR_PTR(error);
-		goto out;
+		if (error != -ENOATTR)
+			acl = ERR_PTR(error);
+	} else  {
+		acl = xfs_acl_from_disk(xfs_acl, len,
+					XFS_ACL_MAX_ENTRIES(ip->i_mount));
 	}
 	}
-
-	acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount));
-	if (IS_ERR(acl))
-		goto out;
-
-out_update_cache:
-	set_cached_acl(inode, type, acl);
-out:
 	kmem_free(xfs_acl);
 	kmem_free(xfs_acl);
 	return acl;
 	return acl;
 }
 }

+ 3 - 3
fs/xfs/xfs_xattr.c

@@ -32,11 +32,11 @@
 
 
 
 
 static int
 static int
-xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry,
-		const char *name, void *value, size_t size)
+xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
+		struct inode *inode, const char *name, void *value, size_t size)
 {
 {
 	int xflags = handler->flags;
 	int xflags = handler->flags;
-	struct xfs_inode *ip = XFS_I(d_inode(dentry));
+	struct xfs_inode *ip = XFS_I(inode);
 	int error, asize = size;
 	int error, asize = size;
 
 
 	/* Convert Linux syscall to XFS internal ATTR flags */
 	/* Convert Linux syscall to XFS internal ATTR flags */

+ 14 - 1
include/linux/fs.h

@@ -577,6 +577,18 @@ static inline void mapping_allow_writable(struct address_space *mapping)
 struct posix_acl;
 struct posix_acl;
 #define ACL_NOT_CACHED ((void *)(-1))
 #define ACL_NOT_CACHED ((void *)(-1))
 
 
+static inline struct posix_acl *
+uncached_acl_sentinel(struct task_struct *task)
+{
+	return (void *)task + 1;
+}
+
+static inline bool
+is_uncached_acl(struct posix_acl *acl)
+{
+	return (long)acl & 1;
+}
+
 #define IOP_FASTPERM	0x0001
 #define IOP_FASTPERM	0x0001
 #define IOP_LOOKUP	0x0002
 #define IOP_LOOKUP	0x0002
 #define IOP_NOFOLLOW	0x0004
 #define IOP_NOFOLLOW	0x0004
@@ -1700,7 +1712,8 @@ struct inode_operations {
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
 	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);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
 	int (*removexattr) (struct dentry *, const char *);
 	int (*removexattr) (struct dentry *, const char *);
 	int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
 	int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,

+ 0 - 1
include/linux/posix_acl.h

@@ -99,7 +99,6 @@ extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
 extern int simple_set_acl(struct inode *, struct posix_acl *, int);
 extern int simple_set_acl(struct inode *, struct posix_acl *, int);
 extern int simple_acl_create(struct inode *, struct inode *);
 extern int simple_acl_create(struct inode *, struct inode *);
 
 
-struct posix_acl **acl_by_type(struct inode *inode, int type);
 struct posix_acl *get_cached_acl(struct inode *inode, int type);
 struct posix_acl *get_cached_acl(struct inode *inode, int type);
 struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type);
 struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type);
 void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl);
 void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl);

+ 3 - 2
include/linux/xattr.h

@@ -30,7 +30,8 @@ struct xattr_handler {
 	int flags;      /* fs private flags */
 	int flags;      /* fs private flags */
 	bool (*list)(struct dentry *dentry);
 	bool (*list)(struct dentry *dentry);
 	int (*get)(const struct xattr_handler *, struct dentry *dentry,
 	int (*get)(const struct xattr_handler *, struct dentry *dentry,
-		   const char *name, void *buffer, size_t size);
+		   struct inode *inode, const char *name, void *buffer,
+		   size_t size);
 	int (*set)(const struct xattr_handler *, struct dentry *dentry,
 	int (*set)(const struct xattr_handler *, struct dentry *dentry,
 		   const char *name, const void *buffer, size_t size,
 		   const char *name, const void *buffer, size_t size,
 		   int flags);
 		   int flags);
@@ -51,7 +52,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_setxattr(struct dentry *, const char *, const void *, size_t, int);
 int vfs_removexattr(struct dentry *, const char *);
 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);
 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, const char *name, const void *value, size_t size, int flags);
 int generic_removexattr(struct dentry *dentry, const char *name);
 int generic_removexattr(struct dentry *dentry, const char *name);

+ 3 - 3
include/trace/events/ext4.h

@@ -872,7 +872,7 @@ TRACE_EVENT(ext4_sync_file_enter,
 	TP_fast_assign(
 	TP_fast_assign(
 		struct dentry *dentry = file->f_path.dentry;
 		struct dentry *dentry = file->f_path.dentry;
 
 
-		__entry->dev		= d_inode(dentry)->i_sb->s_dev;
+		__entry->dev		= dentry->d_sb->s_dev;
 		__entry->ino		= d_inode(dentry)->i_ino;
 		__entry->ino		= d_inode(dentry)->i_ino;
 		__entry->datasync	= datasync;
 		__entry->datasync	= datasync;
 		__entry->parent		= d_inode(dentry->d_parent)->i_ino;
 		__entry->parent		= d_inode(dentry->d_parent)->i_ino;
@@ -1451,7 +1451,7 @@ TRACE_EVENT(ext4_unlink_enter,
 	),
 	),
 
 
 	TP_fast_assign(
 	TP_fast_assign(
-		__entry->dev		= d_inode(dentry)->i_sb->s_dev;
+		__entry->dev		= dentry->d_sb->s_dev;
 		__entry->ino		= d_inode(dentry)->i_ino;
 		__entry->ino		= d_inode(dentry)->i_ino;
 		__entry->parent		= parent->i_ino;
 		__entry->parent		= parent->i_ino;
 		__entry->size		= d_inode(dentry)->i_size;
 		__entry->size		= d_inode(dentry)->i_size;
@@ -1475,7 +1475,7 @@ TRACE_EVENT(ext4_unlink_exit,
 	),
 	),
 
 
 	TP_fast_assign(
 	TP_fast_assign(
-		__entry->dev		= d_inode(dentry)->i_sb->s_dev;
+		__entry->dev		= dentry->d_sb->s_dev;
 		__entry->ino		= d_inode(dentry)->i_ino;
 		__entry->ino		= d_inode(dentry)->i_ino;
 		__entry->ret		= ret;
 		__entry->ret		= ret;
 	),
 	),

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.