[RFC][PATCH 15/15] nilfs2: integrate xattrs support functionality into driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
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@xxxxxxxxxxx>
CC: Ryusuke Konishi <konishi.ryusuke@xxxxxxxxxxxxx>
---
 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



--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux BTRFS]     [Linux CIFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux