Skip to contentSkip to conversation

ext2/3 updates for 2.5.44 (10/11): ext3 acl support

PATCH New [email protected] 1 participant 1 message Oct 20, 2002 VFS

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ext2/3 updates for 2.5.44 (10/11): ext3 acl support

# The following is the BitKeeper ChangeSet Log # --------------------------------------------
# 02/10/20 [email protected] 1.819
# Port of (bugfixed) 0.8.50 acl-ext3 to 2.5. #
# This patch adds ACL support to the ext3 filesystem. # -------------------------------------------- #

# fs/Config.help            |   11 
# fs/Config.in              |    1 
# fs/ext3/Makefile          |    4 
# fs/ext3/acl.c             |  590 ++++++++++++++++++++++++++++++++++++++++++++++
# fs/ext3/acl.h             |   87 ++++++
# fs/ext3/file.c            |    2 
# fs/ext3/ialloc.c          |   32 +-
# fs/ext3/inode.c           |   21 +
# fs/ext3/namei.c           |   11 
# fs/ext3/super.c           |   41 +++
# fs/ext3/xattr.c           |   23 +
# include/linux/ext3_fs.h   |    1 
# include/linux/ext3_fs_i.h |    4 

# 13 files changed, 805 insertions(+), 23 deletions(-) #

fs/Config.help +11 -0
diff -Nru a/fs/Config.help b/fs/Config.help
@@ -166,7 +166,18 @@
   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.
+
+CONFIG_EXT3_FS_POSIX_ACL
+  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_JBD
   This is a generic journaling layer for block devices.  It is
fs/Config.in +1 -0
diff -Nru a/fs/Config.in b/fs/Config.in
@@ -28,6 +28,7 @@
 
 tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
 dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
+dep_mbool '  Ext3 POSIX Access Control Lists' CONFIG_EXT3_FS_POSIX_ACL $CONFIG_EXT3_FS_XATTR $CONFIG_FS_POSIX_ACL
 # 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
 # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
fs/ext3/Makefile +4 -0
diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile
@@ -13,4 +13,8 @@
 ext3-objs += xattr.o xattr_user.o
 endif
 
+ifeq ($(CONFIG_EXT3_FS_POSIX_ACL),y)
+ext3-objs += acl.o
+endif
+
 include $(TOPDIR)/Rules.make
fs/ext3/acl.c new file +590 -0

590 lines not on this page · raw message

fs/ext3/acl.h new file +87 -0

87 lines not on this page · raw message

fs/ext3/file.c +2 -0
diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c
@@ -24,6 +24,7 @@
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
 #include "xattr.h"
+#include "acl.h"
 
 /*
  * Called when an inode is released. Note that this is different
@@ -102,5 +103,6 @@
 	.getxattr	= ext3_getxattr,
 	.listxattr	= ext3_listxattr,
 	.removexattr	= ext3_removexattr,
+	.permission	= ext3_permission,
 };
 
fs/ext3/ialloc.c +23 -9
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
@@ -26,6 +26,7 @@
 #include <asm/byteorder.h>
 
 #include "xattr.h"
+#include "acl.h"
 
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
@@ -423,20 +424,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);
@@ -447,6 +455,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 +13 -8
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
@@ -34,6 +34,8 @@
 #include <linux/string.h>
 #include <linux/buffer_head.h>
 #include <linux/mpage.h>
+#include "xattr.h"
+#include "acl.h"
 
 /*
  * SEARCH_FROM_ZERO forces each block allocation to search from the start
@@ -2199,7 +2201,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;
@@ -2491,13 +2497,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;
@@ -2517,7 +2518,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);
@@ -2541,6 +2543,9 @@
 	 * orphan list manually. */
 	if (inode->i_nlink)
 		ext3_orphan_del(NULL, inode);
+
+	if (!rc && (ia_valid & ATTR_MODE))
+		rc = ext3_acl_chmod(inode);
 
 err_out:
 	ext3_std_error(inode->i_sb, error);
fs/ext3/namei.c +9 -2
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
@@ -37,7 +37,7 @@
 #include <linux/buffer_head.h>
 #include <linux/smp_lock.h>
 #include "xattr.h"
-
+#include "acl.h"
 
 /*
  * define how far ahead to read directories while searching them.
@@ -1624,7 +1624,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);
 	}
@@ -2281,17 +2284,21 @@
 	.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,
 };
 
 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,
 };
 
  
fs/ext3/super.c +41 -0

89 lines not on this page · raw message

fs/ext3/xattr.c +19 -4
diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
@@ -61,6 +61,7 @@
 #include <linux/quotaops.h>
 #include <asm/semaphore.h>
 #include "xattr.h"
+#include "acl.h"
 
 #define EXT3_EA_USER "user."
 
@@ -1105,15 +1106,27 @@
 	err = ext3_xattr_register(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
 	if (err)
 		return err;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	err = init_ext3_acl();
+	if (err)
+		goto out;
+#endif
 	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
 		sizeof(struct mb_cache_entry) +
 		sizeof(struct mb_cache_entry_index), 1, 6);
 	if (!ext3_xattr_cache) {
-		ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out1;
 	}
-
 	return 0;
+out1:
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	exit_ext3_acl();
+out:
+#endif
+	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
+			      &ext3_xattr_user_handler);
+	return err;
 }
 
 void
@@ -1122,6 +1135,8 @@
 	if (ext3_xattr_cache)
 		mb_cache_destroy(ext3_xattr_cache);
 	ext3_xattr_cache = NULL;
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+	exit_ext3_acl();
+#endif
 	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler);
 }
-
include/linux/ext3_fs.h +1 -0
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
@@ -323,6 +323,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 */