Skip to contentSkip to conversation

Posix ACL support for ext 2/3 filesystems

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

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

PATCH 5/5 Posix ACL support for ext 2/3 filesystems

This patch adds ACL support to the ext2 filesystem.

- Ted

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.801 -> 1.802
# fs/ext2/inode.c 1.48 -> 1.49
# include/linux/ext2_fs.h 1.12 -> 1.13

#	     fs/ext2/xattr.c	1.1     -> 1.2    
#	      fs/ext2/file.c	1.10    -> 1.11   
#	    fs/ext2/ialloc.c	1.22    -> 1.23   
#	     fs/ext2/super.c	1.32    -> 1.33   
#	        fs/Config.in	1.44    -> 1.45   
#	    fs/ext2/Makefile	1.4     -> 1.5    
#	      fs/Config.help	1.24    -> 1.25   
#	     fs/ext2/namei.c	1.15    -> 1.16   
#	fs/ext2/xattr_user.c	1.1     -> 1.2    
#	      fs/ext2/ext2.h	1.11    -> 1.12   
#	               (new)	        -> 1.1     fs/ext2/acl.h  
#	               (new)	        -> 1.1     fs/ext2/acl.c  

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

fs/Config.help +11 -0
diff -Nru a/fs/Config.help b/fs/Config.help
@@ -128,7 +128,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 ext2.
+
   If unsure, say N.
+
+CONFIG_EXT2_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_EXT3_FS
   This is the journaling version of the Second extended file system
fs/Config.in +1 -0
diff -Nru a/fs/Config.in b/fs/Config.in
@@ -95,6 +95,7 @@
 
 tristate 'Second extended fs support' CONFIG_EXT2_FS
 dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
+dep_mbool '  Ext2 POSIX Access Control Lists' CONFIG_EXT2_FS_POSIX_ACL $CONFIG_EXT2_FS_XATTR $CONFIG_FS_POSIX_ACL
 
 tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
 
fs/ext2/Makefile +4 -0
diff -Nru a/fs/ext2/Makefile b/fs/ext2/Makefile
@@ -13,4 +13,8 @@
 ext2-objs += xattr.o xattr_user.o
 endif
 
+ifeq ($(CONFIG_EXT2_FS_POSIX_ACL),y)
+ext2-objs += acl.o
+endif
+
 include $(TOPDIR)/Rules.make
fs/ext2/acl.c new file +576 -0

576 lines not on this page · raw message

fs/ext2/acl.h new file +88 -0

88 lines not on this page · raw message

fs/ext2/ext2.h +5 -0
diff -Nru a/fs/ext2/ext2.h b/fs/ext2/ext2.h
@@ -19,6 +19,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;
 };
@@ -78,6 +82,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 +3 -0
diff -Nru a/fs/ext2/file.c b/fs/ext2/file.c
@@ -21,6 +21,7 @@
 #include <linux/time.h>
 #include "ext2.h"
 #include "xattr.h"
+#include "acl.h"
 
 /*
  * Called when an inode is released. Note that this is different
@@ -60,4 +61,6 @@
 	.getxattr	= ext2_getxattr,
 	.listxattr	= ext2_listxattr,
 	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
 };
fs/ext2/ialloc.c +20 -17
diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
@@ -19,6 +19,7 @@
 #include <linux/buffer_head.h>
 #include "ext2.h"
 #include "xattr.h"
+#include "acl.h"
 
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
@@ -302,7 +303,6 @@
 	struct ext2_super_block * es;
 	struct ext2_inode_info *ei;
 	int err;
-	struct inode *ret;
 
 	sb = dir->i_sb;
 	inode = new_inode(sb);
@@ -323,7 +323,6 @@
 		goto fail;
 
 	err = -EIO;
-	brelse(bitmap_bh);
 	bitmap_bh = read_inode_bitmap(sb, group);
 	if (!bitmap_bh)
 		goto fail2;
@@ -339,6 +338,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)) {
@@ -394,21 +394,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);
@@ -422,10 +428,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);
@@ -438,9 +444,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 +21 -1
diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
@@ -22,7 +22,6 @@
  *  Assorted race fixes, rewrite of ext2_get_block() by Al Viro, 2000
  */
 
-#include "ext2.h"
 #include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/highuid.h>
@@ -31,6 +30,8 @@
 #include <linux/module.h>
 #include <linux/buffer_head.h>
 #include <linux/mpage.h>
+#include "ext2.h"
+#include "acl.h"
 
 MODULE_AUTHOR("Remy Card and others");
 MODULE_DESCRIPTION("Second Extended Filesystem");
@@ -982,6 +983,10 @@
 	struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
 	int n;
 
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	ei->i_acl = EXT2_ACL_NOT_CACHED;
+	ei->i_default_acl = EXT2_ACL_NOT_CACHED;
+#endif
 	if (IS_ERR(raw_inode))
  		goto bad_inode;
 
@@ -1170,3 +1175,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 +9 -1
diff -Nru a/fs/ext2/namei.c b/fs/ext2/namei.c
@@ -32,6 +32,7 @@
 #include <linux/pagemap.h>
 #include "ext2.h"
 #include "xattr.h"
+#include "acl.h"
 
 /*
  * Couple of helper functions - make the code slightly cleaner.
@@ -138,7 +139,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);
 	}
@@ -373,6 +377,8 @@
 	.getxattr	= ext2_getxattr,
 	.listxattr	= ext2_listxattr,
 	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
 };
 
 struct inode_operations ext2_special_inode_operations = {
@@ -380,4 +386,6 @@
 	.getxattr	= ext2_getxattr,
 	.listxattr	= ext2_listxattr,
 	.removexattr	= ext2_removexattr,
+	.setattr	= ext2_setattr,
+	.permission	= ext2_permission,
 };
fs/ext2/super.c +43 -1

90 lines not on this page · raw message

fs/ext2/xattr.c +19 -2
diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c
@@ -60,6 +60,7 @@
 #include <asm/semaphore.h>
 #include "ext2.h"
 #include "xattr.h"
+#include "acl.h"
 
 /* These symbols may be needed by a module. */
 EXPORT_SYMBOL(ext2_xattr_register);
@@ -1100,19 +1101,35 @@
 	err = ext2_xattr_register(EXT2_XATTR_INDEX_USER, &ext2_xattr_user_handler);
 	if (err)
 		return err;
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	err = init_ext2_acl();
+	if (err)
+		goto out;
+#endif
 	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
 		sizeof(struct mb_cache_entry) +
 		sizeof(struct mb_cache_entry_index), 1, 6);
 	if (!ext2_xattr_cache) {
-		ext2_xattr_unregister(EXT2_XATTR_INDEX_USER, &ext2_xattr_user_handler);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out1;
 	}
 	return 0;
+out1:
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	exit_ext2_acl();
+out:
+#endif
+	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
+			      &ext2_xattr_user_handler);
+	return err;
 }
 
 void
 exit_ext2_xattr(void)
 {
 	mb_cache_destroy(ext2_xattr_cache);
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+	exit_ext2_acl();
+#endif
 	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER, &ext2_xattr_user_handler);
 }
fs/ext2/xattr_user.c +1 -5
diff -Nru a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c
@@ -10,11 +10,7 @@
 #include <linux/string.h>
 #include "ext2.h"
 #include "xattr.h"
-
-
-#ifdef CONFIG_EXT2_FS_POSIX_ACL
-# include <linux/ext2_acl.h>
-#endif
+#include "acl.h"
 
 #define XATTR_USER_PREFIX "user."
 
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