Skip to contentSkip to conversation

ACL support for ext2/3

RFC PATCH In review [email protected] 1 participant 1 message Oct 10, 2002

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 5/5 ACL support for ext2/3

This patch adds ACL support to the ext2 filesystem.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
#

# fs/Config.help           |    2 
# fs/Config.in             |    1 
# fs/ext2/Makefile         |    1 
# fs/ext2/acl.c            |  581 +++++++++++++++++++++++++++++++++++++++++++++++
# fs/ext2/ext2.h           |    6 
# fs/ext2/file.c           |    4 
# fs/ext2/ialloc.c         |   36 +-
# fs/ext2/inode.c          |   17 +
# fs/ext2/namei.c          |   13 -
# fs/ext2/super.c          |   48 +++
# fs/ext2/xattr_user.c     |    4 
# include/linux/ext2_acl.h |  106 ++++++++
# include/linux/ext2_fs.h  |    1 

# 13 files changed, 797 insertions(+), 23 deletions(-) #
# The following is the BitKeeper ChangeSet Log # --------------------------------------------
# 02/10/10 [email protected] 1.673
# Port of 0.8.50 acl-ext2 to 2.5.
# -------------------------------------------- #

fs/Config.help +2 -0
diff -Nru a/fs/Config.help b/fs/Config.help
@@ -142,6 +142,8 @@
   the kernel or by users (see the attr(5) manual page, or visit
   <http://acl.bestbits.at/> for details).
 
+  You need this for POSIX ACL support on ext2.
+
   If unsure, say N.
 
 Ext2 extended attribute block sharing
fs/Config.in +1 -0
diff -Nru a/fs/Config.in b/fs/Config.in
@@ -104,6 +104,7 @@
   define_tristate CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
   define_bool CONFIG_EXT2_FS_XATTR_SHARING y
   define_bool CONFIG_EXT2_FS_XATTR_USER y
+  define_bool CONFIG_EXT2_FS_POSIX_ACL y
 fi
 
 tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
fs/ext2/Makefile +1 -0
diff -Nru a/fs/ext2/Makefile b/fs/ext2/Makefile
@@ -10,5 +10,6 @@
 export-objs += xattr.o
 obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
 obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
+obj-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
 
 include $(TOPDIR)/Rules.make
fs/ext2/acl.c new file +581 -0

581 lines not on this page · raw message

fs/ext2/ext2.h +6 -0
diff -Nru a/fs/ext2/ext2.h b/fs/ext2/ext2.h
@@ -1,6 +1,7 @@
 #include <linux/fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/ext2_xattr.h>
+#include <linux/ext2_acl.h>
 
 /*
  * second extended file system inode data in memory
@@ -20,6 +21,10 @@
 	__u32	i_prealloc_block;
 	__u32	i_prealloc_count;
 	__u32	i_dir_start_lookup;
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	struct posix_acl	*i_acl;
+	struct posix_acl	*i_default_acl;
+#endif
 	rwlock_t i_meta_lock;
 	struct inode	vfs_inode;
 };
@@ -79,6 +84,7 @@
 extern int ext2_sync_inode (struct inode *);
 extern void ext2_discard_prealloc (struct inode *);
 extern void ext2_truncate (struct inode *);
+extern int ext2_setattr (struct dentry *, struct iattr *);
 
 /* ioctl.c */
 extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
fs/ext2/file.c +4 -0
diff -Nru a/fs/ext2/file.c b/fs/ext2/file.c
@@ -57,4 +57,8 @@
 	.getxattr	= ext2_getxattr,
 	.listxattr	= ext2_listxattr,
 	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
+	.get_posix_acl	= ext2_get_acl,
+	.set_posix_acl	= ext2_set_acl,
 };
fs/ext2/ialloc.c +19 -17
diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
@@ -301,7 +301,6 @@
 	struct ext2_super_block * es;
 	struct ext2_inode_info *ei;
 	int err;
-	struct inode *ret;
 
 	sb = dir->i_sb;
 	inode = new_inode(sb);
@@ -322,7 +321,6 @@
 		goto fail;
 
 	err = -EIO;
-	brelse(bitmap_bh);
 	bitmap_bh = read_inode_bitmap(sb, group);
 	if (!bitmap_bh)
 		goto fail2;
@@ -338,6 +336,7 @@
 		ll_rw_block(WRITE, 1, &bitmap_bh);
 		wait_on_buffer(bitmap_bh);
 	}
+	brelse(bitmap_bh);
 
 	ino = group * EXT2_INODES_PER_GROUP(sb) + i + 1;
 	if (ino < EXT2_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
@@ -392,21 +391,27 @@
 		inode->i_flags |= S_DIRSYNC;
 	inode->i_generation = EXT2_SB(sb)->s_next_generation++;
 	insert_inode_hash(inode);
-	mark_inode_dirty(inode);
 
 	unlock_super(sb);
-	ret = inode;
 	if(DQUOT_ALLOC_INODE(inode)) {
 		DQUOT_DROP(inode);
-		inode->i_flags |= S_NOQUOTA;
-		inode->i_nlink = 0;
-		iput(inode);
-		ret = ERR_PTR(-EDQUOT);
-	} else {
-		ext2_debug("allocating inode %lu\n", inode->i_ino);
-		ext2_preread_inode(inode);
+		goto fail3;
+	}
+	err = ext2_init_acl(inode, dir);
+	if (err) {
+		DQUOT_FREE_INODE(inode);
+		goto fail3;
 	}
-	goto out;
+	mark_inode_dirty(inode);
+	ext2_debug("allocating inode %lu\n", inode->i_ino);
+	ext2_preread_inode(inode);
+	return inode;
+
+fail3:
+	inode->i_flags |= S_NOQUOTA;
+	inode->i_nlink = 0;
+	iput(inode);
+	return ERR_PTR(err);
 
 fail2:
 	desc = ext2_get_group_desc (sb, group, &bh2);
@@ -420,10 +425,10 @@
 	unlock_super(sb);
 	make_bad_inode(inode);
 	iput(inode);
-	ret = ERR_PTR(err);
-	goto out;
+	return ERR_PTR(err);
 
 bad_count:
+	brelse(bitmap_bh);
 	ext2_error (sb, "ext2_new_inode",
 		    "Free inodes count corrupted in group %d",
 		    group);
@@ -436,9 +441,6 @@
 	desc->bg_free_inodes_count = 0;
 	mark_buffer_dirty(bh2);
 	goto repeat;
-out:
-	brelse(bitmap_bh);
-	return ret;
 }
 
 unsigned long ext2_count_free_inodes (struct super_block * sb)
fs/ext2/inode.c +17 -0
diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
@@ -986,6 +986,8 @@
 	struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
 	int n;
 
+	ei->i_acl = EXT2_ACL_NOT_CACHED;
+	ei->i_default_acl = EXT2_ACL_NOT_CACHED;
 	if (IS_ERR(raw_inode))
  		goto bad_inode;
 
@@ -1174,3 +1176,18 @@
 {
 	return ext2_update_inode (inode, 1);
 }
+
+int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		return error;
+	inode_setattr(inode, iattr);
+	if (iattr->ia_valid & ATTR_MODE)
+		error = ext2_acl_chmod(inode);
+	return error;
+}
+
fs/ext2/namei.c +12 -1
diff -Nru a/fs/ext2/namei.c b/fs/ext2/namei.c
@@ -137,7 +137,10 @@
 	struct inode * inode = ext2_new_inode (dir, mode);
 	int err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
-		init_special_inode(inode, mode, rdev);
+		init_special_inode(inode, inode->i_mode, rdev);
+#ifdef CONFIG_EXT2_FS_EXT_ATTR
+		inode->i_op = &ext2_special_inode_operations;
+#endif
 		mark_inode_dirty(inode);
 		err = ext2_add_nondir(dentry, inode);
 	}
@@ -372,6 +375,10 @@
 	.getxattr	= ext2_getxattr,
 	.listxattr	= ext2_listxattr,
 	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
+	.get_posix_acl	= ext2_get_acl,
+	.set_posix_acl	= ext2_set_acl,
 };
 
 struct inode_operations ext2_special_inode_operations = {
@@ -379,4 +386,8 @@
 	.getxattr	= ext2_getxattr,
 	.listxattr	= ext2_listxattr,
 	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
+	.get_posix_acl	= ext2_get_acl,
+	.set_posix_acl	= ext2_set_acl,
 };
fs/ext2/super.c +47 -1

107 lines not on this page · raw message

fs/ext2/xattr_user.c +0 -4
diff -Nru a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c
@@ -9,10 +9,6 @@
 #include <linux/module.h>
 #include <linux/string.h>
 
-#ifdef CONFIG_EXT2_FS_POSIX_ACL
-# include <linux/ext2_acl.h>
-#endif
-
 #define XATTR_USER_PREFIX "user."
 
 static size_t
include/linux/ext2_acl.h new file +106 -0

106 lines not on this page · raw message

include/linux/ext2_fs.h +1 -0
diff -Nru a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
@@ -308,6 +308,7 @@
 #define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
 #define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
 #define EXT2_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+#define EXT2_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
 
 #define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
 #define set_opt(o, opt)			o |= EXT2_MOUNT_##opt