linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/18] Xattr inode operation removal
@ 2016-05-20 11:14 Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 01/18] xattr: Remove unnecessary NULL attribute name check Andreas Gruenbacher
                   ` (18 more replies)
  0 siblings, 19 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

This is version 2 of the xattr inode operation removal patch series. The
patches are available in git form at:

  https://git.kernel.org/cgit/linux/kernel/git/agruen/linux.git/log/?h=work.xattr

The purpose of this series is to remove unnecessary differences between the
xattr implementations on different filesystems and to simplify things.  With
the exception of redirectors like fuse, overlayfs, and ecryptfs, all
filesystems perform some de-multiplexing based on the xattr name, so it makes
sense to make that the default; filesystems that don't do any de-multiplexing
can easily use a catch-all xattr handler.

The patch series is structured as follows:

 * The initial patches convert the remaining filesystems over to use xattr
   handlers for implementing their de-multiplexing.

 * Next, a new IOP_XATTR inode operations flag is introduced: the flag is set
   when an inode supports xattrs.  On most filesystems, the IOP_XATTR flag is
   automatically initialized correctly when the inode is allocated based on
   whether or not the s_xattr field in the inode's superblock is defined.
   Filesystems that support xattrs on some but not all inodes can clear the
   IOP_XATTR flag appropriately.

 * The IOP_XATTR flag is then used to get rid of the two remaining places where
   xattr inode operations other than the generic ones are used: bad inodes and
   libfs empty directories.

 * After that, we get rid of the remaining direct accesses to xattr inode
   operations.

 * Finally, we stop calling the xattr inode operations and remove them.

Note that these patches only remove the getxattr, setxattr, and removexattr
inode operations. The listxattr inode operation does not do any attribute name
de-multiplexing, and remains unchanged except for checking the new IOP_XATTR
flag as well now.

Note that this patch series still breaks Lustre.  I'm hoping that the Lustre
developers will come up with a patch to switch lustre over to use xattr
handlers.

Thanks,
Andreas

Andreas Gruenbacher (18):
  xattr: Remove unnecessary NULL attribute name check
  jffs2: Remove jffs2_{get,set,remove}xattr macros
  hfs: Switch to generic xattr handlers
  kernfs: Switch to generic xattr handlers
  sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names
  sockfs: Get rid of getxattr iop
  ecryptfs: Switch to generic xattr handlers
  overlayfs: Switch to generic xattr handlers
  fuse: Switch to generic xattr handlers
  evm: Turn evm_update_evmxattr into void function
  vfs: Move xattr_resolve_name to the front of fs/xattr.c
  vfs: Add IOP_XATTR inode operations flag
  vfs: Use IOP_XATTR flag for bad-inode handling
  libfs: Use IOP_XATTR flag for empty directory handling
  xattr: Add __vfs_{get,set,remove}xattr helpers
  vfs: Check for the IOP_XATTR flag in listxattr
  xattr: Stop calling {get,set,remove}xattr inode operations
  vfs: Remove {get,set,remove}xattr inode operations

 Documentation/filesystems/Locking     |  24 +++-
 Documentation/filesystems/vfs.txt     |  45 ++++---
 arch/ia64/kernel/perfmon.c            |   4 +-
 drivers/gpu/drm/drm_drv.c             |   1 +
 fs/9p/vfs_inode_dotl.c                |   9 --
 fs/aio.c                              |   2 +-
 fs/anon_inodes.c                      |   2 +-
 fs/bad_inode.c                        |  21 +--
 fs/block_dev.c                        |   2 +-
 fs/btrfs/inode.c                      |  12 --
 fs/btrfs/tests/btrfs-tests.c          |   2 +-
 fs/cachefiles/bind.c                  |   4 +-
 fs/cachefiles/namei.c                 |   4 +-
 fs/ceph/dir.c                         |   3 -
 fs/ceph/inode.c                       |   6 -
 fs/cifs/cifsfs.c                      |   9 --
 fs/ecryptfs/ecryptfs_kernel.h         |   2 +
 fs/ecryptfs/inode.c                   |  57 +++++---
 fs/ecryptfs/main.c                    |   1 +
 fs/ecryptfs/mmap.c                    |  11 +-
 fs/ext2/file.c                        |   3 -
 fs/ext2/namei.c                       |   6 -
 fs/ext2/symlink.c                     |   6 -
 fs/ext4/file.c                        |   3 -
 fs/ext4/namei.c                       |   6 -
 fs/ext4/symlink.c                     |   9 --
 fs/f2fs/file.c                        |   3 -
 fs/f2fs/namei.c                       |  12 --
 fs/fuse/dir.c                         |  40 ++++--
 fs/fuse/fuse_i.h                      |   2 +
 fs/fuse/inode.c                       |   1 +
 fs/gfs2/inode.c                       |   9 --
 fs/hfs/attr.c                         |  82 ++++++++----
 fs/hfs/hfs_fs.h                       |   6 +-
 fs/hfs/inode.c                        |   5 +-
 fs/hfs/super.c                        |   1 +
 fs/hfsplus/dir.c                      |   3 -
 fs/hfsplus/inode.c                    |   3 -
 fs/inode.c                            |   2 +
 fs/jffs2/dir.c                        |   3 -
 fs/jffs2/file.c                       |   3 -
 fs/jffs2/symlink.c                    |   3 -
 fs/jffs2/xattr.h                      |   6 -
 fs/jfs/file.c                         |   3 -
 fs/jfs/namei.c                        |   3 -
 fs/jfs/symlink.c                      |   6 -
 fs/kernfs/dir.c                       |   3 -
 fs/kernfs/inode.c                     | 153 +++++++++++----------
 fs/kernfs/kernfs-internal.h           |   6 +-
 fs/kernfs/mount.c                     |   1 +
 fs/kernfs/symlink.c                   |   3 -
 fs/libfs.c                            |  24 +---
 fs/nfs/nfs3proc.c                     |   6 -
 fs/nfs/nfs4proc.c                     |   6 -
 fs/nsfs.c                             |   2 +-
 fs/ocfs2/file.c                       |   3 -
 fs/ocfs2/namei.c                      |   3 -
 fs/ocfs2/symlink.c                    |   3 -
 fs/orangefs/inode.c                   |   3 -
 fs/orangefs/namei.c                   |   3 -
 fs/orangefs/symlink.c                 |   1 -
 fs/overlayfs/copy_up.c                |   4 +-
 fs/overlayfs/dir.c                    |   3 -
 fs/overlayfs/inode.c                  |  46 +++++--
 fs/overlayfs/overlayfs.h              |   6 +-
 fs/overlayfs/super.c                  |   5 +-
 fs/pipe.c                             |   2 +-
 fs/reiserfs/file.c                    |   3 -
 fs/reiserfs/namei.c                   |   9 --
 fs/squashfs/inode.c                   |   1 -
 fs/squashfs/namei.c                   |   1 -
 fs/squashfs/symlink.c                 |   1 -
 fs/squashfs/xattr.h                   |   1 -
 fs/ubifs/dir.c                        |   3 -
 fs/ubifs/file.c                       |   6 -
 fs/xattr.c                            | 245 +++++++++++++++++-----------------
 fs/xfs/xfs_iops.c                     |  12 --
 include/linux/fs.h                    |   6 +-
 include/linux/xattr.h                 |   6 +-
 mm/shmem.c                            |  15 ---
 net/socket.c                          |  59 ++++----
 security/commoncap.c                  |  25 ++--
 security/integrity/evm/evm.h          |   7 +-
 security/integrity/evm/evm_crypto.c   |  20 ++-
 security/integrity/evm/evm_main.c     |   4 +-
 security/integrity/ima/ima_appraise.c |  21 ++-
 security/selinux/hooks.c              |  19 +--
 security/smack/smack_lsm.c            |  12 +-
 88 files changed, 529 insertions(+), 683 deletions(-)

-- 
2.5.5


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 01/18] xattr: Remove unnecessary NULL attribute name check
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-26 12:49   ` Carlos Maiolino
  2016-05-20 11:14 ` [PATCH v2 02/18] jffs2: Remove jffs2_{get,set,remove}xattr macros Andreas Gruenbacher
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

When NULL is passed to one of the xattr system calls as the attribute
name, copying that name from user space already fails with -EFAULT;
xattr_resolve_name is never called with a NULL attribute name.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/xattr.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index b11945e..2476acc 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -667,9 +667,6 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
 {
 	const struct xattr_handler *handler;
 
-	if (!*name)
-		return NULL;
-
 	for_each_xattr_handler(handlers, handler) {
 		const char *n;
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 02/18] jffs2: Remove jffs2_{get,set,remove}xattr macros
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 01/18] xattr: Remove unnecessary NULL attribute name check Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 03/18] hfs: Switch to generic xattr handlers Andreas Gruenbacher
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

When CONFIG_JFFS2_FS_XATTR is off, jffs2_xattr_handlers is defined as
NULL. With sb->s_xattr == NULL, the generic_{get,set,remove}xattr
functions produce the same result that setting the {get,set,remove}xattr
inode operations to NULL produces, so there is no need for these macros.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/jffs2/dir.c     | 6 +++---
 fs/jffs2/file.c    | 6 +++---
 fs/jffs2/symlink.c | 6 +++---
 fs/jffs2/xattr.h   | 6 ------
 4 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 84c4bf3..db84191 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -61,10 +61,10 @@ const struct inode_operations jffs2_dir_inode_operations =
 	.get_acl =	jffs2_get_acl,
 	.set_acl =	jffs2_set_acl,
 	.setattr =	jffs2_setattr,
-	.setxattr =	jffs2_setxattr,
-	.getxattr =	jffs2_getxattr,
+	.setxattr =	generic_setxattr,
+	.getxattr =	generic_getxattr,
 	.listxattr =	jffs2_listxattr,
-	.removexattr =	jffs2_removexattr
+	.removexattr =	generic_removexattr
 };
 
 /***********************************************************************/
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 0e62dec..fdf9e1c 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -66,10 +66,10 @@ const struct inode_operations jffs2_file_inode_operations =
 	.get_acl =	jffs2_get_acl,
 	.set_acl =	jffs2_set_acl,
 	.setattr =	jffs2_setattr,
-	.setxattr =	jffs2_setxattr,
-	.getxattr =	jffs2_getxattr,
+	.setxattr =	generic_setxattr,
+	.getxattr =	generic_getxattr,
 	.listxattr =	jffs2_listxattr,
-	.removexattr =	jffs2_removexattr
+	.removexattr =	generic_removexattr
 };
 
 const struct address_space_operations jffs2_file_address_operations =
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 2cabd64..afe2d75 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -16,8 +16,8 @@ const struct inode_operations jffs2_symlink_inode_operations =
 	.readlink =	generic_readlink,
 	.get_link =	simple_get_link,
 	.setattr =	jffs2_setattr,
-	.setxattr =	jffs2_setxattr,
-	.getxattr =	jffs2_getxattr,
+	.setxattr =	generic_setxattr,
+	.getxattr =	generic_getxattr,
 	.listxattr =	jffs2_listxattr,
-	.removexattr =	jffs2_removexattr
+	.removexattr =	generic_removexattr
 };
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
index 467ff37..720007b 100644
--- a/fs/jffs2/xattr.h
+++ b/fs/jffs2/xattr.h
@@ -99,9 +99,6 @@ extern const struct xattr_handler jffs2_user_xattr_handler;
 extern const struct xattr_handler jffs2_trusted_xattr_handler;
 
 extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
-#define jffs2_getxattr		generic_getxattr
-#define jffs2_setxattr		generic_setxattr
-#define jffs2_removexattr	generic_removexattr
 
 #else
 
@@ -116,9 +113,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
 
 #define jffs2_xattr_handlers	NULL
 #define jffs2_listxattr		NULL
-#define jffs2_getxattr		NULL
-#define jffs2_setxattr		NULL
-#define jffs2_removexattr	NULL
 
 #endif /* CONFIG_JFFS2_FS_XATTR */
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 03/18] hfs: Switch to generic xattr handlers
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 01/18] xattr: Remove unnecessary NULL attribute name check Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 02/18] jffs2: Remove jffs2_{get,set,remove}xattr macros Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 04/18] kernfs: " Andreas Gruenbacher
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/hfs/attr.c   | 82 +++++++++++++++++++++++++++++++++++++++------------------
 fs/hfs/hfs_fs.h |  6 +----
 fs/hfs/inode.c  |  7 ++---
 fs/hfs/super.c  |  1 +
 4 files changed, 62 insertions(+), 34 deletions(-)

diff --git a/fs/hfs/attr.c b/fs/hfs/attr.c
index 064f92f..8adcf33 100644
--- a/fs/hfs/attr.c
+++ b/fs/hfs/attr.c
@@ -13,10 +13,14 @@
 #include "hfs_fs.h"
 #include "btree.h"
 
-int hfs_setxattr(struct dentry *dentry, const char *name,
-		 const void *value, size_t size, int flags)
+enum hfs_xattr_type {
+	HFS_TYPE,
+	HFS_CREATOR,
+};
+
+static int __hfs_setxattr(struct inode *inode, enum hfs_xattr_type type,
+			  const void *value, size_t size, int flags)
 {
-	struct inode *inode = d_inode(dentry);
 	struct hfs_find_data fd;
 	hfs_cat_rec rec;
 	struct hfs_cat_file *file;
@@ -36,18 +40,22 @@ int hfs_setxattr(struct dentry *dentry, const char *name,
 			sizeof(struct hfs_cat_file));
 	file = &rec.file;
 
-	if (!strcmp(name, "hfs.type")) {
+	switch(type) {
+	case HFS_TYPE:
 		if (size == 4)
 			memcpy(&file->UsrWds.fdType, value, 4);
 		else
 			res = -ERANGE;
-	} else if (!strcmp(name, "hfs.creator")) {
+		break;
+
+	case HFS_CREATOR:
 		if (size == 4)
 			memcpy(&file->UsrWds.fdCreator, value, 4);
 		else
 			res = -ERANGE;
-	} else
-		res = -EOPNOTSUPP;
+		break;
+	}
+
 	if (!res)
 		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
 				sizeof(struct hfs_cat_file));
@@ -56,8 +64,8 @@ out:
 	return res;
 }
 
-ssize_t hfs_getxattr(struct dentry *unused, struct inode *inode,
-		     const char *name, void *value, size_t size)
+static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type,
+			      void *value, size_t size)
 {
 	struct hfs_find_data fd;
 	hfs_cat_rec rec;
@@ -80,41 +88,63 @@ ssize_t hfs_getxattr(struct dentry *unused, struct inode *inode,
 	}
 	file = &rec.file;
 
-	if (!strcmp(name, "hfs.type")) {
+	switch(type) {
+	case HFS_TYPE:
 		if (size >= 4) {
 			memcpy(value, &file->UsrWds.fdType, 4);
 			res = 4;
 		} else
 			res = size ? -ERANGE : 4;
-	} else if (!strcmp(name, "hfs.creator")) {
+		break;
+
+	case HFS_CREATOR:
 		if (size >= 4) {
 			memcpy(value, &file->UsrWds.fdCreator, 4);
 			res = 4;
 		} else
 			res = size ? -ERANGE : 4;
-	} else
-		res = -ENODATA;
+		break;
+	}
+
 out:
 	if (size)
 		hfs_find_exit(&fd);
 	return res;
 }
 
-#define HFS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type"))
-
-ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+static int hfs_xattr_get(const struct xattr_handler *handler,
+			 struct dentry *unused, struct inode *inode,
+			 const char *name, void *value, size_t size)
 {
-	struct inode *inode = d_inode(dentry);
+	return __hfs_getxattr(inode, handler->flags, value, size);
+}
 
-	if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
+static int hfs_xattr_set(const struct xattr_handler *handler,
+			 struct dentry *dentry, const char *name,
+			 const void *value, size_t size, int flags)
+{
+	if (!value)
 		return -EOPNOTSUPP;
 
-	if (!buffer || !size)
-		return HFS_ATTRLIST_SIZE;
-	if (size < HFS_ATTRLIST_SIZE)
-		return -ERANGE;
-	strcpy(buffer, "hfs.type");
-	strcpy(buffer + sizeof("hfs.type"), "hfs.creator");
-
-	return HFS_ATTRLIST_SIZE;
+	return __hfs_setxattr(d_inode(dentry), handler->flags, value, size, flags);
 }
+
+static const struct xattr_handler hfs_creator_handler = {
+	.name = "hfs.creator",
+	.flags = HFS_CREATOR,
+	.get = hfs_xattr_get,
+	.set = hfs_xattr_set,
+};
+
+static const struct xattr_handler hfs_type_handler = {
+	.name = "hfs.type",
+	.flags = HFS_TYPE,
+	.get = hfs_xattr_get,
+	.set = hfs_xattr_set,
+};
+
+const struct xattr_handler *hfs_xattr_handlers[] = {
+	&hfs_creator_handler,
+	&hfs_type_handler,
+	NULL
+};
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index fa3eed8..c4691e8 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -212,11 +212,7 @@ extern void hfs_evict_inode(struct inode *);
 extern void hfs_delete_inode(struct inode *);
 
 /* attr.c */
-extern int hfs_setxattr(struct dentry *dentry, const char *name,
-			const void *value, size_t size, int flags);
-extern ssize_t hfs_getxattr(struct dentry *dentry, struct inode *inode,
-			    const char *name, void *value, size_t size);
-extern ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
+extern const struct xattr_handler *hfs_xattr_handlers[];
 
 /* mdb.c */
 extern int hfs_mdb_get(struct super_block *);
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 8eed66a..d7f833f 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -15,6 +15,7 @@
 #include <linux/mpage.h>
 #include <linux/sched.h>
 #include <linux/uio.h>
+#include <linux/xattr.h>
 
 #include "hfs_fs.h"
 #include "btree.h"
@@ -687,7 +688,7 @@ static const struct file_operations hfs_file_operations = {
 static const struct inode_operations hfs_file_inode_operations = {
 	.lookup		= hfs_file_lookup,
 	.setattr	= hfs_inode_setattr,
-	.setxattr	= hfs_setxattr,
-	.getxattr	= hfs_getxattr,
-	.listxattr	= hfs_listxattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= generic_listxattr,
 };
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 1ca95c2..bf6304a 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -406,6 +406,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
 	}
 
 	sb->s_op = &hfs_super_operations;
+	sb->s_xattr = hfs_xattr_handlers;
 	sb->s_flags |= MS_NODIRATIME;
 	mutex_init(&sbi->bitmap_lock);
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 04/18] kernfs: Switch to generic xattr handlers
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (2 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 03/18] hfs: Switch to generic xattr handlers Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 05/18] sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names Andreas Gruenbacher
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Tejun Heo <tj@kernel.org>
---
 fs/kernfs/dir.c             |   6 +-
 fs/kernfs/inode.c           | 156 +++++++++++++++++++++++---------------------
 fs/kernfs/kernfs-internal.h |   6 +-
 fs/kernfs/mount.c           |   1 +
 fs/kernfs/symlink.c         |   6 +-
 5 files changed, 91 insertions(+), 84 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 68a4431..8e69385b 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1125,9 +1125,9 @@ const struct inode_operations kernfs_dir_iops = {
 	.permission	= kernfs_iop_permission,
 	.setattr	= kernfs_iop_setattr,
 	.getattr	= kernfs_iop_getattr,
-	.setxattr	= kernfs_iop_setxattr,
-	.removexattr	= kernfs_iop_removexattr,
-	.getxattr	= kernfs_iop_getxattr,
+	.setxattr	= generic_setxattr,
+	.removexattr	= generic_removexattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= kernfs_iop_listxattr,
 
 	.mkdir		= kernfs_iop_mkdir,
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index b524722..300a07a 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -28,9 +28,9 @@ static const struct inode_operations kernfs_iops = {
 	.permission	= kernfs_iop_permission,
 	.setattr	= kernfs_iop_setattr,
 	.getattr	= kernfs_iop_getattr,
-	.setxattr	= kernfs_iop_setxattr,
-	.removexattr	= kernfs_iop_removexattr,
-	.getxattr	= kernfs_iop_getxattr,
+	.setxattr	= generic_setxattr,
+	.removexattr	= generic_removexattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= kernfs_iop_listxattr,
 };
 
@@ -135,17 +135,12 @@ out:
 	return error;
 }
 
-static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata,
+static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata,
 				  u32 *secdata_len)
 {
-	struct kernfs_iattrs *attrs;
 	void *old_secdata;
 	size_t old_secdata_len;
 
-	attrs = kernfs_iattrs(kn);
-	if (!attrs)
-		return -ENOMEM;
-
 	old_secdata = attrs->ia_secdata;
 	old_secdata_len = attrs->ia_secdata_len;
 
@@ -157,70 +152,6 @@ static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata,
 	return 0;
 }
 
-int kernfs_iop_setxattr(struct dentry *dentry, const char *name,
-			const void *value, size_t size, int flags)
-{
-	struct kernfs_node *kn = dentry->d_fsdata;
-	struct kernfs_iattrs *attrs;
-	void *secdata;
-	int error;
-	u32 secdata_len = 0;
-
-	attrs = kernfs_iattrs(kn);
-	if (!attrs)
-		return -ENOMEM;
-
-	if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
-		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
-		error = security_inode_setsecurity(d_inode(dentry), suffix,
-						value, size, flags);
-		if (error)
-			return error;
-		error = security_inode_getsecctx(d_inode(dentry),
-						&secdata, &secdata_len);
-		if (error)
-			return error;
-
-		mutex_lock(&kernfs_mutex);
-		error = kernfs_node_setsecdata(kn, &secdata, &secdata_len);
-		mutex_unlock(&kernfs_mutex);
-
-		if (secdata)
-			security_release_secctx(secdata, secdata_len);
-		return error;
-	} else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
-		return simple_xattr_set(&attrs->xattrs, name, value, size,
-					flags);
-	}
-
-	return -EINVAL;
-}
-
-int kernfs_iop_removexattr(struct dentry *dentry, const char *name)
-{
-	struct kernfs_node *kn = dentry->d_fsdata;
-	struct kernfs_iattrs *attrs;
-
-	attrs = kernfs_iattrs(kn);
-	if (!attrs)
-		return -ENOMEM;
-
-	return simple_xattr_set(&attrs->xattrs, name, NULL, 0, XATTR_REPLACE);
-}
-
-ssize_t kernfs_iop_getxattr(struct dentry *unused, struct inode *inode,
-			    const char *name, void *buf, size_t size)
-{
-	struct kernfs_node *kn = inode->i_private;
-	struct kernfs_iattrs *attrs;
-
-	attrs = kernfs_iattrs(kn);
-	if (!attrs)
-		return -ENOMEM;
-
-	return simple_xattr_get(&attrs->xattrs, name, buf, size);
-}
-
 ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
 {
 	struct kernfs_node *kn = dentry->d_fsdata;
@@ -370,3 +301,82 @@ int kernfs_iop_permission(struct inode *inode, int mask)
 
 	return generic_permission(inode, mask);
 }
+
+static int kernfs_xattr_get(const struct xattr_handler *handler,
+			    struct dentry *unused, struct inode *inode,
+			    const char *suffix, void *value, size_t size)
+{
+	const char *name = xattr_full_name(handler, suffix);
+	struct kernfs_node *kn = inode->i_private;
+	struct kernfs_iattrs *attrs;
+
+	attrs = kernfs_iattrs(kn);
+	if (!attrs)
+		return -ENOMEM;
+
+	return simple_xattr_get(&attrs->xattrs, name, value, size);
+}
+
+static int kernfs_xattr_set(const struct xattr_handler *handler,
+			    struct dentry *dentry, const char *suffix,
+			    const void *value, size_t size, int flags)
+{
+	const char *name = xattr_full_name(handler, suffix);
+	struct kernfs_node *kn = dentry->d_fsdata;
+	struct kernfs_iattrs *attrs;
+
+	attrs = kernfs_iattrs(kn);
+	if (!attrs)
+		return -ENOMEM;
+
+	return simple_xattr_set(&attrs->xattrs, name, value, size, flags);
+}
+
+const struct xattr_handler kernfs_trusted_xattr_handler = {
+	.prefix = XATTR_TRUSTED_PREFIX,
+	.get = kernfs_xattr_get,
+	.set = kernfs_xattr_set,
+};
+
+static int kernfs_security_xattr_set(const struct xattr_handler *handler,
+				     struct dentry *dentry, const char *suffix,
+				     const void *value, size_t size, int flags)
+{
+	struct kernfs_node *kn = dentry->d_fsdata;
+	struct inode *inode = d_inode(dentry);
+	struct kernfs_iattrs *attrs;
+	void *secdata;
+	u32 secdata_len = 0;
+	int error;
+
+	attrs = kernfs_iattrs(kn);
+	if (!attrs)
+		return -ENOMEM;
+
+	error = security_inode_setsecurity(inode, suffix, value, size, flags);
+	if (error)
+		return error;
+	error = security_inode_getsecctx(inode, &secdata, &secdata_len);
+	if (error)
+		return error;
+
+	mutex_lock(&kernfs_mutex);
+	error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len);
+	mutex_unlock(&kernfs_mutex);
+
+	if (secdata)
+		security_release_secctx(secdata, secdata_len);
+	return error;
+}
+
+const struct xattr_handler kernfs_security_xattr_handler = {
+	.prefix = XATTR_SECURITY_PREFIX,
+	.get = kernfs_xattr_get,
+	.set = kernfs_security_xattr_set,
+};
+
+const struct xattr_handler *kernfs_xattr_handlers[] = {
+	&kernfs_trusted_xattr_handler,
+	&kernfs_security_xattr_handler,
+	NULL
+};
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index 45c9192..bfd551b 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -76,16 +76,12 @@ extern struct kmem_cache *kernfs_node_cache;
 /*
  * inode.c
  */
+extern const struct xattr_handler *kernfs_xattr_handlers[];
 void kernfs_evict_inode(struct inode *inode);
 int kernfs_iop_permission(struct inode *inode, int mask);
 int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr);
 int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry,
 		       struct kstat *stat);
-int kernfs_iop_setxattr(struct dentry *dentry, const char *name, const void *value,
-			size_t size, int flags);
-int kernfs_iop_removexattr(struct dentry *dentry, const char *name);
-ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode,
-			    const char *name, void *buf, size_t size);
 ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size);
 
 /*
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c
index 63534f5..9c225d7 100644
--- a/fs/kernfs/mount.c
+++ b/fs/kernfs/mount.c
@@ -156,6 +156,7 @@ static int kernfs_fill_super(struct super_block *sb, unsigned long magic)
 	sb->s_blocksize_bits = PAGE_SHIFT;
 	sb->s_magic = magic;
 	sb->s_op = &kernfs_sops;
+	sb->s_xattr = kernfs_xattr_handlers;
 	sb->s_time_gran = 1;
 
 	/* get root inode, initialize and unlock it */
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c
index 117b8b3..549a14c7 100644
--- a/fs/kernfs/symlink.c
+++ b/fs/kernfs/symlink.c
@@ -134,9 +134,9 @@ static const char *kernfs_iop_get_link(struct dentry *dentry,
 }
 
 const struct inode_operations kernfs_symlink_iops = {
-	.setxattr	= kernfs_iop_setxattr,
-	.removexattr	= kernfs_iop_removexattr,
-	.getxattr	= kernfs_iop_getxattr,
+	.setxattr	= generic_setxattr,
+	.removexattr	= generic_removexattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= kernfs_iop_listxattr,
 	.readlink	= generic_readlink,
 	.get_link	= kernfs_iop_get_link,
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 05/18] sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (3 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 04/18] kernfs: " Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 06/18] sockfs: Get rid of getxattr iop Andreas Gruenbacher
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

The standard return value for unsupported attribute names is
-EOPNOTSUPP, as opposed to undefined but supported attributes
(-ENODATA).

Also, fail for attribute names like "system.sockprotonameXXX" and
simplify the code a bit.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 net/socket.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index e7793f5..5aa572f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -469,27 +469,15 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
 static ssize_t sockfs_getxattr(struct dentry *dentry, struct inode *inode,
 			       const char *name, void *value, size_t size)
 {
-	const char *proto_name;
-	size_t proto_size;
-	int error;
-
-	error = -ENODATA;
-	if (!strncmp(name, XATTR_NAME_SOCKPROTONAME, XATTR_NAME_SOCKPROTONAME_LEN)) {
-		proto_name = dentry->d_name.name;
-		proto_size = strlen(proto_name);
-
+	if (!strcmp(name, XATTR_NAME_SOCKPROTONAME)) {
 		if (value) {
-			error = -ERANGE;
-			if (proto_size + 1 > size)
-				goto out;
-
-			strncpy(value, proto_name, proto_size + 1);
+			if (dentry->d_name.len + 1 > size)
+				return -ERANGE;
+			memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
 		}
-		error = proto_size + 1;
+		return dentry->d_name.len + 1;
 	}
-
-out:
-	return error;
+	return -EOPNOTSUPP;
 }
 
 static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 06/18] sockfs: Get rid of getxattr iop
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (4 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 05/18] sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 07/18] ecryptfs: Switch to generic xattr handlers Andreas Gruenbacher
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

If we allow pseudo-filesystems created with mount_pseudo to have xattr
handlers, we can replace sockfs_getxattr with a sockfs_xattr_get handler
to use the xattr handler name parsing.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 arch/ia64/kernel/perfmon.c   |  4 ++--
 drivers/gpu/drm/drm_drv.c    |  1 +
 fs/aio.c                     |  2 +-
 fs/anon_inodes.c             |  2 +-
 fs/block_dev.c               |  2 +-
 fs/btrfs/tests/btrfs-tests.c |  2 +-
 fs/libfs.c                   |  3 ++-
 fs/nsfs.c                    |  2 +-
 fs/pipe.c                    |  2 +-
 include/linux/fs.h           |  1 +
 net/socket.c                 | 48 ++++++++++++++++++++++++++------------------
 11 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 9cd607b..782cddb 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -611,8 +611,8 @@ static const struct dentry_operations pfmfs_dentry_operations;
 static struct dentry *
 pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
 {
-	return mount_pseudo(fs_type, "pfm:", NULL, &pfmfs_dentry_operations,
-			PFMFS_MAGIC);
+	return mount_pseudo(fs_type, "pfm:", NULL, NULL,
+			    &pfmfs_dentry_operations, PFMFS_MAGIC);
 }
 
 static struct file_system_type pfm_fs_type = {
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 167c8d3..3512bb8 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -509,6 +509,7 @@ static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags,
 	return mount_pseudo(fs_type,
 			    "drm:",
 			    &drm_fs_sops,
+			    NULL,
 			    &drm_fs_dops,
 			    0x010203ff);
 }
diff --git a/fs/aio.c b/fs/aio.c
index a6deaa7..56ce2d6 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -239,7 +239,7 @@ static struct dentry *aio_mount(struct file_system_type *fs_type,
 	static const struct dentry_operations ops = {
 		.d_dname	= simple_dname,
 	};
-	return mount_pseudo(fs_type, "aio:", NULL, &ops, AIO_RING_MAGIC);
+	return mount_pseudo(fs_type, "aio:", NULL, NULL, &ops, AIO_RING_MAGIC);
 }
 
 /* aio_setup
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 80ef38c..5e1aeea1 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -41,7 +41,7 @@ static const struct dentry_operations anon_inodefs_dentry_operations = {
 static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
 				int flags, const char *dev_name, void *data)
 {
-	return mount_pseudo(fs_type, "anon_inode:", NULL,
+	return mount_pseudo(fs_type, "anon_inode:", NULL, NULL,
 			&anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
 }
 
diff --git a/fs/block_dev.c b/fs/block_dev.c
index a063d4d..68314e9 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -576,7 +576,7 @@ static struct dentry *bd_mount(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data)
 {
 	struct dentry *dent;
-	dent = mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC);
+	dent = mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, NULL, BDEVFS_MAGIC);
 	if (dent)
 		dent->d_sb->s_iflags |= SB_I_CGROUPWB;
 	return dent;
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
index f54bf45..ebecf33 100644
--- a/fs/btrfs/tests/btrfs-tests.c
+++ b/fs/btrfs/tests/btrfs-tests.c
@@ -40,7 +40,7 @@ static struct dentry *btrfs_test_mount(struct file_system_type *fs_type,
 				       void *data)
 {
 	return mount_pseudo(fs_type, "btrfs_test:", &btrfs_test_super_ops,
-			    NULL, BTRFS_TEST_MAGIC);
+			    NULL, NULL, BTRFS_TEST_MAGIC);
 }
 
 static struct file_system_type test_type = {
diff --git a/fs/libfs.c b/fs/libfs.c
index 8765ff1..92215d5 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -206,7 +206,7 @@ static const struct super_operations simple_super_operations = {
  * will never be mountable)
  */
 struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
-	const struct super_operations *ops,
+	const struct super_operations *ops, const struct xattr_handler **xattr,
 	const struct dentry_operations *dops, unsigned long magic)
 {
 	struct super_block *s;
@@ -223,6 +223,7 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
 	s->s_blocksize_bits = PAGE_SHIFT;
 	s->s_magic = magic;
 	s->s_op = ops ? ops : &simple_super_operations;
+	s->s_xattr = xattr;
 	s->s_time_gran = 1;
 	root = new_inode(s);
 	if (!root)
diff --git a/fs/nsfs.c b/fs/nsfs.c
index 8f20d60..e151cc3 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -154,7 +154,7 @@ static const struct super_operations nsfs_ops = {
 static struct dentry *nsfs_mount(struct file_system_type *fs_type,
 			int flags, const char *dev_name, void *data)
 {
-	return mount_pseudo(fs_type, "nsfs:", &nsfs_ops,
+	return mount_pseudo(fs_type, "nsfs:", &nsfs_ops, NULL,
 			&ns_dentry_operations, NSFS_MAGIC);
 }
 static struct file_system_type nsfs = {
diff --git a/fs/pipe.c b/fs/pipe.c
index 0d3f516..035fa6f 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1143,7 +1143,7 @@ static const struct super_operations pipefs_ops = {
 static struct dentry *pipefs_mount(struct file_system_type *fs_type,
 			 int flags, const char *dev_name, void *data)
 {
-	return mount_pseudo(fs_type, "pipe:", &pipefs_ops,
+	return mount_pseudo(fs_type, "pipe:", &pipefs_ops, NULL,
 			&pipefs_dentry_operations, PIPEFS_MAGIC);
 }
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 10d3d8f..b0c2f76 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2059,6 +2059,7 @@ struct super_block *sget(struct file_system_type *type,
 			int flags, void *data);
 extern struct dentry *mount_pseudo(struct file_system_type *, char *,
 	const struct super_operations *ops,
+	const struct xattr_handler **xattr,
 	const struct dentry_operations *dops,
 	unsigned long);
 
diff --git a/net/socket.c b/net/socket.c
index 5aa572f..d7816b6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -320,11 +320,38 @@ static const struct dentry_operations sockfs_dentry_operations = {
 	.d_dname  = sockfs_dname,
 };
 
+static int sockfs_xattr_get(const struct xattr_handler *handler,
+			    struct dentry *dentry, struct inode *inode,
+			    const char *suffix, void *value, size_t size)
+{
+	if (value) {
+		if (dentry->d_name.len + 1 > size)
+			return -ERANGE;
+		memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
+	}
+	return dentry->d_name.len + 1;
+}
+
+#define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
+#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
+#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
+
+static const struct xattr_handler sockfs_xattr_handler = {
+	.name = XATTR_NAME_SOCKPROTONAME,
+	.get = sockfs_xattr_get,
+};
+
+static const struct xattr_handler *sockfs_xattr_handlers[] = {
+	&sockfs_xattr_handler,
+	NULL
+};
+
 static struct dentry *sockfs_mount(struct file_system_type *fs_type,
 			 int flags, const char *dev_name, void *data)
 {
 	return mount_pseudo(fs_type, "socket:", &sockfs_ops,
-		&sockfs_dentry_operations, SOCKFS_MAGIC);
+			    sockfs_xattr_handlers,
+			    &sockfs_dentry_operations, SOCKFS_MAGIC);
 }
 
 static struct vfsmount *sock_mnt __read_mostly;
@@ -463,23 +490,6 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
 	return NULL;
 }
 
-#define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
-#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
-#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
-static ssize_t sockfs_getxattr(struct dentry *dentry, struct inode *inode,
-			       const char *name, void *value, size_t size)
-{
-	if (!strcmp(name, XATTR_NAME_SOCKPROTONAME)) {
-		if (value) {
-			if (dentry->d_name.len + 1 > size)
-				return -ERANGE;
-			memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
-		}
-		return dentry->d_name.len + 1;
-	}
-	return -EOPNOTSUPP;
-}
-
 static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
 				size_t size)
 {
@@ -509,7 +519,7 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
 }
 
 static const struct inode_operations sockfs_inode_ops = {
-	.getxattr = sockfs_getxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = sockfs_listxattr,
 };
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 07/18] ecryptfs: Switch to generic xattr handlers
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (5 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 06/18] sockfs: Get rid of getxattr iop Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 08/18] overlayfs: " Andreas Gruenbacher
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/ecryptfs/ecryptfs_kernel.h |  2 ++
 fs/ecryptfs/inode.c           | 48 +++++++++++++++++++++++++++++++++++--------
 fs/ecryptfs/main.c            |  1 +
 3 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 3ec495d..38b84ea 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -715,4 +715,6 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
 int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
 		       loff_t offset);
 
+extern const struct xattr_handler *ecryptfs_xattr_handlers[];
+
 #endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 318b046..4129233 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -1088,10 +1088,10 @@ const struct inode_operations ecryptfs_symlink_iops = {
 	.permission = ecryptfs_permission,
 	.setattr = ecryptfs_setattr,
 	.getattr = ecryptfs_getattr_link,
-	.setxattr = ecryptfs_setxattr,
-	.getxattr = ecryptfs_getxattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = ecryptfs_listxattr,
-	.removexattr = ecryptfs_removexattr
+	.removexattr = generic_removexattr
 };
 
 const struct inode_operations ecryptfs_dir_iops = {
@@ -1106,18 +1106,48 @@ const struct inode_operations ecryptfs_dir_iops = {
 	.rename = ecryptfs_rename,
 	.permission = ecryptfs_permission,
 	.setattr = ecryptfs_setattr,
-	.setxattr = ecryptfs_setxattr,
-	.getxattr = ecryptfs_getxattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = ecryptfs_listxattr,
-	.removexattr = ecryptfs_removexattr
+	.removexattr = generic_removexattr
 };
 
 const struct inode_operations ecryptfs_main_iops = {
 	.permission = ecryptfs_permission,
 	.setattr = ecryptfs_setattr,
 	.getattr = ecryptfs_getattr,
-	.setxattr = ecryptfs_setxattr,
-	.getxattr = ecryptfs_getxattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
 	.listxattr = ecryptfs_listxattr,
-	.removexattr = ecryptfs_removexattr
+	.removexattr = generic_removexattr
+};
+
+static int ecryptfs_xattr_get(const struct xattr_handler *handler,
+			      struct dentry *dentry, struct inode *inode,
+			      const char *name, void *buffer, size_t size)
+{
+	return ecryptfs_getxattr(dentry, inode, name, buffer, size);
+}
+
+static int ecryptfs_xattr_set(const struct xattr_handler *handler,
+			      struct dentry *dentry, const char *name,
+			      const void *value, size_t size, int flags)
+{
+	if (value)
+		return ecryptfs_setxattr(dentry, name, value, size, flags);
+	else {
+		BUG_ON(flags != XATTR_REPLACE);
+		return ecryptfs_removexattr(dentry, name);
+	}
+}
+
+const struct xattr_handler ecryptfs_xattr_handler = {
+	.prefix = "",  /* match anything */
+	.get = ecryptfs_xattr_get,
+	.set = ecryptfs_xattr_set,
+};
+
+const struct xattr_handler *ecryptfs_xattr_handlers[] = {
+	&ecryptfs_xattr_handler,
+	NULL
 };
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 1698132..44ee3e2 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -529,6 +529,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 	/* ->kill_sb() will take care of sbi after that point */
 	sbi = NULL;
 	s->s_op = &ecryptfs_sops;
+	s->s_xattr = ecryptfs_xattr_handlers;
 	s->s_d_op = &ecryptfs_dops;
 
 	err = "Reading sb failed";
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 08/18] overlayfs: Switch to generic xattr handlers
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (6 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 07/18] ecryptfs: Switch to generic xattr handlers Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 09/18] fuse: " Andreas Gruenbacher
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/overlayfs/dir.c       |  6 +++---
 fs/overlayfs/inode.c     | 52 ++++++++++++++++++++++++++++++++++++++----------
 fs/overlayfs/overlayfs.h |  6 +-----
 fs/overlayfs/super.c     |  1 +
 4 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index b3fc0a3..16ba0f8 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -967,8 +967,8 @@ const struct inode_operations ovl_dir_inode_operations = {
 	.mknod		= ovl_mknod,
 	.permission	= ovl_permission,
 	.getattr	= ovl_dir_getattr,
-	.setxattr	= ovl_setxattr,
-	.getxattr	= ovl_getxattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= ovl_listxattr,
-	.removexattr	= ovl_removexattr,
+	.removexattr	= generic_removexattr,
 };
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index c7b31a0..d08c926 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -210,8 +210,8 @@ static bool ovl_is_private_xattr(const char *name)
 	return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
 }
 
-int ovl_setxattr(struct dentry *dentry, const char *name,
-		 const void *value, size_t size, int flags)
+static int ovl_setxattr(struct dentry *dentry, const char *name,
+			const void *value, size_t size, int flags)
 {
 	int err;
 	struct dentry *upperdentry;
@@ -246,8 +246,8 @@ static bool ovl_need_xattr_filter(struct dentry *dentry,
 		return false;
 }
 
-ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
-		     const char *name, void *value, size_t size)
+static ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
+			    const char *name, void *value, size_t size)
 {
 	struct path realpath;
 	enum ovl_path_type type = ovl_path_real(dentry, &realpath);
@@ -290,7 +290,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
 	return res;
 }
 
-int ovl_removexattr(struct dentry *dentry, const char *name)
+static int ovl_removexattr(struct dentry *dentry, const char *name)
 {
 	int err;
 	struct path realpath;
@@ -374,10 +374,10 @@ static const struct inode_operations ovl_file_inode_operations = {
 	.setattr	= ovl_setattr,
 	.permission	= ovl_permission,
 	.getattr	= ovl_getattr,
-	.setxattr	= ovl_setxattr,
-	.getxattr	= ovl_getxattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= ovl_listxattr,
-	.removexattr	= ovl_removexattr,
+	.removexattr	= generic_removexattr,
 };
 
 static const struct inode_operations ovl_symlink_inode_operations = {
@@ -385,10 +385,10 @@ static const struct inode_operations ovl_symlink_inode_operations = {
 	.get_link	= ovl_get_link,
 	.readlink	= ovl_readlink,
 	.getattr	= ovl_getattr,
-	.setxattr	= ovl_setxattr,
-	.getxattr	= ovl_getxattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= ovl_listxattr,
-	.removexattr	= ovl_removexattr,
+	.removexattr	= generic_removexattr,
 };
 
 struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
@@ -433,3 +433,33 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
 
 	return inode;
 }
+
+static int ovl_xattr_get(const struct xattr_handler *handler,
+			 struct dentry *dentry, struct inode *inode,
+			 const char *name, void *buffer, size_t size)
+{
+	return ovl_getxattr(dentry, inode, name, buffer, size);
+}
+
+static int ovl_xattr_set(const struct xattr_handler *handler,
+                             struct dentry *dentry, const char *name,
+                             const void *value, size_t size, int flags)
+{
+	if (value)
+		return ovl_setxattr(dentry, name, value, size, flags);
+	else {
+		BUG_ON(flags != XATTR_REPLACE);
+		return ovl_removexattr(dentry, name);
+	}
+}
+
+const struct xattr_handler ovl_xattr_handler = {
+	.prefix = "",  /* match anything */
+	.get = ovl_xattr_get,
+	.set = ovl_xattr_set,
+};
+
+const struct xattr_handler *ovl_xattr_handlers[] = {
+	&ovl_xattr_handler,
+	NULL
+};
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 99ec4b0..b7528e5 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -171,12 +171,7 @@ int ovl_check_d_type_supported(struct path *realpath);
 /* inode.c */
 int ovl_setattr(struct dentry *dentry, struct iattr *attr);
 int ovl_permission(struct inode *inode, int mask);
-int ovl_setxattr(struct dentry *dentry, const char *name,
-		 const void *value, size_t size, int flags);
-ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
-		     const char *name, void *value, size_t size);
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
-int ovl_removexattr(struct dentry *dentry, const char *name);
 struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
 
 struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
@@ -186,6 +181,7 @@ static inline void ovl_copyattr(struct inode *from, struct inode *to)
 	to->i_uid = from->i_uid;
 	to->i_gid = from->i_gid;
 }
+extern const struct xattr_handler *ovl_xattr_handlers[];
 
 /* dir.c */
 extern const struct inode_operations ovl_dir_inode_operations;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index ed53ae0..bb4fb00 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1137,6 +1137,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 
 	sb->s_magic = OVERLAYFS_SUPER_MAGIC;
 	sb->s_op = &ovl_super_operations;
+	sb->s_xattr = ovl_xattr_handlers;
 	sb->s_root = root_dentry;
 	sb->s_fs_info = ufs;
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 09/18] fuse: Switch to generic xattr handlers
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (7 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 08/18] overlayfs: " Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 10/18] evm: Turn evm_update_evmxattr into void function Andreas Gruenbacher
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/fuse/dir.c    | 49 ++++++++++++++++++++++++++++++++++++++++---------
 fs/fuse/fuse_i.h |  2 ++
 fs/fuse/inode.c  |  1 +
 3 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index b941905..6fe29b6 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/namei.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 
 static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
 {
@@ -1879,10 +1880,10 @@ static const struct inode_operations fuse_dir_inode_operations = {
 	.mknod		= fuse_mknod,
 	.permission	= fuse_permission,
 	.getattr	= fuse_getattr,
-	.setxattr	= fuse_setxattr,
-	.getxattr	= fuse_getxattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= fuse_listxattr,
-	.removexattr	= fuse_removexattr,
+	.removexattr	= generic_removexattr,
 };
 
 static const struct file_operations fuse_dir_operations = {
@@ -1900,10 +1901,10 @@ static const struct inode_operations fuse_common_inode_operations = {
 	.setattr	= fuse_setattr,
 	.permission	= fuse_permission,
 	.getattr	= fuse_getattr,
-	.setxattr	= fuse_setxattr,
-	.getxattr	= fuse_getxattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= fuse_listxattr,
-	.removexattr	= fuse_removexattr,
+	.removexattr	= generic_removexattr,
 };
 
 static const struct inode_operations fuse_symlink_inode_operations = {
@@ -1911,10 +1912,10 @@ static const struct inode_operations fuse_symlink_inode_operations = {
 	.get_link	= fuse_get_link,
 	.readlink	= generic_readlink,
 	.getattr	= fuse_getattr,
-	.setxattr	= fuse_setxattr,
-	.getxattr	= fuse_getxattr,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
 	.listxattr	= fuse_listxattr,
-	.removexattr	= fuse_removexattr,
+	.removexattr	= generic_removexattr,
 };
 
 void fuse_init_common(struct inode *inode)
@@ -1932,3 +1933,33 @@ void fuse_init_symlink(struct inode *inode)
 {
 	inode->i_op = &fuse_symlink_inode_operations;
 }
+
+static int fuse_xattr_get(const struct xattr_handler *handler,
+		          struct dentry *dentry, struct inode *inode,
+		          const char *name, void *buffer, size_t size)
+{
+       return fuse_getxattr(dentry, inode, name, buffer, size);
+}
+
+static int fuse_xattr_set(const struct xattr_handler *handler,
+		          struct dentry *dentry, const char *name,
+		          const void *value, size_t size, int flags)
+{
+       if (value)
+		return fuse_setxattr(dentry, name, value, size, flags);
+       else {
+		BUG_ON(flags != XATTR_REPLACE);
+		return fuse_removexattr(dentry, name);
+       }
+}
+
+const struct xattr_handler fuse_xattr_handler = {
+       .prefix = "",  /* match anything */
+       .get = fuse_xattr_get,
+       .set = fuse_xattr_set,
+};
+
+const struct xattr_handler *fuse_xattr_handlers[] = {
+       &fuse_xattr_handler,
+       NULL
+};
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index eddbe02..acf3481 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -956,4 +956,6 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
 
 void fuse_set_initialized(struct fuse_conn *fc);
 
+extern const struct xattr_handler *fuse_xattr_handlers[];
+
 #endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 1ce6766..0a6ec20 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1058,6 +1058,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 	}
 	sb->s_magic = FUSE_SUPER_MAGIC;
 	sb->s_op = &fuse_super_operations;
+	sb->s_xattr = fuse_xattr_handlers;
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	sb->s_time_gran = 1;
 	sb->s_export_op = &fuse_export_operations;
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 10/18] evm: Turn evm_update_evmxattr into void function
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (8 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 09/18] fuse: " Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-25  5:30   ` James Morris
  2016-05-20 11:14 ` [PATCH v2 11/18] vfs: Move xattr_resolve_name to the front of fs/xattr.c Andreas Gruenbacher
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

The return value of evm_update_evmxattr is never used.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 security/integrity/evm/evm.h        |  7 +++----
 security/integrity/evm/evm_crypto.c | 14 ++++++--------
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index f5f1272..8b1cef07 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -39,10 +39,9 @@ extern struct crypto_shash *hash_tfm;
 extern char *evm_config_xattrnames[];
 
 int evm_init_key(void);
-int evm_update_evmxattr(struct dentry *dentry,
-			const char *req_xattr_name,
-			const char *req_xattr_value,
-			size_t req_xattr_value_len);
+void evm_update_evmxattr(struct dentry *dentry, const char *req_xattr_name,
+			 const char *req_xattr_value,
+			 size_t req_xattr_value_len);
 int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value,
 		  size_t req_xattr_value_len, char *digest);
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 30b6b7d0..3ac6407 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -239,24 +239,22 @@ int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
  *
  * Expects to be called with i_mutex locked.
  */
-int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
-			const char *xattr_value, size_t xattr_value_len)
+void evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
+			 const char *xattr_value, size_t xattr_value_len)
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct evm_ima_xattr_data xattr_data;
-	int rc = 0;
+	int rc;
 
 	rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
 			   xattr_value_len, xattr_data.digest);
 	if (rc == 0) {
 		xattr_data.type = EVM_XATTR_HMAC;
-		rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
-					   &xattr_data,
-					   sizeof(xattr_data), 0);
+		__vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, &xattr_data,
+				      sizeof(xattr_data), 0);
 	} else if (rc == -ENODATA && inode->i_op->removexattr) {
-		rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
+		inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
 	}
-	return rc;
 }
 
 int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 11/18] vfs: Move xattr_resolve_name to the front of fs/xattr.c
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (9 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 10/18] evm: Turn evm_update_evmxattr into void function Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 12/18] vfs: Add IOP_XATTR inode operations flag Andreas Gruenbacher
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/xattr.c | 99 +++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 49 insertions(+), 50 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 2476acc..179dd03 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -24,6 +24,55 @@
 
 #include <asm/uaccess.h>
 
+static const char *
+strcmp_prefix(const char *a, const char *a_prefix)
+{
+	while (*a_prefix && *a == *a_prefix) {
+		a++;
+		a_prefix++;
+	}
+	return *a_prefix ? NULL : a;
+}
+
+/*
+ * In order to implement different sets of xattr operations for each xattr
+ * prefix with the generic xattr API, a filesystem should create a
+ * null-terminated array of struct xattr_handler (one for each prefix) and
+ * hang a pointer to it off of the s_xattr field of the superblock.
+ *
+ * The generic_fooxattr() functions will use this list to dispatch xattr
+ * operations to the correct xattr_handler.
+ */
+#define for_each_xattr_handler(handlers, handler)		\
+		for ((handler) = *(handlers)++;			\
+			(handler) != NULL;			\
+			(handler) = *(handlers)++)
+
+/*
+ * Find the xattr_handler with the matching prefix.
+ */
+static const struct xattr_handler *
+xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
+{
+	const struct xattr_handler *handler;
+
+	for_each_xattr_handler(handlers, handler) {
+		const char *n;
+
+		n = strcmp_prefix(*name, xattr_prefix(handler));
+		if (n) {
+			if (!handler->prefix ^ !*n) {
+				if (*n)
+					continue;
+				return ERR_PTR(-EINVAL);
+			}
+			*name = n;
+			return handler;
+		}
+	}
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
 /*
  * Check permissions for extended attribute access.  This is a bit complicated
  * because different namespaces have very different rules.
@@ -634,56 +683,6 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
 	return error;
 }
 
-
-static const char *
-strcmp_prefix(const char *a, const char *a_prefix)
-{
-	while (*a_prefix && *a == *a_prefix) {
-		a++;
-		a_prefix++;
-	}
-	return *a_prefix ? NULL : a;
-}
-
-/*
- * In order to implement different sets of xattr operations for each xattr
- * prefix with the generic xattr API, a filesystem should create a
- * null-terminated array of struct xattr_handler (one for each prefix) and
- * hang a pointer to it off of the s_xattr field of the superblock.
- *
- * The generic_fooxattr() functions will use this list to dispatch xattr
- * operations to the correct xattr_handler.
- */
-#define for_each_xattr_handler(handlers, handler)		\
-		for ((handler) = *(handlers)++;			\
-			(handler) != NULL;			\
-			(handler) = *(handlers)++)
-
-/*
- * Find the xattr_handler with the matching prefix.
- */
-static const struct xattr_handler *
-xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
-{
-	const struct xattr_handler *handler;
-
-	for_each_xattr_handler(handlers, handler) {
-		const char *n;
-
-		n = strcmp_prefix(*name, xattr_prefix(handler));
-		if (n) {
-			if (!handler->prefix ^ !*n) {
-				if (*n)
-					continue;
-				return ERR_PTR(-EINVAL);
-			}
-			*name = n;
-			return handler;
-		}
-	}
-	return ERR_PTR(-EOPNOTSUPP);
-}
-
 /*
  * Find the handler for the prefix and dispatch its get() operation.
  */
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 12/18] vfs: Add IOP_XATTR inode operations flag
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (10 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 11/18] vfs: Move xattr_resolve_name to the front of fs/xattr.c Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 13/18] vfs: Use IOP_XATTR flag for bad-inode handling Andreas Gruenbacher
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

The IOP_XATTR inode operations flag in inode->i_opflags indicates that
the inode has xattr support.  The flag is automatically set by
new_inode() on filesystems with xattr support (where sb->s_xattr is
defined), and cleared otherwise.  Filesystems can explicitly clear it
for inodes that should not have xattr support.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/inode.c         |  2 ++
 fs/xattr.c         | 12 ++++++++----
 include/linux/fs.h |  1 +
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/inode.c b/fs/inode.c
index 4ccbc21..aaad9b2 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -140,6 +140,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 	inode->i_fop = &no_open_fops;
 	inode->__i_nlink = 1;
 	inode->i_opflags = 0;
+	if (sb->s_xattr)
+		inode->i_opflags |= IOP_XATTR;
 	i_uid_write(inode, 0);
 	i_gid_write(inode, 0);
 	atomic_set(&inode->i_writecount, 0);
diff --git a/fs/xattr.c b/fs/xattr.c
index 179dd03..5a3b3e4 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -52,10 +52,13 @@ strcmp_prefix(const char *a, const char *a_prefix)
  * Find the xattr_handler with the matching prefix.
  */
 static const struct xattr_handler *
-xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
+xattr_resolve_name(struct inode *inode, const char **name)
 {
+	const struct xattr_handler **handlers = inode->i_sb->s_xattr;
 	const struct xattr_handler *handler;
 
+	if (!(inode->i_opflags & IOP_XATTR))
+		return ERR_PTR(-EOPNOTSUPP);
 	for_each_xattr_handler(handlers, handler) {
 		const char *n;
 
@@ -290,6 +293,7 @@ nolsm:
 		error = -EOPNOTSUPP;
 
 	return error;
+
 }
 EXPORT_SYMBOL_GPL(vfs_getxattr);
 
@@ -692,7 +696,7 @@ generic_getxattr(struct dentry *dentry, struct inode *inode,
 {
 	const struct xattr_handler *handler;
 
-	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
+	handler = xattr_resolve_name(inode, &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
 	return handler->get(handler, dentry, inode,
@@ -746,7 +750,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz
 
 	if (size == 0)
 		value = "";  /* empty EA, do not remove */
-	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
+	handler = xattr_resolve_name(d_inode(dentry), &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
 	return handler->set(handler, dentry, name, value, size, flags);
@@ -761,7 +765,7 @@ generic_removexattr(struct dentry *dentry, const char *name)
 {
 	const struct xattr_handler *handler;
 
-	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
+	handler = xattr_resolve_name(d_inode(dentry), &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
 	return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b0c2f76..e80594f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -594,6 +594,7 @@ is_uncached_acl(struct posix_acl *acl)
 #define IOP_FASTPERM	0x0001
 #define IOP_LOOKUP	0x0002
 #define IOP_NOFOLLOW	0x0004
+#define IOP_XATTR	0x0008
 
 /*
  * Keep mostly read-only and often accessed (especially for
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 13/18] vfs: Use IOP_XATTR flag for bad-inode handling
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (11 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 12/18] vfs: Add IOP_XATTR inode operations flag Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 14/18] libfs: Use IOP_XATTR flag for empty directory handling Andreas Gruenbacher
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

With this change, all the xattr handler based operations will produce an
-EIO result for bad inodes, and we no longer only depend on inode->i_op
to be set to bad_inode_ops.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/bad_inode.c | 21 +--------------------
 fs/xattr.c     |  8 +++++++-
 2 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 72e35b7..7bb153c 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -100,29 +100,12 @@ static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs)
 	return -EIO;
 }
 
-static int bad_inode_setxattr(struct dentry *dentry, const char *name,
-		const void *value, size_t size, int flags)
-{
-	return -EIO;
-}
-
-static ssize_t bad_inode_getxattr(struct dentry *dentry, struct inode *inode,
-			const char *name, void *buffer, size_t size)
-{
-	return -EIO;
-}
-
 static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer,
 			size_t buffer_size)
 {
 	return -EIO;
 }
 
-static int bad_inode_removexattr(struct dentry *dentry, const char *name)
-{
-	return -EIO;
-}
-
 static const struct inode_operations bad_inode_ops =
 {
 	.create		= bad_inode_create,
@@ -142,10 +125,7 @@ static const struct inode_operations bad_inode_ops =
 	.permission	= bad_inode_permission,
 	.getattr	= bad_inode_getattr,
 	.setattr	= bad_inode_setattr,
-	.setxattr	= bad_inode_setxattr,
-	.getxattr	= bad_inode_getxattr,
 	.listxattr	= bad_inode_listxattr,
-	.removexattr	= bad_inode_removexattr,
 };
 
 
@@ -175,6 +155,7 @@ void make_bad_inode(struct inode *inode)
 	inode->i_atime = inode->i_mtime = inode->i_ctime =
 		current_fs_time(inode->i_sb);
 	inode->i_op = &bad_inode_ops;	
+	inode->i_opflags &= ~IOP_XATTR;
 	inode->i_fop = &bad_file_ops;	
 }
 EXPORT_SYMBOL(make_bad_inode);
diff --git a/fs/xattr.c b/fs/xattr.c
index 5a3b3e4..ff151ff 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -57,8 +57,11 @@ xattr_resolve_name(struct inode *inode, const char **name)
 	const struct xattr_handler **handlers = inode->i_sb->s_xattr;
 	const struct xattr_handler *handler;
 
-	if (!(inode->i_opflags & IOP_XATTR))
+	if (!(inode->i_opflags & IOP_XATTR)) {
+		if (unlikely(is_bad_inode(inode)))
+			return ERR_PTR(-EIO);
 		return ERR_PTR(-EOPNOTSUPP);
+	}
 	for_each_xattr_handler(handlers, handler) {
 		const char *n;
 
@@ -160,6 +163,9 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
 		}
 	} else if (issec) {
 		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
+
+		if (unlikely(is_bad_inode(inode)))
+			return -EIO;
 		error = security_inode_setsecurity(inode, suffix, value,
 						   size, flags);
 		if (!error)
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 14/18] libfs: Use IOP_XATTR flag for empty directory handling
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (12 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 13/18] vfs: Use IOP_XATTR flag for bad-inode handling Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 15/18] xattr: Add __vfs_{get,set,remove}xattr helpers Andreas Gruenbacher
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Instead of special xattr inode operations, use the IOP_XATTR inode
operations flag for the special libfs empty directories.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/libfs.c | 21 +--------------------
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/fs/libfs.c b/fs/libfs.c
index 92215d5..06057e9 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1119,23 +1119,6 @@ static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
 	return -EPERM;
 }
 
-static int empty_dir_setxattr(struct dentry *dentry, const char *name,
-			      const void *value, size_t size, int flags)
-{
-	return -EOPNOTSUPP;
-}
-
-static ssize_t empty_dir_getxattr(struct dentry *dentry, struct inode *inode,
-				  const char *name, void *value, size_t size)
-{
-	return -EOPNOTSUPP;
-}
-
-static int empty_dir_removexattr(struct dentry *dentry, const char *name)
-{
-	return -EOPNOTSUPP;
-}
-
 static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size)
 {
 	return -EOPNOTSUPP;
@@ -1146,9 +1129,6 @@ static const struct inode_operations empty_dir_inode_operations = {
 	.permission	= generic_permission,
 	.setattr	= empty_dir_setattr,
 	.getattr	= empty_dir_getattr,
-	.setxattr	= empty_dir_setxattr,
-	.getxattr	= empty_dir_getxattr,
-	.removexattr	= empty_dir_removexattr,
 	.listxattr	= empty_dir_listxattr,
 };
 
@@ -1184,6 +1164,7 @@ void make_empty_dir_inode(struct inode *inode)
 	inode->i_blocks = 0;
 
 	inode->i_op = &empty_dir_inode_operations;
+	inode->i_opflags &= ~IOP_XATTR;
 	inode->i_fop = &empty_dir_operations;
 }
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 15/18] xattr: Add __vfs_{get,set,remove}xattr helpers
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (13 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 14/18] libfs: Use IOP_XATTR flag for empty directory handling Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-25  5:38   ` James Morris
  2016-05-20 11:14 ` [PATCH v2 16/18] vfs: Check for the IOP_XATTR flag in listxattr Andreas Gruenbacher
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

Right now, various places in the kernel check for the existence of
getxattr, setxattr, and removexattr inode operations and directly call
those operations.  Switch to helper functions and test for the IOP_XATTR
flag instead.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/cachefiles/bind.c                  |  4 +--
 fs/cachefiles/namei.c                 |  4 +--
 fs/ecryptfs/inode.c                   | 18 ++++++--------
 fs/ecryptfs/mmap.c                    | 11 ++++-----
 fs/overlayfs/copy_up.c                |  4 +--
 fs/overlayfs/super.c                  |  4 +--
 fs/xattr.c                            | 46 ++++++++++++++++++++++++++---------
 include/linux/xattr.h                 |  3 +++
 security/commoncap.c                  | 25 ++++++++-----------
 security/integrity/evm/evm_crypto.c   |  8 +++---
 security/integrity/evm/evm_main.c     |  4 +--
 security/integrity/ima/ima_appraise.c | 21 ++++++++--------
 security/selinux/hooks.c              | 19 ++++++---------
 security/smack/smack_lsm.c            | 12 ++++-----
 14 files changed, 98 insertions(+), 85 deletions(-)

diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
index 6af790f..3ff867f 100644
--- a/fs/cachefiles/bind.c
+++ b/fs/cachefiles/bind.c
@@ -20,6 +20,7 @@
 #include <linux/mount.h>
 #include <linux/statfs.h>
 #include <linux/ctype.h>
+#include <linux/xattr.h>
 #include "internal.h"
 
 static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches);
@@ -126,8 +127,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
 	if (d_is_negative(root) ||
 	    !d_backing_inode(root)->i_op->lookup ||
 	    !d_backing_inode(root)->i_op->mkdir ||
-	    !d_backing_inode(root)->i_op->setxattr ||
-	    !d_backing_inode(root)->i_op->getxattr ||
+	    !(d_backing_inode(root)->i_opflags & IOP_XATTR) ||
 	    !root->d_sb->s_op->statfs ||
 	    !root->d_sb->s_op->sync_fs)
 		goto error_unsupported;
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 4ae7500..0d8ca89 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -20,6 +20,7 @@
 #include <linux/namei.h>
 #include <linux/security.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 #include "internal.h"
 
 #define CACHEFILES_KEYBUF_SIZE 512
@@ -798,8 +799,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
 	}
 
 	ret = -EPERM;
-	if (!d_backing_inode(subdir)->i_op->setxattr ||
-	    !d_backing_inode(subdir)->i_op->getxattr ||
+	if (!(d_backing_inode(subdir)->i_opflags & IOP_XATTR) ||
 	    !d_backing_inode(subdir)->i_op->lookup ||
 	    !d_backing_inode(subdir)->i_op->mkdir ||
 	    !d_backing_inode(subdir)->i_op->create ||
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 4129233..f283fa6 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -1004,15 +1004,14 @@ int
 ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 		  size_t size, int flags)
 {
-	int rc = 0;
+	int rc;
 	struct dentry *lower_dentry;
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
-	if (!d_inode(lower_dentry)->i_op->setxattr) {
+	if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) {
 		rc = -EOPNOTSUPP;
 		goto out;
 	}
-
 	rc = vfs_setxattr(lower_dentry, name, value, size, flags);
 	if (!rc && d_really_is_positive(dentry))
 		fsstack_copy_attr_all(d_inode(dentry), d_inode(lower_dentry));
@@ -1024,15 +1023,14 @@ ssize_t
 ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
 			const char *name, void *value, size_t size)
 {
-	int rc = 0;
+	int rc;
 
-	if (!lower_inode->i_op->getxattr) {
+	if (!(lower_inode->i_opflags & IOP_XATTR)) {
 		rc = -EOPNOTSUPP;
 		goto out;
 	}
 	inode_lock(lower_inode);
-	rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
-					 name, value, size);
+	rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size);
 	inode_unlock(lower_inode);
 out:
 	return rc;
@@ -1067,16 +1065,16 @@ out:
 
 static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
 {
-	int rc = 0;
+	int rc;
 	struct dentry *lower_dentry;
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
-	if (!d_inode(lower_dentry)->i_op->removexattr) {
+	if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) {
 		rc = -EOPNOTSUPP;
 		goto out;
 	}
 	inode_lock(d_inode(lower_dentry));
-	rc = d_inode(lower_dentry)->i_op->removexattr(lower_dentry, name);
+	rc = __vfs_removexattr(lower_dentry, name);
 	inode_unlock(d_inode(lower_dentry));
 out:
 	return rc;
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 148d11b..e08154a 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -32,6 +32,7 @@
 #include <linux/file.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -422,7 +423,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
 	struct inode *lower_inode = d_inode(lower_dentry);
 	int rc;
 
-	if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) {
+	if (!(lower_inode->i_opflags & IOP_XATTR)) {
 		printk(KERN_WARNING
 		       "No support for setting xattr in lower filesystem\n");
 		rc = -ENOSYS;
@@ -436,14 +437,12 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
 		goto out;
 	}
 	inode_lock(lower_inode);
-	size = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
-					   ECRYPTFS_XATTR_NAME,
-					   xattr_virt, PAGE_SIZE);
+	size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
+			      xattr_virt, PAGE_SIZE);
 	if (size < 0)
 		size = 8;
 	put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
-	rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
-					 xattr_virt, size, 0);
+	rc = __vfs_setxattr(lower_dentry, ECRYPTFS_XATTR_NAME, xattr_virt, size, 0);
 	inode_unlock(lower_inode);
 	if (rc)
 		printk(KERN_ERR "Error whilst attempting to write inode size "
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index cc514da..4e43569 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -58,8 +58,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
 	char *buf, *name, *value = NULL;
 	int uninitialized_var(error);
 
-	if (!old->d_inode->i_op->getxattr ||
-	    !new->d_inode->i_op->getxattr)
+	if (!(old->d_inode->i_opflags & IOP_XATTR) ||
+	    !(new->d_inode->i_opflags & IOP_XATTR))
 		return 0;
 
 	list_size = vfs_listxattr(old, NULL, 0);
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index bb4fb00..2b3f448 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -271,10 +271,10 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
 	char val;
 	struct inode *inode = dentry->d_inode;
 
-	if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr)
+	if (!S_ISDIR(inode->i_mode) || !(inode->i_opflags & IOP_XATTR))
 		return false;
 
-	res = inode->i_op->getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1);
+	res = __vfs_getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1);
 	if (res == 1 && val == 'y')
 		return true;
 
diff --git a/fs/xattr.c b/fs/xattr.c
index ff151ff..5579ace 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -128,6 +128,18 @@ xattr_permission(struct inode *inode, const char *name, int mask)
 	return inode_permission(inode, mask);
 }
 
+int
+__vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+	       size_t size, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+
+	if (!inode->i_op->setxattr)
+		return -EOPNOTSUPP;
+	return inode->i_op->setxattr(dentry, name, value, size, flags);
+}
+EXPORT_SYMBOL(__vfs_setxattr);
+
 /**
  *  __vfs_setxattr_noperm - perform setxattr operation without performing
  *  permission checks.
@@ -155,7 +167,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
 	if (issec)
 		inode->i_flags &= ~S_NOSEC;
 	if (inode->i_op->setxattr) {
-		error = inode->i_op->setxattr(dentry, name, value, size, flags);
+		error = __vfs_setxattr(dentry, name, value, size, flags);
 		if (!error) {
 			fsnotify_xattr(dentry);
 			security_inode_post_setxattr(dentry, name, value,
@@ -267,6 +279,16 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
 }
 
 ssize_t
+__vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
+	       void *value, size_t size)
+{
+	if (!inode->i_op->getxattr)
+		return -EOPNOTSUPP;
+	return inode->i_op->getxattr(dentry, inode, name, value, size);
+}
+EXPORT_SYMBOL(__vfs_getxattr);
+
+ssize_t
 vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
 {
 	struct inode *inode = dentry->d_inode;
@@ -293,13 +315,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
 		return ret;
 	}
 nolsm:
-	if (inode->i_op->getxattr)
-		error = inode->i_op->getxattr(dentry, inode, name, value, size);
-	else
-		error = -EOPNOTSUPP;
-
-	return error;
-
+	return __vfs_getxattr(dentry, inode, name, value, size);
 }
 EXPORT_SYMBOL_GPL(vfs_getxattr);
 
@@ -324,13 +340,21 @@ vfs_listxattr(struct dentry *d, char *list, size_t size)
 EXPORT_SYMBOL_GPL(vfs_listxattr);
 
 int
-vfs_removexattr(struct dentry *dentry, const char *name)
+__vfs_removexattr(struct dentry *dentry, const char *name)
 {
 	struct inode *inode = dentry->d_inode;
-	int error;
 
 	if (!inode->i_op->removexattr)
 		return -EOPNOTSUPP;
+	return inode->i_op->removexattr(dentry, name);
+}
+EXPORT_SYMBOL(__vfs_removexattr);
+
+int
+vfs_removexattr(struct dentry *dentry, const char *name)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
 
 	error = xattr_permission(inode, name, MAY_WRITE);
 	if (error)
@@ -341,7 +365,7 @@ vfs_removexattr(struct dentry *dentry, const char *name)
 	if (error)
 		goto out;
 
-	error = inode->i_op->removexattr(dentry, name);
+	error = __vfs_removexattr(dentry, name);
 
 	if (!error) {
 		fsnotify_xattr(dentry);
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 1cc4c57..59271a4 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -46,10 +46,13 @@ struct xattr {
 };
 
 ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
+ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
 ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
 ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
+int __vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
 int __vfs_setxattr_noperm(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, struct inode *inode, const char *name, void *buffer, size_t size);
diff --git a/security/commoncap.c b/security/commoncap.c
index e7fadde..b878d77 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -310,13 +310,8 @@ int cap_inode_need_killpriv(struct dentry *dentry)
 	struct inode *inode = d_backing_inode(dentry);
 	int error;
 
-	if (!inode->i_op->getxattr)
-	       return 0;
-
-	error = inode->i_op->getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
-	if (error <= 0)
-		return 0;
-	return 1;
+	error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
+	return error > 0;
 }
 
 /**
@@ -329,12 +324,12 @@ int cap_inode_need_killpriv(struct dentry *dentry)
  */
 int cap_inode_killpriv(struct dentry *dentry)
 {
-	struct inode *inode = d_backing_inode(dentry);
-
-	if (!inode->i_op->removexattr)
-	       return 0;
+	int error;
 
-	return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS);
+	error = __vfs_removexattr(dentry, XATTR_NAME_CAPS);
+	if (error == -EOPNOTSUPP)
+		error = 0;
+	return error;
 }
 
 /*
@@ -394,11 +389,11 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
 
 	memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
 
-	if (!inode || !inode->i_op->getxattr)
+	if (!inode)
 		return -ENODATA;
 
-	size = inode->i_op->getxattr((struct dentry *)dentry, inode,
-				     XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ);
+	size = __vfs_getxattr((struct dentry *)dentry, inode,
+			      XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ);
 	if (size == -ENODATA || size == -EOPNOTSUPP)
 		/* no data, that's ok */
 		return -ENODATA;
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 3ac6407..a9cbeb6 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -182,8 +182,9 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
 	int error;
 	int size;
 
-	if (!inode->i_op->getxattr)
+	if (!(inode->i_opflags & IOP_XATTR))
 		return -EOPNOTSUPP;
+
 	desc = init_desc(type);
 	if (IS_ERR(desc))
 		return PTR_ERR(desc);
@@ -242,7 +243,6 @@ int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
 void evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 			 const char *xattr_value, size_t xattr_value_len)
 {
-	struct inode *inode = d_backing_inode(dentry);
 	struct evm_ima_xattr_data xattr_data;
 	int rc;
 
@@ -252,8 +252,8 @@ void evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 		xattr_data.type = EVM_XATTR_HMAC;
 		__vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, &xattr_data,
 				      sizeof(xattr_data), 0);
-	} else if (rc == -ENODATA && inode->i_op->removexattr) {
-		inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
+	} else if (rc == -ENODATA) {
+		__vfs_removexattr(dentry, XATTR_NAME_EVM);
 	}
 }
 
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index b9e2628..ba86155 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -78,11 +78,11 @@ static int evm_find_protected_xattrs(struct dentry *dentry)
 	int error;
 	int count = 0;
 
-	if (!inode->i_op->getxattr)
+	if (!(inode->i_opflags & IOP_XATTR))
 		return -EOPNOTSUPP;
 
 	for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
-		error = inode->i_op->getxattr(dentry, inode, *xattr, NULL, 0);
+		error = __vfs_getxattr(dentry, inode, *xattr, NULL, 0);
 		if (error < 0) {
 			if (error == -ENODATA)
 				continue;
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 1bcbc12..6886f68 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -165,13 +165,13 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
 int ima_read_xattr(struct dentry *dentry,
 		   struct evm_ima_xattr_data **xattr_value)
 {
-	struct inode *inode = d_backing_inode(dentry);
-
-	if (!inode->i_op->getxattr)
-		return 0;
+	ssize_t ret;
 
-	return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
-				  0, GFP_NOFS);
+	ret = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
+				 0, GFP_NOFS);
+	if (ret == -EOPNOTSUPP)
+		ret = 0;
+	return ret;
 }
 
 /*
@@ -195,7 +195,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 	enum integrity_status status = INTEGRITY_UNKNOWN;
 	int rc = xattr_len, hash_start = 0;
 
-	if (!inode->i_op->getxattr)
+	if (!(inode->i_opflags & IOP_XATTR))
 		return INTEGRITY_UNKNOWN;
 
 	if (rc <= 0) {
@@ -322,10 +322,10 @@ void ima_inode_post_setattr(struct dentry *dentry)
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct integrity_iint_cache *iint;
-	int must_appraise, rc;
+	int must_appraise;
 
 	if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode)
-	    || !inode->i_op->removexattr)
+	    || !(inode->i_opflags & IOP_XATTR))
 		return;
 
 	must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
@@ -338,8 +338,7 @@ void ima_inode_post_setattr(struct dentry *dentry)
 			iint->flags |= IMA_APPRAISE;
 	}
 	if (!must_appraise)
-		rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);
-	return;
+		__vfs_removexattr(dentry, XATTR_NAME_IMA);
 }
 
 /*
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a86d537..f11b444 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -507,14 +507,14 @@ static int sb_finish_set_opts(struct super_block *sb)
 		   the root directory.  -ENODATA is ok, as this may be
 		   the first boot of the SELinux kernel before we have
 		   assigned xattr values to the filesystem. */
-		if (!root_inode->i_op->getxattr) {
+		if (!(root_inode->i_opflags & IOP_XATTR)) {
 			printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
 			       "xattr support\n", sb->s_id, sb->s_type->name);
 			rc = -EOPNOTSUPP;
 			goto out;
 		}
-		rc = root_inode->i_op->getxattr(root, root_inode,
-						XATTR_NAME_SELINUX, NULL, 0);
+
+		rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
 		if (rc < 0 && rc != -ENODATA) {
 			if (rc == -EOPNOTSUPP)
 				printk(KERN_WARNING "SELinux: (dev %s, type "
@@ -1387,11 +1387,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
 	case SECURITY_FS_USE_NATIVE:
 		break;
 	case SECURITY_FS_USE_XATTR:
-		if (!inode->i_op->getxattr) {
+		if (!(inode->i_opflags & IOP_XATTR)) {
 			isec->sid = sbsec->def_sid;
 			break;
 		}
-
 		/* Need a dentry, since the xattr API requires one.
 		   Life would be simpler if we could just pass the inode. */
 		if (opt_dentry) {
@@ -1422,14 +1421,12 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
 			goto out_unlock;
 		}
 		context[len] = '\0';
-		rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX,
-					   context, len);
+		rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
 		if (rc == -ERANGE) {
 			kfree(context);
 
 			/* Need a larger buffer.  Query for the right size. */
-			rc = inode->i_op->getxattr(dentry, inode, XATTR_NAME_SELINUX,
-						   NULL, 0);
+			rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
 			if (rc < 0) {
 				dput(dentry);
 				goto out_unlock;
@@ -1442,9 +1439,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
 				goto out_unlock;
 			}
 			context[len] = '\0';
-			rc = inode->i_op->getxattr(dentry, inode,
-						   XATTR_NAME_SELINUX,
-						   context, len);
+			rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
 		}
 		dput(dentry);
 		if (rc < 0) {
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ff2b8c3..472985d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -265,14 +265,14 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
 	char *buffer;
 	struct smack_known *skp = NULL;
 
-	if (ip->i_op->getxattr == NULL)
+	if (!(ip->i_opflags & IOP_XATTR))
 		return ERR_PTR(-EOPNOTSUPP);
 
 	buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL);
 	if (buffer == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	rc = ip->i_op->getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
+	rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
 	if (rc < 0)
 		skp = ERR_PTR(rc);
 	else if (rc == 0)
@@ -3489,8 +3489,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
 		 * It would be curious if the label of the task
 		 * does not match that assigned.
 		 */
-		if (inode->i_op->getxattr == NULL)
-			break;
+		if (!(inode->i_opflags & IOP_XATTR))
+		        break;
 		/*
 		 * Get the dentry for xattr.
 		 */
@@ -3514,12 +3514,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
 			 */
 			if (isp->smk_flags & SMK_INODE_CHANGED) {
 				isp->smk_flags &= ~SMK_INODE_CHANGED;
-				rc = inode->i_op->setxattr(dp,
+				rc = __vfs_setxattr(dp,
 					XATTR_NAME_SMACKTRANSMUTE,
 					TRANS_TRUE, TRANS_TRUE_SIZE,
 					0);
 			} else {
-				rc = inode->i_op->getxattr(dp, inode,
+				rc = __vfs_getxattr(dp, inode,
 					XATTR_NAME_SMACKTRANSMUTE, trattr,
 					TRANS_TRUE_SIZE);
 				if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 16/18] vfs: Check for the IOP_XATTR flag in listxattr
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (14 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 15/18] xattr: Add __vfs_{get,set,remove}xattr helpers Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 17/18] xattr: Stop calling {get,set,remove}xattr inode operations Andreas Gruenbacher
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

When an inode doesn't support xattrs, turn listxattr off as well.

(When xattrs are "turned off", the VFS still passes security xattr
operations through to security modules, which can still expose inode
security labels that way.)

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/xattr.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 5579ace..e9fc705 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -320,18 +320,19 @@ nolsm:
 EXPORT_SYMBOL_GPL(vfs_getxattr);
 
 ssize_t
-vfs_listxattr(struct dentry *d, char *list, size_t size)
+vfs_listxattr(struct dentry *dentry, char *list, size_t size)
 {
+	struct inode *inode = d_inode(dentry);
 	ssize_t error;
 
-	error = security_inode_listxattr(d);
+	error = security_inode_listxattr(dentry);
 	if (error)
 		return error;
-	error = -EOPNOTSUPP;
-	if (d->d_inode->i_op->listxattr) {
-		error = d->d_inode->i_op->listxattr(d, list, size);
+	if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
+		error = -EOPNOTSUPP;
+		error = inode->i_op->listxattr(dentry, list, size);
 	} else {
-		error = security_inode_listsecurity(d->d_inode, list, size);
+		error = security_inode_listsecurity(inode, list, size);
 		if (size && error > size)
 			error = -ERANGE;
 	}
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 17/18] xattr: Stop calling {get,set,remove}xattr inode operations
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (15 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 16/18] vfs: Check for the IOP_XATTR flag in listxattr Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-20 11:14 ` [PATCH v2 18/18] vfs: Remove " Andreas Gruenbacher
  2016-05-26 19:39 ` [PATCH v2 00/18] Xattr inode operation removal Carlos Maiolino
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

All filesystems that support xattrs by now do so via xattr handlers.
They all define sb->s_xattr, and their getxattr, setxattr, and
removexattr inode operations use the generic inode operations.  On
filesystems that don't support xattrs, the xattr inode operations are
all NULL, and sb->s_xattr is also NULL.

This means that we can remove the getxattr, setxattr, and removexattr
inode operations and directly call the generic handlers, or better,
inline expand those handlers into fs/xattr.c.

Filesystems that do not support xattrs on some inodes should clear the
IOP_XATTR i_opflags flag in those inodes.  (Right now, some filesystems
have checks to disable xattrs on some inodes in the ->list, ->get, and
->set xattr handler operations instead.)  The IOP_XATTR flag is
automatically cleared in inodes of filesystems that don't have xattr
support.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 Documentation/filesystems/Locking | 24 +++++++++++++-----
 Documentation/filesystems/vfs.txt | 45 ++++++++++++++++++++++------------
 fs/xattr.c                        | 51 ++++++++++++++++++++++++---------------
 3 files changed, 80 insertions(+), 40 deletions(-)

diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 75eea7c..9cb941e 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -56,10 +56,7 @@ prototypes:
 	int (*get_acl)(struct inode *, int);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
-	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
-	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
-	int (*removexattr) (struct dentry *, const char *);
 	int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
 	void (*update_time)(struct inode *, struct timespec *, int);
 	int (*atomic_open)(struct inode *, struct dentry *,
@@ -87,16 +84,14 @@ setattr:	yes
 permission:	no (may not block if called in rcu-walk mode)
 get_acl:	no
 getattr:	no
-setxattr:	yes
-getxattr:	no
 listxattr:	no
-removexattr:	yes
 fiemap:		no
 update_time:	no
 atomic_open:	yes
 tmpfile:	no
 dentry_open:	no
 
+
 	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
 victim.
 	cross-directory ->rename() and rename2() has (per-superblock)
@@ -105,6 +100,23 @@ victim.
 See Documentation/filesystems/directory-locking for more detailed discussion
 of the locking scheme for directory operations.
 
+----------------------- xattr_handler operations -----------------------
+protoypes:
+	bool (*list)(struct dentry *dentry);
+	int (*get)(const struct xattr_handler *handler, struct dentry *dentry,
+		   struct inode *inode, const char *name, void *buffer,
+		   size_t size);
+	int (*set)(const struct xattr_handler *handler, struct dentry *dentry,
+		   const char *name, const void *buffer, size_t size,
+		   int flags);
+
+locking rules:
+	all may block
+		i_mutex(inode)
+list:		no
+get:		no
+set:		yes
+
 --------------------------- super_operations ---------------------------
 prototypes:
 	struct inode *(*alloc_inode)(struct super_block *sb);
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index c61a223..65988f7 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -323,6 +323,35 @@ Whoever sets up the inode is responsible for filling in the "i_op" field. This
 is a pointer to a "struct inode_operations" which describes the methods that
 can be performed on individual inodes.
 
+struct xattr_handlers
+---------------------
+
+On filesystems that support extended attributes (xattrs), the s_xattr
+superblock field points to a NULL-terminated array of xattr handlers.  Extended
+attributes are name:value pairs.
+
+  name: Indicates that the handler matches attributes with the specified name
+	(such as "system.posix_acl_access"); the prefix field must be NULL.
+
+  prefix: Indicates that the handler matches all attributes with the specified
+	name prefix (such as "user."); the name field must be NULL.
+
+  list: Determine if attributes matching this xattr handler should be listed
+	for a particular dentry.  Used by some listxattr implementations like
+	generic_listxattr.
+
+  get: Called by the VFS to get the value of a particular extended attribute.
+	This method is called by the getxattr(2) system call.
+
+  set: Called by the VFS to set the value of a particular extended attribute.
+	When the new value is NULL, called to remove a particular extended
+	attribute.  This method is called by the the setxattr(2) and
+	removexattr(2) system calls.
+
+When none of the xattr handlers of a filesystem match the specified attribute
+name or when a filesystem doesn't support extended attributes, the various
+*xattr(2) system calls return -EOPNOTSUPP.
+
 
 The Inode Object
 ================
@@ -356,10 +385,7 @@ struct inode_operations {
 	int (*get_acl)(struct inode *, int);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
-	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
-	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
-	int (*removexattr) (struct dentry *, const char *);
 	void (*update_time)(struct inode *, struct timespec *, int);
 	int (*atomic_open)(struct inode *, struct dentry *, struct file *,
 			unsigned open_flag, umode_t create_mode, int *opened);
@@ -464,19 +490,8 @@ otherwise noted.
   getattr: called by the VFS to get attributes of a file. This method
   	is called by stat(2) and related system calls.
 
-  setxattr: called by the VFS to set an extended attribute for a file.
-  	Extended attribute is a name:value pair associated with an
-  	inode. This method is called by setxattr(2) system call.
-
-  getxattr: called by the VFS to retrieve the value of an extended
-  	attribute name. This method is called by getxattr(2) function
-  	call.
-
   listxattr: called by the VFS to list all extended attributes for a
-  	given file. This method is called by listxattr(2) system call.
-
-  removexattr: called by the VFS to remove an extended attribute from
-  	a file. This method is called by removexattr(2) system call.
+	given file. This method is called by the listxattr(2) system call.
 
   update_time: called by the VFS to update a specific time or the i_version of
   	an inode.  If this is not defined the VFS will update the inode itself
diff --git a/fs/xattr.c b/fs/xattr.c
index e9fc705..f70917b 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -36,12 +36,9 @@ strcmp_prefix(const char *a, const char *a_prefix)
 
 /*
  * In order to implement different sets of xattr operations for each xattr
- * prefix with the generic xattr API, a filesystem should create a
- * null-terminated array of struct xattr_handler (one for each prefix) and
- * hang a pointer to it off of the s_xattr field of the superblock.
- *
- * The generic_fooxattr() functions will use this list to dispatch xattr
- * operations to the correct xattr_handler.
+ * prefix, a filesystem should create a null-terminated array of struct
+ * xattr_handler (one for each prefix) and hang a pointer to it off of the
+ * s_xattr field of the superblock.
  */
 #define for_each_xattr_handler(handlers, handler)		\
 		for ((handler) = *(handlers)++;			\
@@ -132,11 +129,16 @@ int
 __vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 	       size_t size, int flags)
 {
-	struct inode *inode = dentry->d_inode;
+	const struct xattr_handler *handler;
 
-	if (!inode->i_op->setxattr)
+	handler = xattr_resolve_name(d_inode(dentry), &name);
+	if (IS_ERR(handler))
+		return PTR_ERR(handler);
+	if (!handler->set)
 		return -EOPNOTSUPP;
-	return inode->i_op->setxattr(dentry, name, value, size, flags);
+	if (size == 0)
+		value = "";  /* empty EA, do not remove */
+	return handler->set(handler, dentry, name, value, size, flags);
 }
 EXPORT_SYMBOL(__vfs_setxattr);
 
@@ -166,7 +168,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
 
 	if (issec)
 		inode->i_flags &= ~S_NOSEC;
-	if (inode->i_op->setxattr) {
+	if (inode->i_opflags & IOP_XATTR) {
 		error = __vfs_setxattr(dentry, name, value, size, flags);
 		if (!error) {
 			fsnotify_xattr(dentry);
@@ -251,6 +253,7 @@ ssize_t
 vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
 		   size_t xattr_size, gfp_t flags)
 {
+	const struct xattr_handler *handler;
 	struct inode *inode = dentry->d_inode;
 	char *value = *xattr_value;
 	int error;
@@ -259,10 +262,12 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
 	if (error)
 		return error;
 
-	if (!inode->i_op->getxattr)
+	handler = xattr_resolve_name(inode, &name);
+	if (IS_ERR(handler))
+		return PTR_ERR(handler);
+	if (!handler->get)
 		return -EOPNOTSUPP;
-
-	error = inode->i_op->getxattr(dentry, inode, name, NULL, 0);
+	error = handler->get(handler, dentry, inode, name, NULL, 0);
 	if (error < 0)
 		return error;
 
@@ -273,7 +278,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
 		memset(value, 0, error + 1);
 	}
 
-	error = inode->i_op->getxattr(dentry, inode, name, value, error);
+	error = handler->get(handler, dentry, inode, name, value, error);
 	*xattr_value = value;
 	return error;
 }
@@ -282,9 +287,14 @@ ssize_t
 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
 	       void *value, size_t size)
 {
-	if (!inode->i_op->getxattr)
+	const struct xattr_handler *handler;
+
+	handler = xattr_resolve_name(inode, &name);
+	if (IS_ERR(handler))
+		return PTR_ERR(handler);
+	if (!handler->get)
 		return -EOPNOTSUPP;
-	return inode->i_op->getxattr(dentry, inode, name, value, size);
+	return handler->get(handler, dentry, inode, name, value, size);
 }
 EXPORT_SYMBOL(__vfs_getxattr);
 
@@ -343,11 +353,14 @@ EXPORT_SYMBOL_GPL(vfs_listxattr);
 int
 __vfs_removexattr(struct dentry *dentry, const char *name)
 {
-	struct inode *inode = dentry->d_inode;
+	const struct xattr_handler *handler;
 
-	if (!inode->i_op->removexattr)
+	handler = xattr_resolve_name(d_inode(dentry), &name);
+	if (IS_ERR(handler))
+		return PTR_ERR(handler);
+	if (!handler->set)
 		return -EOPNOTSUPP;
-	return inode->i_op->removexattr(dentry, name);
+	return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
 }
 EXPORT_SYMBOL(__vfs_removexattr);
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 18/18] vfs: Remove {get,set,remove}xattr inode operations
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (16 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 17/18] xattr: Stop calling {get,set,remove}xattr inode operations Andreas Gruenbacher
@ 2016-05-20 11:14 ` Andreas Gruenbacher
  2016-05-26 19:39 ` [PATCH v2 00/18] Xattr inode operation removal Carlos Maiolino
  18 siblings, 0 replies; 24+ messages in thread
From: Andreas Gruenbacher @ 2016-05-20 11:14 UTC (permalink / raw)
  To: Alexander Viro
  Cc: Andreas Gruenbacher, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

These inode operations are no longer used; remove them.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/9p/vfs_inode_dotl.c |  9 ---------
 fs/btrfs/inode.c       | 12 ------------
 fs/ceph/dir.c          |  3 ---
 fs/ceph/inode.c        |  6 ------
 fs/cifs/cifsfs.c       |  9 ---------
 fs/ecryptfs/inode.c    |  9 ---------
 fs/ext2/file.c         |  3 ---
 fs/ext2/namei.c        |  6 ------
 fs/ext2/symlink.c      |  6 ------
 fs/ext4/file.c         |  3 ---
 fs/ext4/namei.c        |  6 ------
 fs/ext4/symlink.c      |  9 ---------
 fs/f2fs/file.c         |  3 ---
 fs/f2fs/namei.c        | 12 ------------
 fs/fuse/dir.c          |  9 ---------
 fs/gfs2/inode.c        |  9 ---------
 fs/hfs/inode.c         |  2 --
 fs/hfsplus/dir.c       |  3 ---
 fs/hfsplus/inode.c     |  3 ---
 fs/jffs2/dir.c         |  3 ---
 fs/jffs2/file.c        |  3 ---
 fs/jffs2/symlink.c     |  3 ---
 fs/jfs/file.c          |  3 ---
 fs/jfs/namei.c         |  3 ---
 fs/jfs/symlink.c       |  6 ------
 fs/kernfs/dir.c        |  3 ---
 fs/kernfs/inode.c      |  3 ---
 fs/kernfs/symlink.c    |  3 ---
 fs/nfs/nfs3proc.c      |  6 ------
 fs/nfs/nfs4proc.c      |  6 ------
 fs/ocfs2/file.c        |  3 ---
 fs/ocfs2/namei.c       |  3 ---
 fs/ocfs2/symlink.c     |  3 ---
 fs/orangefs/inode.c    |  3 ---
 fs/orangefs/namei.c    |  3 ---
 fs/orangefs/symlink.c  |  1 -
 fs/overlayfs/dir.c     |  3 ---
 fs/overlayfs/inode.c   |  6 ------
 fs/reiserfs/file.c     |  3 ---
 fs/reiserfs/namei.c    |  9 ---------
 fs/squashfs/inode.c    |  1 -
 fs/squashfs/namei.c    |  1 -
 fs/squashfs/symlink.c  |  1 -
 fs/squashfs/xattr.h    |  1 -
 fs/ubifs/dir.c         |  3 ---
 fs/ubifs/file.c        |  6 ------
 fs/xattr.c             | 51 --------------------------------------------------
 fs/xfs/xfs_iops.c      | 12 ------------
 include/linux/fs.h     |  4 ----
 include/linux/xattr.h  |  3 ---
 mm/shmem.c             | 15 ---------------
 net/socket.c           |  1 -
 52 files changed, 300 deletions(-)

diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index a34702c..f0f36b8 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -973,9 +973,6 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = {
 	.rename = v9fs_vfs_rename,
 	.getattr = v9fs_vfs_getattr_dotl,
 	.setattr = v9fs_vfs_setattr_dotl,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
-	.removexattr = generic_removexattr,
 	.listxattr = v9fs_listxattr,
 	.get_acl = v9fs_iop_get_acl,
 };
@@ -983,9 +980,6 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = {
 const struct inode_operations v9fs_file_inode_operations_dotl = {
 	.getattr = v9fs_vfs_getattr_dotl,
 	.setattr = v9fs_vfs_setattr_dotl,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
-	.removexattr = generic_removexattr,
 	.listxattr = v9fs_listxattr,
 	.get_acl = v9fs_iop_get_acl,
 };
@@ -995,8 +989,5 @@ const struct inode_operations v9fs_symlink_inode_operations_dotl = {
 	.get_link = v9fs_vfs_get_link_dotl,
 	.getattr = v9fs_vfs_getattr_dotl,
 	.setattr = v9fs_vfs_setattr_dotl,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
-	.removexattr = generic_removexattr,
 	.listxattr = v9fs_listxattr,
 };
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 6b7fe29..cef1b57 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -10160,10 +10160,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
 	.symlink	= btrfs_symlink,
 	.setattr	= btrfs_setattr,
 	.mknod		= btrfs_mknod,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= btrfs_listxattr,
-	.removexattr	= generic_removexattr,
 	.permission	= btrfs_permission,
 	.get_acl	= btrfs_get_acl,
 	.set_acl	= btrfs_set_acl,
@@ -10237,10 +10234,7 @@ static const struct address_space_operations btrfs_symlink_aops = {
 static const struct inode_operations btrfs_file_inode_operations = {
 	.getattr	= btrfs_getattr,
 	.setattr	= btrfs_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr      = btrfs_listxattr,
-	.removexattr	= generic_removexattr,
 	.permission	= btrfs_permission,
 	.fiemap		= btrfs_fiemap,
 	.get_acl	= btrfs_get_acl,
@@ -10251,10 +10245,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
 	.getattr	= btrfs_getattr,
 	.setattr	= btrfs_setattr,
 	.permission	= btrfs_permission,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= btrfs_listxattr,
-	.removexattr	= generic_removexattr,
 	.get_acl	= btrfs_get_acl,
 	.set_acl	= btrfs_set_acl,
 	.update_time	= btrfs_update_time,
@@ -10265,10 +10256,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
 	.getattr	= btrfs_getattr,
 	.setattr	= btrfs_setattr,
 	.permission	= btrfs_permission,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= btrfs_listxattr,
-	.removexattr	= generic_removexattr,
 	.update_time	= btrfs_update_time,
 };
 
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 3ab1192..1fe2f7a 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -1343,10 +1343,7 @@ const struct inode_operations ceph_dir_iops = {
 	.permission = ceph_permission,
 	.getattr = ceph_getattr,
 	.setattr = ceph_setattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = ceph_listxattr,
-	.removexattr = generic_removexattr,
 	.get_acl = ceph_get_acl,
 	.set_acl = ceph_set_acl,
 	.mknod = ceph_mknod,
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index e669cfa..a2c8457 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -93,10 +93,7 @@ const struct inode_operations ceph_file_iops = {
 	.permission = ceph_permission,
 	.setattr = ceph_setattr,
 	.getattr = ceph_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = ceph_listxattr,
-	.removexattr = generic_removexattr,
 	.get_acl = ceph_get_acl,
 	.set_acl = ceph_set_acl,
 };
@@ -1771,10 +1768,7 @@ static const struct inode_operations ceph_symlink_iops = {
 	.get_link = simple_get_link,
 	.setattr = ceph_setattr,
 	.getattr = ceph_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = ceph_listxattr,
-	.removexattr = generic_removexattr,
 };
 
 int __ceph_setattr(struct inode *inode, struct iattr *attr)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 08fa36e..7372d5b 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -894,10 +894,7 @@ const struct inode_operations cifs_dir_inode_ops = {
 	.setattr = cifs_setattr,
 	.symlink = cifs_symlink,
 	.mknod   = cifs_mknod,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = cifs_listxattr,
-	.removexattr = generic_removexattr,
 };
 
 const struct inode_operations cifs_file_inode_ops = {
@@ -905,10 +902,7 @@ const struct inode_operations cifs_file_inode_ops = {
 	.setattr = cifs_setattr,
 	.getattr = cifs_getattr, /* do we need this anymore? */
 	.permission = cifs_permission,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = cifs_listxattr,
-	.removexattr = generic_removexattr,
 };
 
 const struct inode_operations cifs_symlink_inode_ops = {
@@ -918,10 +912,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
 	/* BB add the following two eventually */
 	/* revalidate: cifs_revalidate,
 	   setattr:    cifs_notify_change, *//* BB do we need notify change */
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = cifs_listxattr,
-	.removexattr = generic_removexattr,
 };
 
 static int cifs_clone_file_range(struct file *src_file, loff_t off,
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index f283fa6..eebb7b01 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -1086,10 +1086,7 @@ const struct inode_operations ecryptfs_symlink_iops = {
 	.permission = ecryptfs_permission,
 	.setattr = ecryptfs_setattr,
 	.getattr = ecryptfs_getattr_link,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = ecryptfs_listxattr,
-	.removexattr = generic_removexattr
 };
 
 const struct inode_operations ecryptfs_dir_iops = {
@@ -1104,20 +1101,14 @@ const struct inode_operations ecryptfs_dir_iops = {
 	.rename = ecryptfs_rename,
 	.permission = ecryptfs_permission,
 	.setattr = ecryptfs_setattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = ecryptfs_listxattr,
-	.removexattr = generic_removexattr
 };
 
 const struct inode_operations ecryptfs_main_iops = {
 	.permission = ecryptfs_permission,
 	.setattr = ecryptfs_setattr,
 	.getattr = ecryptfs_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = ecryptfs_listxattr,
-	.removexattr = generic_removexattr
 };
 
 static int ecryptfs_xattr_get(const struct xattr_handler *handler,
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index c1400b1..8c28f44 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -178,10 +178,7 @@ const struct file_operations ext2_file_operations = {
 
 const struct inode_operations ext2_file_inode_operations = {
 #ifdef CONFIG_EXT2_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext2_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 	.setattr	= ext2_setattr,
 	.get_acl	= ext2_get_acl,
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index d446203..ff32ea7 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -428,10 +428,7 @@ const struct inode_operations ext2_dir_inode_operations = {
 	.mknod		= ext2_mknod,
 	.rename		= ext2_rename,
 #ifdef CONFIG_EXT2_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext2_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 	.setattr	= ext2_setattr,
 	.get_acl	= ext2_get_acl,
@@ -441,10 +438,7 @@ const struct inode_operations ext2_dir_inode_operations = {
 
 const struct inode_operations ext2_special_inode_operations = {
 #ifdef CONFIG_EXT2_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext2_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 	.setattr	= ext2_setattr,
 	.get_acl	= ext2_get_acl,
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index 3495d8a..8437b19 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -25,10 +25,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
 	.get_link	= page_get_link,
 	.setattr	= ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext2_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 };
  
@@ -37,9 +34,6 @@ const struct inode_operations ext2_fast_symlink_inode_operations = {
 	.get_link	= simple_get_link,
 	.setattr	= ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext2_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 };
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 00ff691..e811fb11 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -711,10 +711,7 @@ const struct file_operations ext4_file_operations = {
 const struct inode_operations ext4_file_inode_operations = {
 	.setattr	= ext4_setattr,
 	.getattr	= ext4_getattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext4_listxattr,
-	.removexattr	= generic_removexattr,
 	.get_acl	= ext4_get_acl,
 	.set_acl	= ext4_set_acl,
 	.fiemap		= ext4_fiemap,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 5611ec9..ad89756 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3882,10 +3882,7 @@ const struct inode_operations ext4_dir_inode_operations = {
 	.tmpfile	= ext4_tmpfile,
 	.rename2	= ext4_rename2,
 	.setattr	= ext4_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext4_listxattr,
-	.removexattr	= generic_removexattr,
 	.get_acl	= ext4_get_acl,
 	.set_acl	= ext4_set_acl,
 	.fiemap         = ext4_fiemap,
@@ -3893,10 +3890,7 @@ const struct inode_operations ext4_dir_inode_operations = {
 
 const struct inode_operations ext4_special_inode_operations = {
 	.setattr	= ext4_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext4_listxattr,
-	.removexattr	= generic_removexattr,
 	.get_acl	= ext4_get_acl,
 	.set_acl	= ext4_set_acl,
 };
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
index 75ed5c2..65fa087 100644
--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -94,10 +94,7 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.get_link	= ext4_encrypted_get_link,
 	.setattr	= ext4_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext4_listxattr,
-	.removexattr	= generic_removexattr,
 };
 #endif
 
@@ -105,18 +102,12 @@ const struct inode_operations ext4_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.get_link	= page_get_link,
 	.setattr	= ext4_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext4_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 const struct inode_operations ext4_fast_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.get_link	= simple_get_link,
 	.setattr	= ext4_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ext4_listxattr,
-	.removexattr	= generic_removexattr,
 };
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index eb9d027..32f325e 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -729,10 +729,7 @@ const struct inode_operations f2fs_file_inode_operations = {
 	.get_acl	= f2fs_get_acl,
 	.set_acl	= f2fs_set_acl,
 #ifdef CONFIG_F2FS_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= f2fs_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 	.fiemap		= f2fs_fiemap,
 };
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 324ed38..10d098c 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -1066,10 +1066,7 @@ const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
 	.getattr	= f2fs_getattr,
 	.setattr	= f2fs_setattr,
 #ifdef CONFIG_F2FS_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= f2fs_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 };
 
@@ -1089,10 +1086,7 @@ const struct inode_operations f2fs_dir_inode_operations = {
 	.get_acl	= f2fs_get_acl,
 	.set_acl	= f2fs_set_acl,
 #ifdef CONFIG_F2FS_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= f2fs_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 };
 
@@ -1102,10 +1096,7 @@ const struct inode_operations f2fs_symlink_inode_operations = {
 	.getattr	= f2fs_getattr,
 	.setattr	= f2fs_setattr,
 #ifdef CONFIG_F2FS_FS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= f2fs_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 };
 
@@ -1115,9 +1106,6 @@ const struct inode_operations f2fs_special_inode_operations = {
 	.get_acl	= f2fs_get_acl,
 	.set_acl	= f2fs_set_acl,
 #ifdef CONFIG_F2FS_FS_XATTR
-	.setxattr       = generic_setxattr,
-	.getxattr       = generic_getxattr,
 	.listxattr	= f2fs_listxattr,
-	.removexattr    = generic_removexattr,
 #endif
 };
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 6fe29b6..103ba69 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1880,10 +1880,7 @@ static const struct inode_operations fuse_dir_inode_operations = {
 	.mknod		= fuse_mknod,
 	.permission	= fuse_permission,
 	.getattr	= fuse_getattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= fuse_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 static const struct file_operations fuse_dir_operations = {
@@ -1901,10 +1898,7 @@ static const struct inode_operations fuse_common_inode_operations = {
 	.setattr	= fuse_setattr,
 	.permission	= fuse_permission,
 	.getattr	= fuse_getattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= fuse_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 static const struct inode_operations fuse_symlink_inode_operations = {
@@ -1912,10 +1906,7 @@ static const struct inode_operations fuse_symlink_inode_operations = {
 	.get_link	= fuse_get_link,
 	.readlink	= generic_readlink,
 	.getattr	= fuse_getattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= fuse_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 void fuse_init_common(struct inode *inode)
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 72e9c64..cc6557f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1994,10 +1994,7 @@ const struct inode_operations gfs2_file_iops = {
 	.permission = gfs2_permission,
 	.setattr = gfs2_setattr,
 	.getattr = gfs2_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = gfs2_listxattr,
-	.removexattr = generic_removexattr,
 	.fiemap = gfs2_fiemap,
 	.get_acl = gfs2_get_acl,
 	.set_acl = gfs2_set_acl,
@@ -2016,10 +2013,7 @@ const struct inode_operations gfs2_dir_iops = {
 	.permission = gfs2_permission,
 	.setattr = gfs2_setattr,
 	.getattr = gfs2_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = gfs2_listxattr,
-	.removexattr = generic_removexattr,
 	.fiemap = gfs2_fiemap,
 	.get_acl = gfs2_get_acl,
 	.set_acl = gfs2_set_acl,
@@ -2032,10 +2026,7 @@ const struct inode_operations gfs2_symlink_iops = {
 	.permission = gfs2_permission,
 	.setattr = gfs2_setattr,
 	.getattr = gfs2_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = gfs2_listxattr,
-	.removexattr = generic_removexattr,
 	.fiemap = gfs2_fiemap,
 };
 
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index d7f833f..85961fc 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -688,7 +688,5 @@ static const struct file_operations hfs_file_operations = {
 static const struct inode_operations hfs_file_inode_operations = {
 	.lookup		= hfs_file_lookup,
 	.setattr	= hfs_inode_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= generic_listxattr,
 };
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 42e1286..9cbe430 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -562,10 +562,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
 	.symlink		= hfsplus_symlink,
 	.mknod			= hfsplus_mknod,
 	.rename			= hfsplus_rename,
-	.setxattr		= generic_setxattr,
-	.getxattr		= generic_getxattr,
 	.listxattr		= hfsplus_listxattr,
-	.removexattr		= generic_removexattr,
 #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
 	.get_acl		= hfsplus_get_posix_acl,
 	.set_acl		= hfsplus_set_posix_acl,
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index ef9fefe..f5baee5 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -333,10 +333,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
 
 static const struct inode_operations hfsplus_file_inode_operations = {
 	.setattr	= hfsplus_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= hfsplus_listxattr,
-	.removexattr	= generic_removexattr,
 #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
 	.get_acl	= hfsplus_get_posix_acl,
 	.set_acl	= hfsplus_set_posix_acl,
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index db84191..56cf89c 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -61,10 +61,7 @@ const struct inode_operations jffs2_dir_inode_operations =
 	.get_acl =	jffs2_get_acl,
 	.set_acl =	jffs2_set_acl,
 	.setattr =	jffs2_setattr,
-	.setxattr =	generic_setxattr,
-	.getxattr =	generic_getxattr,
 	.listxattr =	jffs2_listxattr,
-	.removexattr =	generic_removexattr
 };
 
 /***********************************************************************/
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index fdf9e1c..c12476e 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -66,10 +66,7 @@ const struct inode_operations jffs2_file_inode_operations =
 	.get_acl =	jffs2_get_acl,
 	.set_acl =	jffs2_set_acl,
 	.setattr =	jffs2_setattr,
-	.setxattr =	generic_setxattr,
-	.getxattr =	generic_getxattr,
 	.listxattr =	jffs2_listxattr,
-	.removexattr =	generic_removexattr
 };
 
 const struct address_space_operations jffs2_file_address_operations =
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index afe2d75..8f3f085 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -16,8 +16,5 @@ const struct inode_operations jffs2_symlink_inode_operations =
 	.readlink =	generic_readlink,
 	.get_link =	simple_get_link,
 	.setattr =	jffs2_setattr,
-	.setxattr =	generic_setxattr,
-	.getxattr =	generic_getxattr,
 	.listxattr =	jffs2_listxattr,
-	.removexattr =	generic_removexattr
 };
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 7f1a585..f6eb041 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -140,10 +140,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
 }
 
 const struct inode_operations jfs_file_inode_operations = {
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= jfs_listxattr,
-	.removexattr	= generic_removexattr,
 	.setattr	= jfs_setattr,
 #ifdef CONFIG_JFS_POSIX_ACL
 	.get_acl	= jfs_get_acl,
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 539dedd..cdaacec 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1537,10 +1537,7 @@ const struct inode_operations jfs_dir_inode_operations = {
 	.rmdir		= jfs_rmdir,
 	.mknod		= jfs_mknod,
 	.rename		= jfs_rename,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= jfs_listxattr,
-	.removexattr	= generic_removexattr,
 	.setattr	= jfs_setattr,
 #ifdef CONFIG_JFS_POSIX_ACL
 	.get_acl	= jfs_get_acl,
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index c94c7e4..c82404f 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -25,19 +25,13 @@ const struct inode_operations jfs_fast_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.get_link	= simple_get_link,
 	.setattr	= jfs_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= jfs_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 const struct inode_operations jfs_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.get_link	= page_get_link,
 	.setattr	= jfs_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= jfs_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 8e69385b..d98c7e58 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1125,9 +1125,6 @@ const struct inode_operations kernfs_dir_iops = {
 	.permission	= kernfs_iop_permission,
 	.setattr	= kernfs_iop_setattr,
 	.getattr	= kernfs_iop_getattr,
-	.setxattr	= generic_setxattr,
-	.removexattr	= generic_removexattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= kernfs_iop_listxattr,
 
 	.mkdir		= kernfs_iop_mkdir,
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 300a07a..1730556 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -28,9 +28,6 @@ static const struct inode_operations kernfs_iops = {
 	.permission	= kernfs_iop_permission,
 	.setattr	= kernfs_iop_setattr,
 	.getattr	= kernfs_iop_getattr,
-	.setxattr	= generic_setxattr,
-	.removexattr	= generic_removexattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= kernfs_iop_listxattr,
 };
 
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c
index 549a14c7..9b43ca0 100644
--- a/fs/kernfs/symlink.c
+++ b/fs/kernfs/symlink.c
@@ -134,9 +134,6 @@ static const char *kernfs_iop_get_link(struct dentry *dentry,
 }
 
 const struct inode_operations kernfs_symlink_iops = {
-	.setxattr	= generic_setxattr,
-	.removexattr	= generic_removexattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= kernfs_iop_listxattr,
 	.readlink	= generic_readlink,
 	.get_link	= kernfs_iop_get_link,
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index cb28cce..0be4e42 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -899,9 +899,6 @@ static const struct inode_operations nfs3_dir_inode_operations = {
 	.setattr	= nfs_setattr,
 #ifdef CONFIG_NFS_V3_ACL
 	.listxattr	= nfs3_listxattr,
-	.getxattr	= generic_getxattr,
-	.setxattr	= generic_setxattr,
-	.removexattr	= generic_removexattr,
 	.get_acl	= nfs3_get_acl,
 	.set_acl	= nfs3_set_acl,
 #endif
@@ -913,9 +910,6 @@ static const struct inode_operations nfs3_file_inode_operations = {
 	.setattr	= nfs_setattr,
 #ifdef CONFIG_NFS_V3_ACL
 	.listxattr	= nfs3_listxattr,
-	.getxattr	= generic_getxattr,
-	.setxattr	= generic_setxattr,
-	.removexattr	= generic_removexattr,
 	.get_acl	= nfs3_get_acl,
 	.set_acl	= nfs3_set_acl,
 #endif
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 084e857..e7ceb85 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -8853,20 +8853,14 @@ static const struct inode_operations nfs4_dir_inode_operations = {
 	.permission	= nfs_permission,
 	.getattr	= nfs_getattr,
 	.setattr	= nfs_setattr,
-	.getxattr	= generic_getxattr,
-	.setxattr	= generic_setxattr,
 	.listxattr	= nfs4_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 static const struct inode_operations nfs4_file_inode_operations = {
 	.permission	= nfs_permission,
 	.getattr	= nfs_getattr,
 	.setattr	= nfs_setattr,
-	.getxattr	= generic_getxattr,
-	.setxattr	= generic_setxattr,
 	.listxattr	= nfs4_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 const struct nfs_rpc_ops nfs_v4_clientops = {
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 4e7b0dc..baf291b 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2460,10 +2460,7 @@ const struct inode_operations ocfs2_file_iops = {
 	.setattr	= ocfs2_setattr,
 	.getattr	= ocfs2_getattr,
 	.permission	= ocfs2_permission,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ocfs2_listxattr,
-	.removexattr	= generic_removexattr,
 	.fiemap		= ocfs2_fiemap,
 	.get_acl	= ocfs2_iop_get_acl,
 	.set_acl	= ocfs2_iop_set_acl,
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index a8f1225..6cc043e 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -2913,10 +2913,7 @@ const struct inode_operations ocfs2_dir_iops = {
 	.setattr	= ocfs2_setattr,
 	.getattr	= ocfs2_getattr,
 	.permission	= ocfs2_permission,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ocfs2_listxattr,
-	.removexattr	= generic_removexattr,
 	.fiemap         = ocfs2_fiemap,
 	.get_acl	= ocfs2_iop_get_acl,
 	.set_acl	= ocfs2_iop_set_acl,
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index 6c2a3e3..6ad8eec 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -91,9 +91,6 @@ const struct inode_operations ocfs2_symlink_inode_operations = {
 	.get_link	= page_get_link,
 	.getattr	= ocfs2_getattr,
 	.setattr	= ocfs2_setattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ocfs2_listxattr,
-	.removexattr	= generic_removexattr,
 	.fiemap		= ocfs2_fiemap,
 };
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 85640e9..80b1b35 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -299,10 +299,7 @@ struct inode_operations orangefs_file_inode_operations = {
 	.set_acl = orangefs_set_acl,
 	.setattr = orangefs_setattr,
 	.getattr = orangefs_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = orangefs_listxattr,
-	.removexattr = generic_removexattr,
 	.permission = orangefs_permission,
 };
 
diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c
index 5a60c50..d396d03 100644
--- a/fs/orangefs/namei.c
+++ b/fs/orangefs/namei.c
@@ -454,9 +454,6 @@ struct inode_operations orangefs_dir_inode_operations = {
 	.rename = orangefs_rename,
 	.setattr = orangefs_setattr,
 	.getattr = orangefs_getattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
-	.removexattr = generic_removexattr,
 	.listxattr = orangefs_listxattr,
 	.permission = orangefs_permission,
 };
diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c
index 6418dd6..dade1ef 100644
--- a/fs/orangefs/symlink.c
+++ b/fs/orangefs/symlink.c
@@ -14,6 +14,5 @@ struct inode_operations orangefs_symlink_inode_operations = {
 	.setattr = orangefs_setattr,
 	.getattr = orangefs_getattr,
 	.listxattr = orangefs_listxattr,
-	.setxattr = generic_setxattr,
 	.permission = orangefs_permission,
 };
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 16ba0f8..6438002 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -967,8 +967,5 @@ const struct inode_operations ovl_dir_inode_operations = {
 	.mknod		= ovl_mknod,
 	.permission	= ovl_permission,
 	.getattr	= ovl_dir_getattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ovl_listxattr,
-	.removexattr	= generic_removexattr,
 };
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index d08c926..10dda4b 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -374,10 +374,7 @@ static const struct inode_operations ovl_file_inode_operations = {
 	.setattr	= ovl_setattr,
 	.permission	= ovl_permission,
 	.getattr	= ovl_getattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ovl_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 static const struct inode_operations ovl_symlink_inode_operations = {
@@ -385,10 +382,7 @@ static const struct inode_operations ovl_symlink_inode_operations = {
 	.get_link	= ovl_get_link,
 	.readlink	= ovl_readlink,
 	.getattr	= ovl_getattr,
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= ovl_listxattr,
-	.removexattr	= generic_removexattr,
 };
 
 struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 90f815b..2f8c5c9 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -260,10 +260,7 @@ const struct file_operations reiserfs_file_operations = {
 
 const struct inode_operations reiserfs_file_inode_operations = {
 	.setattr = reiserfs_setattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 	.get_acl = reiserfs_get_acl,
 	.set_acl = reiserfs_set_acl,
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 8a36696..fd7d060 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1650,10 +1650,7 @@ const struct inode_operations reiserfs_dir_inode_operations = {
 	.mknod = reiserfs_mknod,
 	.rename = reiserfs_rename,
 	.setattr = reiserfs_setattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 	.get_acl = reiserfs_get_acl,
 	.set_acl = reiserfs_set_acl,
@@ -1667,10 +1664,7 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
 	.readlink = generic_readlink,
 	.get_link	= page_get_link,
 	.setattr = reiserfs_setattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 };
 
@@ -1679,10 +1673,7 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
  */
 const struct inode_operations reiserfs_special_inode_operations = {
 	.setattr = reiserfs_setattr,
-	.setxattr = generic_setxattr,
-	.getxattr = generic_getxattr,
 	.listxattr = reiserfs_listxattr,
-	.removexattr = generic_removexattr,
 	.permission = reiserfs_permission,
 	.get_acl = reiserfs_get_acl,
 	.set_acl = reiserfs_set_acl,
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c
index 0927b1e..e9793b1 100644
--- a/fs/squashfs/inode.c
+++ b/fs/squashfs/inode.c
@@ -425,7 +425,6 @@ failed_read:
 
 
 const struct inode_operations squashfs_inode_ops = {
-	.getxattr = generic_getxattr,
 	.listxattr = squashfs_listxattr
 };
 
diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c
index 67cad77..40c10d9 100644
--- a/fs/squashfs/namei.c
+++ b/fs/squashfs/namei.c
@@ -247,6 +247,5 @@ failed:
 
 const struct inode_operations squashfs_dir_inode_ops = {
 	.lookup = squashfs_lookup,
-	.getxattr = generic_getxattr,
 	.listxattr = squashfs_listxattr
 };
diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
index d688ef4..79b9c31 100644
--- a/fs/squashfs/symlink.c
+++ b/fs/squashfs/symlink.c
@@ -120,7 +120,6 @@ const struct address_space_operations squashfs_symlink_aops = {
 const struct inode_operations squashfs_symlink_inode_ops = {
 	.readlink = generic_readlink,
 	.get_link = page_get_link,
-	.getxattr = generic_getxattr,
 	.listxattr = squashfs_listxattr
 };
 
diff --git a/fs/squashfs/xattr.h b/fs/squashfs/xattr.h
index c83f5d9..afe70f8 100644
--- a/fs/squashfs/xattr.h
+++ b/fs/squashfs/xattr.h
@@ -42,6 +42,5 @@ static inline int squashfs_xattr_lookup(struct super_block *sb,
 	return 0;
 }
 #define squashfs_listxattr NULL
-#define generic_getxattr NULL
 #define squashfs_xattr_handlers NULL
 #endif
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 4b86d3a..1d55aea 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -1182,10 +1182,7 @@ const struct inode_operations ubifs_dir_inode_operations = {
 	.rename      = ubifs_rename,
 	.setattr     = ubifs_setattr,
 	.getattr     = ubifs_getattr,
-	.setxattr    = generic_setxattr,
-	.getxattr    = generic_getxattr,
 	.listxattr   = ubifs_listxattr,
-	.removexattr = generic_removexattr,
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
 	.update_time = ubifs_update_time,
 #endif
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 0831697..ffdc4b2 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1597,10 +1597,7 @@ const struct address_space_operations ubifs_file_address_operations = {
 const struct inode_operations ubifs_file_inode_operations = {
 	.setattr     = ubifs_setattr,
 	.getattr     = ubifs_getattr,
-	.setxattr    = generic_setxattr,
-	.getxattr    = generic_getxattr,
 	.listxattr   = ubifs_listxattr,
-	.removexattr = generic_removexattr,
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
 	.update_time = ubifs_update_time,
 #endif
@@ -1611,10 +1608,7 @@ const struct inode_operations ubifs_symlink_inode_operations = {
 	.get_link    = simple_get_link,
 	.setattr     = ubifs_setattr,
 	.getattr     = ubifs_getattr,
-	.setxattr    = generic_setxattr,
-	.getxattr    = generic_getxattr,
 	.listxattr   = ubifs_listxattr,
-	.removexattr = generic_removexattr,
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
 	.update_time = ubifs_update_time,
 #endif
diff --git a/fs/xattr.c b/fs/xattr.c
index f70917b..5669adf 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -732,22 +732,6 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
 }
 
 /*
- * Find the handler for the prefix and dispatch its get() operation.
- */
-ssize_t
-generic_getxattr(struct dentry *dentry, struct inode *inode,
-		 const char *name, void *buffer, size_t size)
-{
-	const struct xattr_handler *handler;
-
-	handler = xattr_resolve_name(inode, &name);
-	if (IS_ERR(handler))
-		return PTR_ERR(handler);
-	return handler->get(handler, dentry, inode,
-			    name, buffer, size);
-}
-
-/*
  * Combine the results of the list() operation from every xattr_handler in the
  * list.
  */
@@ -783,42 +767,7 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
 	}
 	return size;
 }
-
-/*
- * Find the handler for the prefix and dispatch its set() operation.
- */
-int
-generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
-{
-	const struct xattr_handler *handler;
-
-	if (size == 0)
-		value = "";  /* empty EA, do not remove */
-	handler = xattr_resolve_name(d_inode(dentry), &name);
-	if (IS_ERR(handler))
-		return PTR_ERR(handler);
-	return handler->set(handler, dentry, name, value, size, flags);
-}
-
-/*
- * Find the handler for the prefix and dispatch its set() operation to remove
- * any associated extended attribute.
- */
-int
-generic_removexattr(struct dentry *dentry, const char *name)
-{
-	const struct xattr_handler *handler;
-
-	handler = xattr_resolve_name(d_inode(dentry), &name);
-	if (IS_ERR(handler))
-		return PTR_ERR(handler);
-	return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
-}
-
-EXPORT_SYMBOL(generic_getxattr);
 EXPORT_SYMBOL(generic_listxattr);
-EXPORT_SYMBOL(generic_setxattr);
-EXPORT_SYMBOL(generic_removexattr);
 
 /**
  * xattr_full_name  -  Compute full attribute name from suffix
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index fb7dc61..3d3a589 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1091,9 +1091,6 @@ static const struct inode_operations xfs_inode_operations = {
 	.set_acl		= xfs_set_acl,
 	.getattr		= xfs_vn_getattr,
 	.setattr		= xfs_vn_setattr,
-	.setxattr		= generic_setxattr,
-	.getxattr		= generic_getxattr,
-	.removexattr		= generic_removexattr,
 	.listxattr		= xfs_vn_listxattr,
 	.fiemap			= xfs_vn_fiemap,
 	.update_time		= xfs_vn_update_time,
@@ -1119,9 +1116,6 @@ static const struct inode_operations xfs_dir_inode_operations = {
 	.set_acl		= xfs_set_acl,
 	.getattr		= xfs_vn_getattr,
 	.setattr		= xfs_vn_setattr,
-	.setxattr		= generic_setxattr,
-	.getxattr		= generic_getxattr,
-	.removexattr		= generic_removexattr,
 	.listxattr		= xfs_vn_listxattr,
 	.update_time		= xfs_vn_update_time,
 	.tmpfile		= xfs_vn_tmpfile,
@@ -1147,9 +1141,6 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
 	.set_acl		= xfs_set_acl,
 	.getattr		= xfs_vn_getattr,
 	.setattr		= xfs_vn_setattr,
-	.setxattr		= generic_setxattr,
-	.getxattr		= generic_getxattr,
-	.removexattr		= generic_removexattr,
 	.listxattr		= xfs_vn_listxattr,
 	.update_time		= xfs_vn_update_time,
 	.tmpfile		= xfs_vn_tmpfile,
@@ -1160,9 +1151,6 @@ static const struct inode_operations xfs_symlink_inode_operations = {
 	.get_link		= xfs_vn_get_link,
 	.getattr		= xfs_vn_getattr,
 	.setattr		= xfs_vn_setattr,
-	.setxattr		= generic_setxattr,
-	.getxattr		= generic_getxattr,
-	.removexattr		= generic_removexattr,
 	.listxattr		= xfs_vn_listxattr,
 	.update_time		= xfs_vn_update_time,
 };
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e80594f..4f8a9c0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1731,11 +1731,7 @@ struct inode_operations {
 			struct inode *, struct dentry *, unsigned int);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
-	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
-	ssize_t (*getxattr) (struct dentry *, struct inode *,
-			     const char *, void *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
-	int (*removexattr) (struct dentry *, const char *);
 	int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
 		      u64 len);
 	int (*update_time)(struct inode *, struct timespec *, int);
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 59271a4..94e9bca 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -55,10 +55,7 @@ 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, struct inode *inode, const char *name, void *buffer, size_t size);
 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
-int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
-int generic_removexattr(struct dentry *dentry, const char *name);
 ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
 			   char **xattr_value, size_t size, gfp_t flags);
 
diff --git a/mm/shmem.c b/mm/shmem.c
index e684a91..b12d6b3 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2698,10 +2698,7 @@ static const struct inode_operations shmem_short_symlink_operations = {
 	.readlink	= generic_readlink,
 	.get_link	= simple_get_link,
 #ifdef CONFIG_TMPFS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= shmem_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 };
 
@@ -2709,10 +2706,7 @@ static const struct inode_operations shmem_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.get_link	= shmem_get_link,
 #ifdef CONFIG_TMPFS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= shmem_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 };
 
@@ -3184,10 +3178,7 @@ static const struct inode_operations shmem_inode_operations = {
 	.getattr	= shmem_getattr,
 	.setattr	= shmem_setattr,
 #ifdef CONFIG_TMPFS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= shmem_listxattr,
-	.removexattr	= generic_removexattr,
 	.set_acl	= simple_set_acl,
 #endif
 };
@@ -3206,10 +3197,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
 	.tmpfile	= shmem_tmpfile,
 #endif
 #ifdef CONFIG_TMPFS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= shmem_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 #ifdef CONFIG_TMPFS_POSIX_ACL
 	.setattr	= shmem_setattr,
@@ -3219,10 +3207,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
 
 static const struct inode_operations shmem_special_inode_operations = {
 #ifdef CONFIG_TMPFS_XATTR
-	.setxattr	= generic_setxattr,
-	.getxattr	= generic_getxattr,
 	.listxattr	= shmem_listxattr,
-	.removexattr	= generic_removexattr,
 #endif
 #ifdef CONFIG_TMPFS_POSIX_ACL
 	.setattr	= shmem_setattr,
diff --git a/net/socket.c b/net/socket.c
index d7816b6..4bbfd38 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -519,7 +519,6 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
 }
 
 static const struct inode_operations sockfs_inode_ops = {
-	.getxattr = generic_getxattr,
 	.listxattr = sockfs_listxattr,
 };
 
-- 
2.5.5


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 10/18] evm: Turn evm_update_evmxattr into void function
  2016-05-20 11:14 ` [PATCH v2 10/18] evm: Turn evm_update_evmxattr into void function Andreas Gruenbacher
@ 2016-05-25  5:30   ` James Morris
  2016-05-25 11:08     ` Mimi Zohar
  0 siblings, 1 reply; 24+ messages in thread
From: James Morris @ 2016-05-25  5:30 UTC (permalink / raw)
  To: Andreas Gruenbacher, Mimi Zohar
  Cc: Alexander Viro, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

On Fri, 20 May 2016, Andreas Gruenbacher wrote:

> The return value of evm_update_evmxattr is never used.
> 
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>

As I mentioned last time, the EVM code is silently ignoring errors here, 
and I'd prefer to see that fixed.

Mimi: any comment on this?



-- 
James Morris
<jmorris@namei.org>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 15/18] xattr: Add __vfs_{get,set,remove}xattr helpers
  2016-05-20 11:14 ` [PATCH v2 15/18] xattr: Add __vfs_{get,set,remove}xattr helpers Andreas Gruenbacher
@ 2016-05-25  5:38   ` James Morris
  0 siblings, 0 replies; 24+ messages in thread
From: James Morris @ 2016-05-25  5:38 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Alexander Viro, linux-fsdevel, Tyler Hicks, ecryptfs,
	Miklos Szeredi, linux-unionfs, Mimi Zohar, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

On Fri, 20 May 2016, Andreas Gruenbacher wrote:

> Right now, various places in the kernel check for the existence of
> getxattr, setxattr, and removexattr inode operations and directly call
> those operations.  Switch to helper functions and test for the IOP_XATTR
> flag instead.
> 
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>


Acked-by: James Morris <james.l.morris@oracle.com>

-- 
James Morris
<jmorris@namei.org>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 10/18] evm: Turn evm_update_evmxattr into void function
  2016-05-25  5:30   ` James Morris
@ 2016-05-25 11:08     ` Mimi Zohar
  0 siblings, 0 replies; 24+ messages in thread
From: Mimi Zohar @ 2016-05-25 11:08 UTC (permalink / raw)
  To: James Morris
  Cc: Andreas Gruenbacher, Alexander Viro, linux-fsdevel, Tyler Hicks,
	ecryptfs, Miklos Szeredi, linux-unionfs, linux-ima-devel,
	linux-security-module, David Howells, Serge Hallyn,
	Dmitry Kasatkin, Paul Moore, Stephen Smalley, Eric Paris,
	Casey Schaufler, Oleg Drokin, Andreas Dilger

On Wed, 2016-05-25 at 15:30 +1000, James Morris wrote:
> On Fri, 20 May 2016, Andreas Gruenbacher wrote:
> 
> > The return value of evm_update_evmxattr is never used.
> > 
> > Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> 
> As I mentioned last time, the EVM code is silently ignoring errors here, 
> and I'd prefer to see that fixed.

Agreed.   evm_update_evmxattr() is called as a result of a "protected"
xattr or some other file metadata having been modified.  The two actions
need to remain in sync, otherwise subsequent file access will be denied.
At the point that evm_update_evmxattr() fails, there isn't much that can
be done other than audit the failure.  The file metadata has already
been modified.

Mimi


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/18] xattr: Remove unnecessary NULL attribute name check
  2016-05-20 11:14 ` [PATCH v2 01/18] xattr: Remove unnecessary NULL attribute name check Andreas Gruenbacher
@ 2016-05-26 12:49   ` Carlos Maiolino
  0 siblings, 0 replies; 24+ messages in thread
From: Carlos Maiolino @ 2016-05-26 12:49 UTC (permalink / raw)
  To: linux-fsdevel

On Fri, May 20, 2016 at 01:14:18PM +0200, Andreas Gruenbacher wrote:
> When NULL is passed to one of the xattr system calls as the attribute
> name, copying that name from user space already fails with -EFAULT;
> xattr_resolve_name is never called with a NULL attribute name.
> 
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>

Hi Andreas,

this patch looks invalid for me now, since patch aaf431b4f9 (also from you) has
been already applied.

Do you still plan to remove this if statement?

you replaced it in the above mentioned patch by:

return ERR_PTR(-EINVAL)


> ---
>  fs/xattr.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/fs/xattr.c b/fs/xattr.c
> index b11945e..2476acc 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -667,9 +667,6 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
>  {
>  	const struct xattr_handler *handler;
>  
> -	if (!*name)
> -		return NULL;
> -
>  	for_each_xattr_handler(handlers, handler) {
>  		const char *n;
>  
> -- 
> 2.5.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Carlos

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 00/18] Xattr inode operation removal
  2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
                   ` (17 preceding siblings ...)
  2016-05-20 11:14 ` [PATCH v2 18/18] vfs: Remove " Andreas Gruenbacher
@ 2016-05-26 19:39 ` Carlos Maiolino
  18 siblings, 0 replies; 24+ messages in thread
From: Carlos Maiolino @ 2016-05-26 19:39 UTC (permalink / raw)
  To: linux-fsdevel

On Fri, May 20, 2016 at 01:14:17PM +0200, Andreas Gruenbacher wrote:
> This is version 2 of the xattr inode operation removal patch series. The
> patches are available in git form at:
> 
>   https://git.kernel.org/cgit/linux/kernel/git/agruen/linux.git/log/?h=work.xattr
> 

I just finished some tests on this patch, afaict, I couldn't find any
regressions, you can add:

Tested-by: Carlos Maiolino <cmaiolino@redhat.com>

> The purpose of this series is to remove unnecessary differences between the
> xattr implementations on different filesystems and to simplify things.  With
> the exception of redirectors like fuse, overlayfs, and ecryptfs, all
> filesystems perform some de-multiplexing based on the xattr name, so it makes
> sense to make that the default; filesystems that don't do any de-multiplexing
> can easily use a catch-all xattr handler.
> 
> The patch series is structured as follows:
> 
>  * The initial patches convert the remaining filesystems over to use xattr
>    handlers for implementing their de-multiplexing.
> 
>  * Next, a new IOP_XATTR inode operations flag is introduced: the flag is set
>    when an inode supports xattrs.  On most filesystems, the IOP_XATTR flag is
>    automatically initialized correctly when the inode is allocated based on
>    whether or not the s_xattr field in the inode's superblock is defined.
>    Filesystems that support xattrs on some but not all inodes can clear the
>    IOP_XATTR flag appropriately.
> 
>  * The IOP_XATTR flag is then used to get rid of the two remaining places where
>    xattr inode operations other than the generic ones are used: bad inodes and
>    libfs empty directories.
> 
>  * After that, we get rid of the remaining direct accesses to xattr inode
>    operations.
> 
>  * Finally, we stop calling the xattr inode operations and remove them.
> 
> Note that these patches only remove the getxattr, setxattr, and removexattr
> inode operations. The listxattr inode operation does not do any attribute name
> de-multiplexing, and remains unchanged except for checking the new IOP_XATTR
> flag as well now.
> 
> Note that this patch series still breaks Lustre.  I'm hoping that the Lustre
> developers will come up with a patch to switch lustre over to use xattr
> handlers.
> 
> Thanks,
> Andreas
> 
> Andreas Gruenbacher (18):
>   xattr: Remove unnecessary NULL attribute name check
>   jffs2: Remove jffs2_{get,set,remove}xattr macros
>   hfs: Switch to generic xattr handlers
>   kernfs: Switch to generic xattr handlers
>   sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names
>   sockfs: Get rid of getxattr iop
>   ecryptfs: Switch to generic xattr handlers
>   overlayfs: Switch to generic xattr handlers
>   fuse: Switch to generic xattr handlers
>   evm: Turn evm_update_evmxattr into void function
>   vfs: Move xattr_resolve_name to the front of fs/xattr.c
>   vfs: Add IOP_XATTR inode operations flag
>   vfs: Use IOP_XATTR flag for bad-inode handling
>   libfs: Use IOP_XATTR flag for empty directory handling
>   xattr: Add __vfs_{get,set,remove}xattr helpers
>   vfs: Check for the IOP_XATTR flag in listxattr
>   xattr: Stop calling {get,set,remove}xattr inode operations
>   vfs: Remove {get,set,remove}xattr inode operations
> 
>  Documentation/filesystems/Locking     |  24 +++-
>  Documentation/filesystems/vfs.txt     |  45 ++++---
>  arch/ia64/kernel/perfmon.c            |   4 +-
>  drivers/gpu/drm/drm_drv.c             |   1 +
>  fs/9p/vfs_inode_dotl.c                |   9 --
>  fs/aio.c                              |   2 +-
>  fs/anon_inodes.c                      |   2 +-
>  fs/bad_inode.c                        |  21 +--
>  fs/block_dev.c                        |   2 +-
>  fs/btrfs/inode.c                      |  12 --
>  fs/btrfs/tests/btrfs-tests.c          |   2 +-
>  fs/cachefiles/bind.c                  |   4 +-
>  fs/cachefiles/namei.c                 |   4 +-
>  fs/ceph/dir.c                         |   3 -
>  fs/ceph/inode.c                       |   6 -
>  fs/cifs/cifsfs.c                      |   9 --
>  fs/ecryptfs/ecryptfs_kernel.h         |   2 +
>  fs/ecryptfs/inode.c                   |  57 +++++---
>  fs/ecryptfs/main.c                    |   1 +
>  fs/ecryptfs/mmap.c                    |  11 +-
>  fs/ext2/file.c                        |   3 -
>  fs/ext2/namei.c                       |   6 -
>  fs/ext2/symlink.c                     |   6 -
>  fs/ext4/file.c                        |   3 -
>  fs/ext4/namei.c                       |   6 -
>  fs/ext4/symlink.c                     |   9 --
>  fs/f2fs/file.c                        |   3 -
>  fs/f2fs/namei.c                       |  12 --
>  fs/fuse/dir.c                         |  40 ++++--
>  fs/fuse/fuse_i.h                      |   2 +
>  fs/fuse/inode.c                       |   1 +
>  fs/gfs2/inode.c                       |   9 --
>  fs/hfs/attr.c                         |  82 ++++++++----
>  fs/hfs/hfs_fs.h                       |   6 +-
>  fs/hfs/inode.c                        |   5 +-
>  fs/hfs/super.c                        |   1 +
>  fs/hfsplus/dir.c                      |   3 -
>  fs/hfsplus/inode.c                    |   3 -
>  fs/inode.c                            |   2 +
>  fs/jffs2/dir.c                        |   3 -
>  fs/jffs2/file.c                       |   3 -
>  fs/jffs2/symlink.c                    |   3 -
>  fs/jffs2/xattr.h                      |   6 -
>  fs/jfs/file.c                         |   3 -
>  fs/jfs/namei.c                        |   3 -
>  fs/jfs/symlink.c                      |   6 -
>  fs/kernfs/dir.c                       |   3 -
>  fs/kernfs/inode.c                     | 153 +++++++++++----------
>  fs/kernfs/kernfs-internal.h           |   6 +-
>  fs/kernfs/mount.c                     |   1 +
>  fs/kernfs/symlink.c                   |   3 -
>  fs/libfs.c                            |  24 +---
>  fs/nfs/nfs3proc.c                     |   6 -
>  fs/nfs/nfs4proc.c                     |   6 -
>  fs/nsfs.c                             |   2 +-
>  fs/ocfs2/file.c                       |   3 -
>  fs/ocfs2/namei.c                      |   3 -
>  fs/ocfs2/symlink.c                    |   3 -
>  fs/orangefs/inode.c                   |   3 -
>  fs/orangefs/namei.c                   |   3 -
>  fs/orangefs/symlink.c                 |   1 -
>  fs/overlayfs/copy_up.c                |   4 +-
>  fs/overlayfs/dir.c                    |   3 -
>  fs/overlayfs/inode.c                  |  46 +++++--
>  fs/overlayfs/overlayfs.h              |   6 +-
>  fs/overlayfs/super.c                  |   5 +-
>  fs/pipe.c                             |   2 +-
>  fs/reiserfs/file.c                    |   3 -
>  fs/reiserfs/namei.c                   |   9 --
>  fs/squashfs/inode.c                   |   1 -
>  fs/squashfs/namei.c                   |   1 -
>  fs/squashfs/symlink.c                 |   1 -
>  fs/squashfs/xattr.h                   |   1 -
>  fs/ubifs/dir.c                        |   3 -
>  fs/ubifs/file.c                       |   6 -
>  fs/xattr.c                            | 245 +++++++++++++++++-----------------
>  fs/xfs/xfs_iops.c                     |  12 --
>  include/linux/fs.h                    |   6 +-
>  include/linux/xattr.h                 |   6 +-
>  mm/shmem.c                            |  15 ---
>  net/socket.c                          |  59 ++++----
>  security/commoncap.c                  |  25 ++--
>  security/integrity/evm/evm.h          |   7 +-
>  security/integrity/evm/evm_crypto.c   |  20 ++-
>  security/integrity/evm/evm_main.c     |   4 +-
>  security/integrity/ima/ima_appraise.c |  21 ++-
>  security/selinux/hooks.c              |  19 +--
>  security/smack/smack_lsm.c            |  12 +-
>  88 files changed, 529 insertions(+), 683 deletions(-)
> 
> -- 
> 2.5.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Carlos

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2016-05-26 19:39 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-20 11:14 [PATCH v2 00/18] Xattr inode operation removal Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 01/18] xattr: Remove unnecessary NULL attribute name check Andreas Gruenbacher
2016-05-26 12:49   ` Carlos Maiolino
2016-05-20 11:14 ` [PATCH v2 02/18] jffs2: Remove jffs2_{get,set,remove}xattr macros Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 03/18] hfs: Switch to generic xattr handlers Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 04/18] kernfs: " Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 05/18] sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 06/18] sockfs: Get rid of getxattr iop Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 07/18] ecryptfs: Switch to generic xattr handlers Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 08/18] overlayfs: " Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 09/18] fuse: " Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 10/18] evm: Turn evm_update_evmxattr into void function Andreas Gruenbacher
2016-05-25  5:30   ` James Morris
2016-05-25 11:08     ` Mimi Zohar
2016-05-20 11:14 ` [PATCH v2 11/18] vfs: Move xattr_resolve_name to the front of fs/xattr.c Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 12/18] vfs: Add IOP_XATTR inode operations flag Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 13/18] vfs: Use IOP_XATTR flag for bad-inode handling Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 14/18] libfs: Use IOP_XATTR flag for empty directory handling Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 15/18] xattr: Add __vfs_{get,set,remove}xattr helpers Andreas Gruenbacher
2016-05-25  5:38   ` James Morris
2016-05-20 11:14 ` [PATCH v2 16/18] vfs: Check for the IOP_XATTR flag in listxattr Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 17/18] xattr: Stop calling {get,set,remove}xattr inode operations Andreas Gruenbacher
2016-05-20 11:14 ` [PATCH v2 18/18] vfs: Remove " Andreas Gruenbacher
2016-05-26 19:39 ` [PATCH v2 00/18] Xattr inode operation removal Carlos Maiolino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).