All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 15/15] nilfs2: integrate xattrs support functionality into driver
@ 2013-11-27 12:43 Vyacheslav Dubeyko
  0 siblings, 0 replies; only message in thread
From: Vyacheslav Dubeyko @ 2013-11-27 12:43 UTC (permalink / raw)
  To: Ryusuke Konishi; +Cc: Linux FS Devel, linux-nilfs

From: Vyacheslav Dubeyko <slava@dubeyko.com>
Subject: [RFC][PATCH 15/15] nilfs2: integrate xattrs support functionality into driver

This patch integrates xattrs support functionality into
file system driver.

Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
CC: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
---
 fs/nilfs2/Kconfig     |   38 ++++++++++++++++++++++++++++++++++++++
 fs/nilfs2/Makefile    |    6 +++++-
 fs/nilfs2/bmap.c      |    1 +
 fs/nilfs2/file.c      |    7 +++++++
 fs/nilfs2/inode.c     |   22 ++++++++--------------
 fs/nilfs2/namei.c     |   42 ++++++++++++++++++++++++++++++++++++++++++
 fs/nilfs2/segment.c   |   22 ++++++++++++++++++++++
 fs/nilfs2/super.c     |   20 +++++++++++++++++---
 fs/nilfs2/the_nilfs.c |   19 +++++++++++++++++++
 9 files changed, 159 insertions(+), 18 deletions(-)

diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig
index 80da8eb..dcd420e 100644
--- a/fs/nilfs2/Kconfig
+++ b/fs/nilfs2/Kconfig
@@ -22,3 +22,41 @@ config NILFS2_FS
 
 	  To compile this file system support as a module, choose M here: the
 	  module will be called nilfs2.  If unsure, say N.
+
+config NILFS2_FS_DEBUG
+	bool "NILFS2 debugging"
+	depends on NILFS2_FS
+	help
+	  This option enables additional pre-condition and post-condition
+	  checking in functions. It can enable debug output too. The main
+	  goal of this option is providing environment for debugging code
+	  of NILFS2 driver and excluding debug checking and output from
+	  end-users' kernel build.
+
+	  If you are going to debug NILFS2 driver then choose Y here.
+	  If unsure, say N.
+
+config NILFS2_FS_POSIX_ACL
+	bool "NILFS2 POSIX Access Control Lists"
+	depends on NILFS2_FS
+	select FS_POSIX_ACL
+	help
+	  POSIX Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the POSIX ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N
+
+config NILFS2_FS_SECURITY
+	bool "NILFS2 Security Labels"
+	depends on NILFS2_FS
+	help
+	  Security labels support alternative access control models
+	  implemented by security modules like SELinux.  This option
+	  enables an extended attribute handler for file security
+	  labels in the NILFS2 filesystem.
+
+	  If you are not using a security module that requires using
+	  extended attributes for file security labels, say N.
diff --git a/fs/nilfs2/Makefile b/fs/nilfs2/Makefile
index 85c9873..8e56dbd 100644
--- a/fs/nilfs2/Makefile
+++ b/fs/nilfs2/Makefile
@@ -2,4 +2,8 @@ obj-$(CONFIG_NILFS2_FS) += nilfs2.o
 nilfs2-y := inode.o file.o dir.o super.o namei.o page.o mdt.o \
 	btnode.o bmap.o btree.o direct.o dat.o recovery.o \
 	the_nilfs.o segbuf.o segment.o cpfile.o sufile.o \
-	ifile.o alloc.o gcinode.o ioctl.o
+	ifile.o alloc.o gcinode.o ioctl.o \
+	xafile.o xattr.o xattr_user.o xattr_trusted.o
+
+nilfs2-$(CONFIG_NILFS2_FS_POSIX_ACL)	+= acl.o
+nilfs2-$(CONFIG_NILFS2_FS_SECURITY)	+= xattr_security.o
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index aadbd0b..7ab515f 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -499,6 +499,7 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
 		break;
 	case NILFS_CPFILE_INO:
 	case NILFS_SUFILE_INO:
+	case NILFS_XATTR_INO:
 		bmap->b_ptr_type = NILFS_BMAP_PTR_VS;
 		bmap->b_last_allocated_key = 0;
 		bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 08fdb77..7592e37 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -26,6 +26,8 @@
 #include <linux/writeback.h>
 #include "nilfs.h"
 #include "segment.h"
+#include "xattr.h"
+#include "acl.h"
 
 int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 {
@@ -169,6 +171,11 @@ const struct file_operations nilfs_file_operations = {
 const struct inode_operations nilfs_file_inode_operations = {
 	.setattr	= nilfs_setattr,
 	.permission     = nilfs_permission,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= nilfs_listxattr,
+	.removexattr	= generic_removexattr,
+	.get_acl	= nilfs_get_acl,
 	.fiemap		= nilfs_fiemap,
 };
 
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 7e350c5..690072b 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -33,6 +33,8 @@
 #include "mdt.h"
 #include "cpfile.h"
 #include "ifile.h"
+#include "xattr.h"
+#include "acl.h"
 
 /**
  * struct nilfs_iget_args - arguments used during comparison between inodes
@@ -386,8 +388,6 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)
 	ii->i_flags = nilfs_mask_flags(
 		mode, NILFS_I(dir)->i_flags & NILFS_FL_INHERITED);
 
-	/* ii->i_file_acl = 0; */
-	/* ii->i_dir_acl = 0; */
 	ii->i_dir_start_lookup = 0;
 	nilfs_set_inode_flags(inode);
 	spin_lock(&nilfs->ns_next_gen_lock);
@@ -395,15 +395,10 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)
 	spin_unlock(&nilfs->ns_next_gen_lock);
 	insert_inode_hash(inode);
 
-	err = nilfs_init_acl(inode, dir);
-	if (unlikely(err))
-		goto failed_acl; /* never occur. When supporting
-				    nilfs_init_acl(), proper cancellation of
-				    above jobs should be considered */
+	ii->i_xattr = NILFS_INVALID_XANODE;
 
 	return inode;
 
- failed_acl:
  failed_bmap:
 	clear_nlink(inode);
 	iput(inode);  /* raw_inode will be deleted through
@@ -460,14 +455,12 @@ int nilfs_read_inode_common(struct inode *inode,
 
 	inode->i_blocks = le64_to_cpu(raw_inode->i_blocks);
 	ii->i_flags = le32_to_cpu(raw_inode->i_flags);
-#if 0
-	ii->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
-	ii->i_dir_acl = S_ISREG(inode->i_mode) ?
-		0 : le32_to_cpu(raw_inode->i_dir_acl);
-#endif
+
 	ii->i_dir_start_lookup = 0;
 	inode->i_generation = le32_to_cpu(raw_inode->i_generation);
 
+	ii->i_xattr = le64_to_cpu(raw_inode->i_xattr);
+
 	if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
 	    S_ISLNK(inode->i_mode)) {
 		err = nilfs_bmap_read(ii->i_bmap, raw_inode);
@@ -655,7 +648,8 @@ void nilfs_write_inode_common(struct inode *inode,
 		raw_inode->i_pad = 0;
 		memset((void *)raw_inode + sizeof(*raw_inode), 0,
 		       nilfs->ns_inode_size - sizeof(*raw_inode));
-	}
+	} else
+		raw_inode->i_xattr = cpu_to_le64(ii->i_xattr);
 
 	if (has_bmap)
 		nilfs_bmap_write(ii->i_bmap, raw_inode);
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 9de78f0..dc40a99 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -41,6 +41,8 @@
 #include <linux/pagemap.h>
 #include "nilfs.h"
 #include "export.h"
+#include "xattr.h"
+#include "acl.h"
 
 #define NILFS_FID_SIZE_NON_CONNECTABLE \
 	(offsetof(struct nilfs_fid, parent_gen) / 4)
@@ -97,12 +99,17 @@ static int nilfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 	inode = nilfs_new_inode(dir, mode);
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
+		err = nilfs_init_inode_security(inode, dir, &dentry->d_name);
+		if (unlikely(err))
+			goto out;
 		inode->i_op = &nilfs_file_inode_operations;
 		inode->i_fop = &nilfs_file_operations;
 		inode->i_mapping->a_ops = &nilfs_aops;
 		nilfs_mark_inode_dirty(inode);
 		err = nilfs_add_nondir(dentry, inode);
 	}
+
+out:
 	if (!err)
 		err = nilfs_transaction_commit(dir->i_sb);
 	else
@@ -127,10 +134,15 @@ nilfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
 	inode = nilfs_new_inode(dir, mode);
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
+		err = nilfs_init_inode_security(inode, dir, &dentry->d_name);
+		if (unlikely(err))
+			goto out;
 		init_special_inode(inode, inode->i_mode, rdev);
 		nilfs_mark_inode_dirty(inode);
 		err = nilfs_add_nondir(dentry, inode);
 	}
+
+out:
 	if (!err)
 		err = nilfs_transaction_commit(dir->i_sb);
 	else
@@ -160,6 +172,10 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry,
 	if (IS_ERR(inode))
 		goto out;
 
+	err = nilfs_init_inode_security(inode, dir, &dentry->d_name);
+	if (unlikely(err))
+		goto out;
+
 	/* slow symlink */
 	inode->i_op = &nilfs_symlink_inode_operations;
 	inode->i_mapping->a_ops = &nilfs_aops;
@@ -227,6 +243,10 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	if (IS_ERR(inode))
 		goto out_dir;
 
+	err = nilfs_init_inode_security(inode, dir, &dentry->d_name);
+	if (unlikely(err))
+		goto out_dir;
+
 	inode->i_op = &nilfs_dir_inode_operations;
 	inode->i_fop = &nilfs_dir_operations;
 	inode->i_mapping->a_ops = &nilfs_aops;
@@ -285,6 +305,13 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
 			      inode->i_ino, inode->i_nlink);
 		set_nlink(inode, 1);
 	}
+
+	if (inode->i_nlink == 1) {
+		err = nilfs_xattr_delete_inode(inode);
+		if (err)
+			goto out;
+	}
+
 	err = nilfs_delete_entry(de, page);
 	if (err)
 		goto out;
@@ -553,12 +580,22 @@ const struct inode_operations nilfs_dir_inode_operations = {
 	.rename		= nilfs_rename,
 	.setattr	= nilfs_setattr,
 	.permission	= nilfs_permission,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= nilfs_listxattr,
+	.removexattr	= generic_removexattr,
+	.get_acl	= nilfs_get_acl,
 	.fiemap		= nilfs_fiemap,
 };
 
 const struct inode_operations nilfs_special_inode_operations = {
 	.setattr	= nilfs_setattr,
 	.permission	= nilfs_permission,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= nilfs_listxattr,
+	.removexattr	= generic_removexattr,
+	.get_acl	= nilfs_get_acl,
 };
 
 const struct inode_operations nilfs_symlink_inode_operations = {
@@ -566,6 +603,11 @@ const struct inode_operations nilfs_symlink_inode_operations = {
 	.follow_link	= page_follow_link_light,
 	.put_link	= page_put_link,
 	.permission     = nilfs_permission,
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= nilfs_listxattr,
+	.removexattr	= generic_removexattr,
+	.get_acl	= nilfs_get_acl,
 };
 
 const struct export_operations nilfs_export_ops = {
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 9f6b486..f808934 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -70,6 +70,7 @@ enum {
 	NILFS_ST_IFILE,
 	NILFS_ST_CPFILE,
 	NILFS_ST_SUFILE,
+	NILFS_ST_XAFILE,
 	NILFS_ST_DAT,
 	NILFS_ST_SR,		/* Super root */
 	NILFS_ST_DSYNC,		/* Data sync blocks */
@@ -757,6 +758,10 @@ static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
 		ret++;
 	if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile))
 		ret++;
+	if (nilfs_has_xafile(nilfs)) {
+		if (nilfs_mdt_fetch_dirty(nilfs->ns_xafile))
+			ret++;
+	}
 	if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat))
 		ret++;
 	return ret;
@@ -793,6 +798,8 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)
 	nilfs_mdt_clear_dirty(sci->sc_root->ifile);
 	nilfs_mdt_clear_dirty(nilfs->ns_cpfile);
 	nilfs_mdt_clear_dirty(nilfs->ns_sufile);
+	if (nilfs_has_xafile(nilfs))
+		nilfs_mdt_clear_dirty(nilfs->ns_xafile);
 	nilfs_mdt_clear_dirty(nilfs->ns_dat);
 }
 
@@ -909,6 +916,13 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
 				 NILFS_SR_CPFILE_OFFSET(isz), 1);
 	nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
 				 NILFS_SR_SUFILE_OFFSET(isz), 1);
+	if (nilfs_has_xafile(nilfs)) {
+		nilfs_write_inode_common(nilfs->ns_xafile, (void *)raw_sr +
+					 NILFS_SR_XAFILE_OFFSET(isz), 1);
+	} else {
+		memset((void *)raw_sr + NILFS_SR_XAFILE_OFFSET(isz), 0,
+			sizeof(struct nilfs_inode));
+	}
 	memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
 }
 
@@ -1157,6 +1171,14 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
 		if (unlikely(err))
 			break;
 		sci->sc_stage.scnt++;  /* Fall through */
+	case NILFS_ST_XAFILE:
+		if (nilfs_has_xafile(nilfs)) {
+			err = nilfs_segctor_scan_file(sci, nilfs->ns_xafile,
+							&nilfs_sc_file_ops);
+			if (unlikely(err))
+				break;
+		}
+		sci->sc_stage.scnt++;  /* Fall through */
 	case NILFS_ST_DAT:
  dat_stage:
 		err = nilfs_segctor_scan_file(sci, nilfs->ns_dat,
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 7ac2a12..75b1362 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -61,6 +61,8 @@
 #include "dat.h"
 #include "segment.h"
 #include "segbuf.h"
+#include "xattr.h"
+#include "acl.h"
 
 MODULE_AUTHOR("NTT Corp.");
 MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
@@ -486,6 +488,8 @@ static void nilfs_put_super(struct super_block *sb)
 		up_write(&nilfs->ns_sem);
 	}
 
+	if (nilfs_has_xafile(nilfs))
+		iput(nilfs->ns_xafile);
 	iput(nilfs->ns_sufile);
 	iput(nilfs->ns_cpfile);
 	iput(nilfs->ns_dat);
@@ -1071,6 +1075,12 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_time_gran = 1;
 	sb->s_max_links = NILFS_LINK_MAX;
 
+	sb->s_xattr = nilfs_xattr_handlers;
+	if (nilfs_has_xafile(nilfs))
+		set_posix_acl_flag(sb);
+	else
+		sb->s_flags &= ~MS_POSIXACL;
+
 	bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
 	sb->s_bdi = bdi ? : &default_backing_dev_info;
 
@@ -1113,6 +1123,8 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
 	nilfs_put_root(fsroot);
 
  failed_unload:
+	if (nilfs_has_xafile(nilfs))
+		iput(nilfs->ns_xafile);
 	iput(nilfs->ns_sufile);
 	iput(nilfs->ns_cpfile);
 	iput(nilfs->ns_dat);
@@ -1136,7 +1148,11 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
 		err = -EINVAL;
 		goto restore_opts;
 	}
-	sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
+
+	if (nilfs_has_xafile(nilfs))
+		set_posix_acl_flag(sb);
+	else
+		sb->s_flags &= ~MS_POSIXACL;
 
 	err = -EINVAL;
 
@@ -1379,9 +1395,7 @@ static void nilfs_inode_init_once(void *obj)
 	struct nilfs_inode_info *ii = obj;
 
 	INIT_LIST_HEAD(&ii->i_dirty);
-#ifdef CONFIG_NILFS_XATTR
 	init_rwsem(&ii->xattr_sem);
-#endif
 	address_space_init_once(&ii->i_btnode_cache);
 	ii->i_bmap = &ii->i_bmap_data;
 	inode_init_once(&ii->vfs_inode);
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 94c451c..a5fa271 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -33,6 +33,7 @@
 #include "cpfile.h"
 #include "sufile.h"
 #include "dat.h"
+#include "xafile.h"
 #include "segbuf.h"
 
 
@@ -142,6 +143,14 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
 	if (err)
 		goto failed_cpfile;
 
+	if (nilfs_has_xafile(nilfs)) {
+		rawi = (void *)bh_sr->b_data +
+				NILFS_SR_XAFILE_OFFSET(inode_size);
+		err = nilfs_xafile_read(sb, rawi, &nilfs->ns_xafile);
+		if (err)
+			goto failed_xafile;
+	}
+
 	raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
 	nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime);
 
@@ -149,6 +158,10 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
 	brelse(bh_sr);
 	return err;
 
+ failed_xafile:
+	if (nilfs_has_xafile(nilfs))
+		iput(nilfs->ns_xafile);
+
  failed_cpfile:
 	iput(nilfs->ns_cpfile);
 
@@ -343,6 +356,8 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
 	goto failed;
 
  failed_unload:
+	if (nilfs_has_xafile(nilfs))
+		iput(nilfs->ns_xafile);
 	iput(nilfs->ns_cpfile);
 	iput(nilfs->ns_sufile);
 	iput(nilfs->ns_dat);
@@ -584,6 +599,10 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
 	if (err)
 		goto failed_sbh;
 
+	if (le64_to_cpu(sbp->s_feature_compat_ro) &
+	    NILFS_FEATURE_COMPAT_RO_XAFILE)
+		set_nilfs_has_xafile(nilfs);
+
 	blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
 	if (blocksize < NILFS_MIN_BLOCK_SIZE ||
 	    blocksize > NILFS_MAX_BLOCK_SIZE) {
-- 
1.7.9.5




^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2013-11-27 12:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-27 12:43 [RFC][PATCH 15/15] nilfs2: integrate xattrs support functionality into driver Vyacheslav Dubeyko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.