Add extended attributes to ext2/3
Subsystems (2)
PATCH 4/4 Add extended attributes to ext2/3
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.
- Ted
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
#
# fs/Config.help | 7 # fs/Config.in | 1 # fs/ext2/Makefile | 6 # fs/ext2/ext2.h | 3 # fs/ext2/file.c | 4 # fs/ext2/ialloc.c | 1 # fs/ext2/inode.c | 38 - # fs/ext2/namei.c | 13 # fs/ext2/super.c | 18 # fs/ext2/symlink.c | 13 # fs/ext2/xattr.c | 1208 ++++++++++++++++++++++++++++++++++++++++ # fs/ext2/xattr_user.c | 100 +++ # include/linux/ext2_fs.h | 28 - # include/linux/ext2_xattr.h | 135 +++++
# 14 files changed, 1531 insertions(+), 44 deletions(-) #
# The following is the BitKeeper ChangeSet Log # --------------------------------------------
# 02/10/14 [email protected] 1.786
# Port of (bugfixed) 0.8.50 xattr-ext2 to 2.5 #
# -------------------------------------------- #
fs/Config.help +7 -0
@@ -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_bool ' Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT3_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 +3 -0
@@ -1,5 +1,6 @@#include <linux/fs.h> #include <linux/ext2_fs.h> +#include <linux/ext2_xattr.h> /* * second extended file system inode data in memory
@@ -110,6 +111,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 +4 -0
@@ -55,4 +55,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 +1 -0
@@ -97,6 +97,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 -16
@@ -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;
@@ -1024,9 +1035,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;
@@ -1035,15 +1044,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 ;
@@ -1075,11 +1086,6 @@if (IS_ERR (raw_inode))return -EIO ; -if (ino ==EXT2_ACL_IDX_INO || ino ==EXT2_ACL_DATA_INO ) { -ext2_error (sb,"ext2_write_inode" ,"bad inode number: %lu" , 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 +12 -1
@@ -162,7 +162,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 +368,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 +17 -1
@@ -131,6 +131,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;
@@ -233,6 +234,13 @@continue ;if ((value =strchr (this_char,'=' )) !=NULL ) *value++ =0 ; +#ifdef CONFIG_EXT2_FS_XATTR +if (!strcmp (this_char,"user_xattr" )) +set_opt (*mount_options,XATTR_USER ); +else if (!strcmp (this_char,"nouser_xattr" )) +clear_opt (*mount_options,XATTR_USER ); + else +#endif if (!strcmp (this_char,"bsddf" ))clear_opt (*mount_options,MINIX_DF );else if (!strcmp (this_char,"nouid32" )) {
@@ -487,6 +495,9 @@*/ sbi->s_mount_opt =0 ; +#ifdef CONFIG_EXT2_FS_XATTR +set_opt (EXT2_SB (sb)->s_mount_opt,XATTR_USER ); +#endif if (!parse_options ((char *) data, &sb_block, &resuid, &resgid, &sbi->s_mount_opt)) goto failed_sbi;
@@ -883,7 +894,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);
@@ -893,6 +907,7 @@ out:destroy_inodecache (); out1: +exit_ext2_xattr ();return err; }
@@ -900,6 +915,7 @@ {unregister_filesystem (&ext2_fs_type);destroy_inodecache (); +exit_ext2_xattr (); }module_init (init_ext2_fs)
fs/ext2/symlink.c +13 -0
@@ -31,7 +31,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 +1208 -0
1,208 lines not on this page · raw message
fs/ext2/xattr_user.c new file +100 -0
100 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
@@ -475,7 +451,7 @@#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008#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#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
include/linux/ext2_xattr.h new file +135 -0
135 lines not on this page · raw message
Quoted 4 lines · [email protected] writes:
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.in line 96
Quoted 8 lines
diff -Nru a/fs/Config.in b/fs/Config.in
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_bool ' Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT3_FS
^^^
Is this intentional?
Regards, Olaf.
Quoted 10 lines · Olaf Dietsche
fs/Config.in line 96
Quoted 8 lines
diff -Nru a/fs/Config.in b/fs/Config.in
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_bool ' Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT3_FS^^^Is this intentional?
Nope, that's a typo. Thanks for catching it.
- Ted