ext2/3 updates for 2.5.44 (6/11): ext2 xattr support
Subsystems (2)
PATCH 1/1 ext2/3 updates for 2.5.44 (6/11): ext2 xattr support
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/10/20 [email protected] 1.815
# Port of (bugfixed) 0.8.50 xattr-ext2 to 2.5 (w/ hch cleanups. mbcache API) #
# This patch adds extended attribute support to the ext2 filesystem. This
# uses the generic extended attribute patch which was developed by Andreas # Gruenbacher and the XFS team. As a result, the user space utilities # which work for XFS will also work with these patches. # -------------------------------------------- # # fs/Config.help | 7 # fs/Config.in | 1 # fs/ext2/Makefile | 6 # fs/ext2/ext2.h | 2 # fs/ext2/file.c | 7 # fs/ext2/ialloc.c | 4 # fs/ext2/inode.c | 39 - # fs/ext2/namei.c | 16 # fs/ext2/super.c | 20 # fs/ext2/symlink.c | 14 # fs/ext2/xattr.c | 1118 ++++++++++++++++++++++++++++++++++++++++++++++++ # fs/ext2/xattr.h | 135 +++++ # fs/ext2/xattr_user.c | 98 ++++ # include/linux/ext2_fs.h | 28 - # 14 files changed, 1446 insertions(+), 49 deletions(-) # diff -Nru a/fs/Config.help b/fs/Config.help --- a/fs/Config.help Sun Oct 20 04:41:19 2002 +++ b/fs/Config.help Sun Oct 20 04:41:19 2002 @@ -123,6 +123,13 @@ be compiled as a module, and so this could be dangerous. Most everyone wants to say Y here.
+CONFIG_EXT2_FS_XATTR
+ Extended attributes are name:value pairs associated with inodes by + the kernel or by users (see the attr(5) manual page, or visit + <http://acl.bestbits.at/> for details).
+
+ If unsure, say N.
+
CONFIG_EXT3_FS
This is the journaling version of the Second extended file system (often called ext3), the de facto standard Linux file system
fs/Config.in +1 -0
@@ -93,6 +93,7 @@ tristate 'ROM file system support' CONFIG_ROMFS_FS tristate 'Second extended fs support' CONFIG_EXT2_FS +dep_mbool ' Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
fs/ext2/Makefile +6 -0
@@ -7,4 +7,10 @@ ext2-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 + +ifeq ($(CONFIG_EXT2_FS_XATTR),y) +ext2-objs += xattr.o xattr_user.o +endif + include $(TOPDIR)/Rules.make
fs/ext2/ext2.h +2 -0
@@ -117,6 +117,8 @@/* namei.c */ extern struct inode_operations ext2_dir_inode_operations; +extern struct inode_operations ext2_special_inode_operations;/* symlink.c */ extern struct inode_operations ext2_fast_symlink_inode_operations; +extern struct inode_operations ext2_symlink_inode_operations;
fs/ext2/file.c +6 -1
@@ -18,8 +18,9 @@* ([email protected]) */ -#include "ext2.h" #include <linux/time.h> +#include "ext2.h" +#include "xattr.h" /* * Called when an inode is released. Note that this is different
@@ -55,4 +56,8 @@struct inode_operations ext2_file_inode_operations = { .truncate = ext2_truncate, + .setxattr = ext2_setxattr, + .getxattr = ext2_getxattr, + .listxattr = ext2_listxattr, + .removexattr = ext2_removexattr, };
fs/ext2/ialloc.c +3 -1
@@ -13,11 +13,12 @@*/ #include <linux/config.h> -#include "ext2.h" #include <linux/quotaops.h> #include <linux/sched.h> #include <linux/backing-dev.h> #include <linux/buffer_head.h> +#include "ext2.h" +#include "xattr.h" /* * ialloc.c contains the inodes allocation and deallocation routines
@@ -97,6 +98,7 @@*/ if (!is_bad_inode (inode)) {/* Quota is already initialized in iput() */ +ext2_xattr_delete_inode (inode);DQUOT_FREE_INODE (inode);DQUOT_DROP (inode); }
fs/ext2/inode.c +22 -17
@@ -39,6 +39,18 @@static int ext2_update_inode (struct inode * inode,int do_sync);/* +* Test whether an inode is a fast symlink. +*/ +static inline int ext2_inode_is_fast_symlink (struct inode *inode) +{ +int ea_blocks =EXT2_I (inode)->i_file_acl ? + (inode->i_sb->s_blocksize >>9 ) :0 ; + +return (S_ISLNK (inode->i_mode) && + inode->i_blocks - ea_blocks ==0 ); +} + +/* * Called at each iput() */ void ext2_put_inode (struct inode * inode)
@@ -51,9 +63,7 @@*/ void ext2_delete_inode (struct inode * inode) { -if (is_bad_inode (inode) || - inode->i_ino ==EXT2_ACL_IDX_INO || - inode->i_ino ==EXT2_ACL_DATA_INO ) +if (is_bad_inode (inode)) goto no_delete;EXT2_I (inode)->i_dtime =CURRENT_TIME ;mark_inode_dirty (inode);
@@ -843,6 +853,8 @@if (!(S_ISREG (inode->i_mode) ||S_ISDIR (inode->i_mode) ||S_ISLNK (inode->i_mode)))return ; +if (ext2_inode_is_fast_symlink (inode)) +return ;if (IS_APPEND (inode) ||IS_IMMUTABLE (inode))return ;
@@ -929,8 +941,7 @@struct ext2_group_desc * gdp; *p =NULL ; -if ((ino !=EXT2_ROOT_INO && ino !=EXT2_ACL_IDX_INO && - ino !=EXT2_ACL_DATA_INO && ino <EXT2_FIRST_INO (sb)) || +if ((ino !=EXT2_ROOT_INO && ino <EXT2_FIRST_INO (sb)) || ino >le32_to_cpu (EXT2_SB (sb)->s_es->s_inodes_count)) goto Einval;
@@ -1026,9 +1037,7 @@for (n =0 ; n <EXT2_N_BLOCKS ; n++) ei->i_data[n] = raw_inode->i_block[n]; -if (ino ==EXT2_ACL_IDX_INO || ino ==EXT2_ACL_DATA_INO ) -/* Nothing to do */ ; -else if (S_ISREG (inode->i_mode)) { +if (S_ISREG (inode->i_mode)) { inode->i_op = &ext2_file_inode_operations; inode->i_fop = &ext2_file_operations; inode->i_mapping->a_ops = &ext2_aops;
@@ -1037,15 +1046,17 @@ inode->i_fop = &ext2_dir_operations; inode->i_mapping->a_ops = &ext2_aops; }else if (S_ISLNK (inode->i_mode)) { -if (!inode->i_blocks) +if (ext2_inode_is_fast_symlink (inode)) inode->i_op = &ext2_fast_symlink_inode_operations;else { - inode->i_op = &page_symlink_inode_operations; + inode->i_op = &ext2_symlink_inode_operations; inode->i_mapping->a_ops = &ext2_aops; } - }else + }else { + inode->i_op = &ext2_special_inode_operations;init_special_inode (inode, inode->i_mode,le32_to_cpu (raw_inode->i_block[0 ])); + }brelse (bh);if (ei->i_flags &EXT2_SYNC_FL ) inode->i_flags |=S_SYNC ;
@@ -1082,12 +1093,6 @@if (ei->i_state &EXT2_STATE_NEW )memset (raw_inode,0 ,EXT2_SB (sb)->s_inode_size); -if (ino ==EXT2_ACL_IDX_INO || ino ==EXT2_ACL_DATA_INO ) { -ext2_error (sb,"ext2_write_inode" ,"bad inode number: %lu" , - (unsigned long ) ino); -brelse (bh); -return -EIO ; - } raw_inode->i_mode =cpu_to_le16 (inode->i_mode);if (!(test_opt (sb,NO_UID32 ))) { raw_inode->i_uid_low =cpu_to_le16 (low_16_bits (uid));
fs/ext2/namei.c +14 -2
@@ -29,8 +29,9 @@* David S. Miller ([email protected]), 1995 */ -#include "ext2.h" #include <linux/pagemap.h> +#include "ext2.h" +#include "xattr.h" /* * Couple of helper functions - make the code slightly cleaner.
@@ -162,7 +163,7 @@if (l >sizeof (EXT2_I (inode)->i_data)) {/* slow symlink */ - inode->i_op = &page_symlink_inode_operations; + inode->i_op = &ext2_symlink_inode_operations; inode->i_mapping->a_ops = &ext2_aops; err =page_symlink (inode, symname, l);if (err)
@@ -368,4 +369,15 @@ .rmdir = ext2_rmdir, .mknod = ext2_mknod, .rename = ext2_rename, + .setxattr = ext2_setxattr, + .getxattr = ext2_getxattr, + .listxattr = ext2_listxattr, + .removexattr = ext2_removexattr, +}; + +struct inode_operations ext2_special_inode_operations = { + .setxattr = ext2_setxattr, + .getxattr = ext2_getxattr, + .listxattr = ext2_listxattr, + .removexattr = ext2_removexattr, };
fs/ext2/super.c +18 -2
@@ -19,7 +19,6 @@#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> -#include "ext2.h" #include <linux/slab.h> #include <linux/init.h> #include <linux/blkdev.h>
@@ -27,6 +26,8 @@#include <linux/buffer_head.h> #include <linux/smp_lock.h> #include <asm/uaccess.h> +#include "ext2.h" +#include "xattr.h" static void ext2_sync_super(struct super_block *sb,
@@ -127,6 +128,7 @@int i;struct ext2_sb_info *sbi =EXT2_SB (sb); +ext2_xattr_put_super (sb);if (!(sb->s_flags &MS_RDONLY )) {struct ext2_super_block *es = sbi->s_es;
@@ -278,6 +280,13 @@continue ;if ((value =strchr (this_char,'=' )) !=NULL ) *value++ =0 ; +#ifdef CONFIG_EXT2_FS_XATTR +if (!strcmp (this_char,"user_xattr" )) +set_opt (sbi->s_mount_opt,XATTR_USER ); +else if (!strcmp (this_char,"nouser_xattr" )) +clear_opt (sbi->s_mount_opt,XATTR_USER ); + else +#endif if (!strcmp (this_char,"bsddf" ))clear_opt (sbi->s_mount_opt,MINIX_DF );else if (!strcmp (this_char,"nouid32" )) {
@@ -560,6 +569,8 @@set_opt (sbi->s_mount_opt,GRPID );if (def_mount_opts &EXT2_DEFM_UID16 )set_opt (sbi->s_mount_opt,NO_UID32 ); +if (def_mount_opts &EXT2_DEFM_XATTR_USER ) +set_opt (sbi->s_mount_opt,XATTR_USER );if (le16_to_cpu (sbi->s_es->s_errors) ==EXT2_ERRORS_PANIC )set_opt (sbi->s_mount_opt,ERRORS_PANIC );
@@ -917,7 +928,10 @@static int __init init_ext2_fs (void ) { -int err =init_inodecache (); +int err =init_ext2_xattr (); +if (err) +return err; + err =init_inodecache ();if (err) goto out1; err =register_filesystem (&ext2_fs_type);
@@ -927,6 +941,7 @@ out:destroy_inodecache (); out1: +exit_ext2_xattr ();return err; }
@@ -934,6 +949,7 @@ {unregister_filesystem (&ext2_fs_type);destroy_inodecache (); +exit_ext2_xattr (); }module_init (init_ext2_fs)
fs/ext2/symlink.c +14 -0
@@ -18,6 +18,7 @@*/ #include "ext2.h" +#include "xattr.h" static int ext2_readlink (struct dentry *dentry,char *buffer,int buflen) {
@@ -31,7 +32,20 @@return vfs_follow_link (nd, (char *)ei->i_data); } +struct inode_operations ext2_symlink_inode_operations = { + .readlink = page_readlink, + .follow_link = page_follow_link, + .setxattr = ext2_setxattr, + .getxattr = ext2_getxattr, + .listxattr = ext2_listxattr, + .removexattr = ext2_removexattr, +}; +struct inode_operations ext2_fast_symlink_inode_operations = { .readlink = ext2_readlink, .follow_link = ext2_follow_link, + .setxattr = ext2_setxattr, + .getxattr = ext2_getxattr, + .listxattr = ext2_listxattr, + .removexattr = ext2_removexattr, };
fs/ext2/xattr.c new file +1118 -0
1,118 lines not on this page · raw message
fs/ext2/xattr.h new file +135 -0
135 lines not on this page · raw message
fs/ext2/xattr_user.c new file +98 -0
98 lines not on this page · raw message
include/linux/ext2_fs.h +2 -26
@@ -58,8 +58,6 @@*/ #define EXT2_BAD_INO 1/* Bad blocks inode */ #define EXT2_ROOT_INO 2/* Root inode */ -#define EXT2_ACL_IDX_INO 3/* ACL inode */ -#define EXT2_ACL_DATA_INO 4/* ACL inode */ #define EXT2_BOOT_LOADER_INO 5/* Boot loader inode */ #define EXT2_UNDEL_DIR_INO 6/* Undelete directory inode */
@@ -99,7 +97,6 @@#else # define EXT2_BLOCK_SIZE (s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)#endif -#define EXT2_ACLE_PER_BLOCK (s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))#define EXT2_ADDR_PER_BLOCK (s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))#ifdef __KERNEL__# define EXT2_BLOCK_SIZE_BITS (s) ((s)->s_blocksize_bits)
@@ -134,28 +131,6 @@#endif /* -* ACL structures -*/ -struct ext2_acl_header /* Header of Access Control Lists */ -{ -__u32 aclh_size; -__u32 aclh_file_count; -__u32 aclh_acle_count; -__u32 aclh_first_acle; -}; - -struct ext2_acl_entry /* Access Control List Entry */ -{ -__u32 acle_size; -__u16 acle_perms;/* Access permissions */ -__u16 acle_type;/* Type of entry */ -__u16 acle_tag;/* User or group identity */ -__u16 acle_pad1; -__u32 acle_next;/* Pointer on next entry for the */ -/* same inode or on next free entry */ -}; - -/* * Structure of a blocks group descriptor */ struct ext2_group_desc
@@ -332,6 +307,7 @@#define EXT2_MOUNT_ERRORS_PANIC 0x0040/* Panic on errors */ #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 clear_opt (o, opt) o &= ~EXT2_MOUNT_##opt#define set_opt (o, opt) o |= EXT2_MOUNT_##opt
@@ -489,7 +465,7 @@#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010#define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff -#define EXT2_FEATURE_COMPAT_SUPP 0 +#define EXT2_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ EXT2_FEATURE_INCOMPAT_META_BG)#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \