Skip to contentSkip to conversation

ACL support for ext2/3

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

lore
Share & tools
lore
#0 lore raw

RFC PATCH 4/5 ACL support for ext2/3

This patch adds ACL support to the ext3 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/ext3/Makefile          |    2 
# fs/ext3/acl.c             |  609 ++++++++++++++++++++++++++++++++++++++++++++++
# fs/ext3/file.c            |    4 
# fs/ext3/ialloc.c          |   32 +-
# fs/ext3/inode.c           |   36 ++
# fs/ext3/namei.c           |   14 -
# fs/ext3/super.c           |   50 +++
# include/linux/ext3_acl.h  |  109 ++++++++
# include/linux/ext3_fs.h   |    1 
# include/linux/ext3_fs_i.h |    4 

# 12 files changed, 844 insertions(+), 20 deletions(-) #
# The following is the BitKeeper ChangeSet Log # --------------------------------------------
# 02/10/09 [email protected] 1.672
# Port 0.8.50 acl-ext3 patch to 2.5
# -------------------------------------------- #

fs/Config.help +2 -0
diff -Nru a/fs/Config.help b/fs/Config.help
@@ -197,6 +197,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 ext3.
+
   If unsure, say N.
 
 Ext3 extended attribute block sharing
fs/Config.in +1 -0
diff -Nru a/fs/Config.in b/fs/Config.in
@@ -33,6 +33,7 @@
   define_tristate CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
   define_bool CONFIG_EXT3_FS_XATTR_SHARING y
   define_bool CONFIG_EXT3_FS_XATTR_USER y
+  define_bool CONFIG_EXT3_FS_POSIX_ACL y
 fi
 # CONFIG_JBD could be its own option (even modular), but until there are
 # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
fs/ext3/Makefile +1 -1
diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile
@@ -7,8 +7,8 @@
 ext3-objs    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
 		ioctl.o namei.o super.o symlink.o
 
-export-objs += xattr.o
 obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
 obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
+obj-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
 
 include $(TOPDIR)/Rules.make
fs/ext3/acl.c new file +609 -0

609 lines not on this page · raw message

fs/ext3/file.c +4 -0
diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c
@@ -23,6 +23,7 @@
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_xattr.h>
+#include <linux/ext3_acl.h>
 #include <linux/ext3_jbd.h>
 #include <linux/smp_lock.h>
 
@@ -97,5 +98,8 @@
 	.getxattr	= ext3_getxattr,
 	.listxattr	= ext3_listxattr,
 	.removexattr	= ext3_removexattr,
+	.permission	= ext3_permission,
+	.get_posix_acl	= ext3_get_acl,
+	.set_posix_acl	= ext3_set_acl,
 };
 
fs/ext3/ialloc.c +23 -9
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
@@ -18,6 +18,7 @@
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
 #include <linux/ext3_xattr.h>
+#include <linux/ext3_acl.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/quotaops.h>
@@ -422,20 +423,27 @@
 	inode->i_generation = EXT3_SB(sb)->s_next_generation++;
 
 	ei->i_state = EXT3_STATE_NEW;
-	err = ext3_mark_inode_dirty(handle, inode);
-	if (err) goto fail;
-	
+
 	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 {
-		ext3_debug("allocating inode %lu\n", inode->i_ino);
+		err = -EDQUOT;
+		goto fail2;
 	}
+	err = ext3_init_acl(handle, inode, dir);
+	if (err) {
+		DQUOT_FREE_INODE(inode);
+		goto fail2;
+  	}
+	err = ext3_mark_inode_dirty(handle, inode);
+	if (err) {
+		ext3_std_error(sb, err);
+		DQUOT_FREE_INODE(inode);
+		goto fail2;
+	}
+
+	ext3_debug("allocating inode %lu\n", inode->i_ino);
 	goto really_out;
 fail:
 	ext3_std_error(sb, err);
@@ -446,6 +454,12 @@
 really_out:
 	brelse(bitmap_bh);
 	return ret;
+
+fail2:
+	inode->i_flags |= S_NOQUOTA;
+	inode->i_nlink = 0;
+	iput(inode);
+	return ERR_PTR(err);
 }
 
 /* Verify that we are loading a valid orphan from disk */
fs/ext3/inode.c +28 -8
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
@@ -27,6 +27,8 @@
 #include <linux/time.h>
 #include <linux/ext3_jbd.h>
 #include <linux/jbd.h>
+#include <linux/ext3_xattr.h>
+#include <linux/ext3_acl.h>
 #include <linux/smp_lock.h>
 #include <linux/highuid.h>
 #include <linux/pagemap.h>
@@ -2205,7 +2207,11 @@
 	struct buffer_head *bh;
 	int block;
 	
-	if(ext3_get_inode_loc(inode, &iloc))
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	ei->i_acl = EXT3_ACL_NOT_CACHED;
+	ei->i_default_acl = EXT3_ACL_NOT_CACHED;
+#endif
+	if (ext3_get_inode_loc(inode, &iloc))
 		goto bad_inode;
 	bh = iloc.bh;
 	raw_inode = iloc.raw_inode;
@@ -2501,13 +2507,8 @@
  * be freed, so we have a strong guarantee that no future commit will
  * leave these blocks visible to the user.)  
  *
- * This is only needed for regular files.  rmdir() has its own path, and
- * we can never truncate a direcory except on final unlink (at which
- * point i_nlink is zero so recovery is easy.)
- *
- * Called with the BKL.  
+ * Called with inode->sem down.
  */
-
 int ext3_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = dentry->d_inode;
@@ -2527,7 +2528,8 @@
 
 	lock_kernel();
 
-	if (attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
+	if (S_ISREG(inode->i_mode) &&
+	    attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
 		handle_t *handle;
 
 		handle = ext3_journal_start(inode, 3);
@@ -2545,12 +2547,30 @@
 	}
 	
 	rc = inode_setattr(inode, attr);
+	if (!error)
+		error = rc;
 
 	/* If inode_setattr's call to ext3_truncate failed to get a
 	 * transaction handle at all, we need to clean up the in-core
 	 * orphan list manually. */
 	if (inode->i_nlink)
 		ext3_orphan_del(NULL, inode);
+
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	if (!error && test_opt(inode->i_sb, POSIX_ACL) && (ia_valid & ATTR_MODE)) {
+		handle_t *handle;
+
+		handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
+		if (IS_ERR(handle)) {
+			error = PTR_ERR(handle);
+			goto err_out;
+		}
+		error = ext3_acl_chmod(handle, inode);
+		rc = ext3_journal_stop(handle, inode);
+		if (!error)
+			error = rc;
+	}
+#endif
 
 err_out:
 	ext3_std_error(inode->i_sb, error);
fs/ext3/namei.c +13 -1
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
@@ -24,6 +24,7 @@
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
 #include <linux/ext3_xattr.h>
+#include <linux/ext3_acl.h>
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/string.h>
@@ -543,7 +544,10 @@
 	inode = ext3_new_inode (handle, dir, mode);
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
-		init_special_inode(inode, mode, rdev);
+		init_special_inode(inode, inode->i_mode, rdev);
+#ifdef CONFIG_EXT3_FS_XATTR
+		inode->i_op = &ext3_special_inode_operations;
+#endif
 		err = ext3_add_nondir(handle, dentry, inode);
 		ext3_mark_inode_dirty(handle, inode);
 	}
@@ -1200,17 +1204,25 @@
 	.rmdir		= ext3_rmdir,
 	.mknod		= ext3_mknod,
 	.rename		= ext3_rename,
+	.setattr	= ext3_setattr,
 	.setxattr	= ext3_setxattr,	
 	.getxattr	= ext3_getxattr,	
 	.listxattr	= ext3_listxattr,	
 	.removexattr	= ext3_removexattr,
+	.permission	= ext3_permission,
+	.get_posix_acl	= ext3_get_acl,
+	.set_posix_acl	= ext3_set_acl,
 };
 
 struct inode_operations ext3_special_inode_operations = {
+	.setattr	= ext3_setattr,
 	.setxattr	= ext3_setxattr,
 	.getxattr	= ext3_getxattr,
 	.listxattr	= ext3_listxattr,
 	.removexattr	= ext3_removexattr,
+	.permission	= ext3_permission,
+	.get_posix_acl	= ext3_get_acl,
+	.set_posix_acl	= ext3_set_acl,
 };
 
  
fs/ext3/super.c +49 -1

115 lines not on this page · raw message

include/linux/ext3_acl.h new file +109 -0

109 lines not on this page · raw message

include/linux/ext3_fs.h +1 -0
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
@@ -317,6 +317,7 @@
 #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
 #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
 #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+#define EXT3_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
 
 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
 #ifndef _LINUX_EXT2_FS_H
include/linux/ext3_fs_i.h +4 -0
diff -Nru a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
@@ -41,6 +41,10 @@
 	__u32	i_prealloc_count;
 #endif
 	__u32	i_dir_start_lookup;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	struct posix_acl	*i_acl;
+	struct posix_acl	*i_default_acl;
+#endif
 	
 	struct list_head i_orphan;	/* unlinked but open inodes */