Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Tue, Jan 07, 2014 at 11:43:56AM -0800, Darrick J. Wong wrote: > I had thought of indexed inode flags as an alternative to the xattr/string > parsing thing. Feature flags make their first appearance as part of a per-FS > flag-space and are migrated to the common flag-space when there is demand. > It would also avoid the need for each fs to create its own flag ioctl. > > On the other hand, someone suggested I try remaking IOC_[GS]ETFLAG as an > xattr, > so off I went. :) > > #define FS_IOC_FLAGS_COMMON 0 > #define FS_IOC_FLAGS_COMMON2 1 > #define FS_IOC_FLAGS_EXT4 0xEF53 > > struct inode_flag_ioctl { > u32 flag; > u32 value; /* or u64? */ > }; > #define FS_IOC_GETFLAGS2 _IOR('f', 12, struct inode_flag_ioctl); > #define FS_IOC_SETFLAGS2 _IOW('f', 13, struct inode_flag_ioctl); Is having this structure and demultiplexing based on inode_flag_ioctl.flag really worth it? I'd just simply introduce two new ioctl's for generic flags: FS_IOC_COMMON_[GS]ETFLAGS, and then two new ioctl's for each file system: FS_IOC_EXT4_[GS]ETFLAGS, FS_IOC_BTRFS_[GS]ETFLAGS, etc. Is this uglier or pretier than using strings? Eh six of one, half dozen of the other. I think it's mostly a matter of personal taste. - Ted -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Tue, 2014-01-07 at 14:02 -0800, Darrick J. Wong wrote: > On Tue, Jan 07, 2014 at 07:59:15PM +, Chris Mason wrote: > > On Tue, 2014-01-07 at 11:43 -0800, Darrick J. Wong wrote: > > > On Tue, Jan 07, 2014 at 12:04:30PM -0500, Theodore Ts'o wrote: > > > > On Tue, Jan 07, 2014 at 07:49:35AM -0800, Christoph Hellwig wrote: > > > > > On Tue, Jan 07, 2014 at 01:48:31PM +0100, Jan Kara wrote: > > > > > > I have to say I'm not thrilled by the idea of juggling strings in > > > > > > userspace and in kernel to set a flag for an inode... > > > > > > > > > > Nevermind the massive amounts of code that sit in the filesystem. > > > > > > > > The reason for this patch was to address what Dave Chinner has called > > > > "a shitty interface"[1]. Using bitfields that need to be coordinated > > > > across file systems, when sometimes a bit assignment is validly a fs > > > > specific thing, and then later becomes something that gets shared > > > > across file systems. > > > > > > > > [1] http://thread.gmane.org/gmane.linux.file-systems/80164/focus=80396 > > > > > > > > If we don't go about it this way, there are alternatives: we could > > > > create new ioctls (or a new syscall) as we start running out of bits > > > > used by FS_IOC_[GS]ETFLAGS. We can create new ioctls for bits which > > > > are intended for fs-specific flags, which then later get promoted to > > > > the new syscall when some functionality starts to get shared accross > > > > other file systems (probably with a different bit assignment). This > > > > is certainly less code, but it does mean more complexity outside of > > > > the code when we try to coordinate new functionality across file > > > > systems. > > > > > > I had thought of indexed inode flags as an alternative to the xattr/string > > > parsing thing. Feature flags make their first appearance as part of a > > > per-FS > > > flag-space and are migrated to the common flag-space when there is demand. > > > It would also avoid the need for each fs to create its own flag ioctl. > > > > > > On the other hand, someone suggested I try remaking IOC_[GS]ETFLAG as an > > > xattr, > > > so off I went. :) > > > > > > > At least in btrfs xattrs are more expensive than something right in the > > inode. We can cache it when we load the inode (it'll be right next to > > the inode most of the time) but for performance critical things I do > > like the good old fashioned flags. > > Just to clarify -- I wasn't proposing any on-disk changes for any filesystems, > merely creating virtual xattrs that wrap the inode flags. Ah, sorry I missed that part. I was assuming that as we run out of flags we'll want to use real xattrs instead. > > > It's also possible to turn xattrs off, so we have to deal with > > filesystems that are mounted with them off and then back on again. I > > can't think of huge problems from that right now, just something to be > > aware of. > > Just to satisfy my curiosity: are xattrs always separate objects in btrfs? Strictly speaking, yes. They aren't in the inode struct. But most of the time they will be in the same btree block. For anything performance critical we can order the keys to push them to the front. -chris -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Tue, Jan 07, 2014 at 07:59:15PM +, Chris Mason wrote: > On Tue, 2014-01-07 at 11:43 -0800, Darrick J. Wong wrote: > > On Tue, Jan 07, 2014 at 12:04:30PM -0500, Theodore Ts'o wrote: > > > On Tue, Jan 07, 2014 at 07:49:35AM -0800, Christoph Hellwig wrote: > > > > On Tue, Jan 07, 2014 at 01:48:31PM +0100, Jan Kara wrote: > > > > > I have to say I'm not thrilled by the idea of juggling strings in > > > > > userspace and in kernel to set a flag for an inode... > > > > > > > > Nevermind the massive amounts of code that sit in the filesystem. > > > > > > The reason for this patch was to address what Dave Chinner has called > > > "a shitty interface"[1]. Using bitfields that need to be coordinated > > > across file systems, when sometimes a bit assignment is validly a fs > > > specific thing, and then later becomes something that gets shared > > > across file systems. > > > > > > [1] http://thread.gmane.org/gmane.linux.file-systems/80164/focus=80396 > > > > > > If we don't go about it this way, there are alternatives: we could > > > create new ioctls (or a new syscall) as we start running out of bits > > > used by FS_IOC_[GS]ETFLAGS. We can create new ioctls for bits which > > > are intended for fs-specific flags, which then later get promoted to > > > the new syscall when some functionality starts to get shared accross > > > other file systems (probably with a different bit assignment). This > > > is certainly less code, but it does mean more complexity outside of > > > the code when we try to coordinate new functionality across file > > > systems. > > > > I had thought of indexed inode flags as an alternative to the xattr/string > > parsing thing. Feature flags make their first appearance as part of a > > per-FS > > flag-space and are migrated to the common flag-space when there is demand. > > It would also avoid the need for each fs to create its own flag ioctl. > > > > On the other hand, someone suggested I try remaking IOC_[GS]ETFLAG as an > > xattr, > > so off I went. :) > > > > At least in btrfs xattrs are more expensive than something right in the > inode. We can cache it when we load the inode (it'll be right next to > the inode most of the time) but for performance critical things I do > like the good old fashioned flags. Just to clarify -- I wasn't proposing any on-disk changes for any filesystems, merely creating virtual xattrs that wrap the inode flags. > It's also possible to turn xattrs off, so we have to deal with > filesystems that are mounted with them off and then back on again. I > can't think of huge problems from that right now, just something to be > aware of. Just to satisfy my curiosity: are xattrs always separate objects in btrfs? --D > > -chris > > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Tue, 2014-01-07 at 11:43 -0800, Darrick J. Wong wrote: > On Tue, Jan 07, 2014 at 12:04:30PM -0500, Theodore Ts'o wrote: > > On Tue, Jan 07, 2014 at 07:49:35AM -0800, Christoph Hellwig wrote: > > > On Tue, Jan 07, 2014 at 01:48:31PM +0100, Jan Kara wrote: > > > > I have to say I'm not thrilled by the idea of juggling strings in > > > > userspace and in kernel to set a flag for an inode... > > > > > > Nevermind the massive amounts of code that sit in the filesystem. > > > > The reason for this patch was to address what Dave Chinner has called > > "a shitty interface"[1]. Using bitfields that need to be coordinated > > across file systems, when sometimes a bit assignment is validly a fs > > specific thing, and then later becomes something that gets shared > > across file systems. > > > > [1] http://thread.gmane.org/gmane.linux.file-systems/80164/focus=80396 > > > > If we don't go about it this way, there are alternatives: we could > > create new ioctls (or a new syscall) as we start running out of bits > > used by FS_IOC_[GS]ETFLAGS. We can create new ioctls for bits which > > are intended for fs-specific flags, which then later get promoted to > > the new syscall when some functionality starts to get shared accross > > other file systems (probably with a different bit assignment). This > > is certainly less code, but it does mean more complexity outside of > > the code when we try to coordinate new functionality across file > > systems. > > I had thought of indexed inode flags as an alternative to the xattr/string > parsing thing. Feature flags make their first appearance as part of a per-FS > flag-space and are migrated to the common flag-space when there is demand. > It would also avoid the need for each fs to create its own flag ioctl. > > On the other hand, someone suggested I try remaking IOC_[GS]ETFLAG as an > xattr, > so off I went. :) > At least in btrfs xattrs are more expensive than something right in the inode. We can cache it when we load the inode (it'll be right next to the inode most of the time) but for performance critical things I do like the good old fashioned flags. It's also possible to turn xattrs off, so we have to deal with filesystems that are mounted with them off and then back on again. I can't think of huge problems from that right now, just something to be aware of. -chris -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Tue, Jan 07, 2014 at 12:04:30PM -0500, Theodore Ts'o wrote: > On Tue, Jan 07, 2014 at 07:49:35AM -0800, Christoph Hellwig wrote: > > On Tue, Jan 07, 2014 at 01:48:31PM +0100, Jan Kara wrote: > > > I have to say I'm not thrilled by the idea of juggling strings in > > > userspace and in kernel to set a flag for an inode... > > > > Nevermind the massive amounts of code that sit in the filesystem. > > The reason for this patch was to address what Dave Chinner has called > "a shitty interface"[1]. Using bitfields that need to be coordinated > across file systems, when sometimes a bit assignment is validly a fs > specific thing, and then later becomes something that gets shared > across file systems. > > [1] http://thread.gmane.org/gmane.linux.file-systems/80164/focus=80396 > > If we don't go about it this way, there are alternatives: we could > create new ioctls (or a new syscall) as we start running out of bits > used by FS_IOC_[GS]ETFLAGS. We can create new ioctls for bits which > are intended for fs-specific flags, which then later get promoted to > the new syscall when some functionality starts to get shared accross > other file systems (probably with a different bit assignment). This > is certainly less code, but it does mean more complexity outside of > the code when we try to coordinate new functionality across file > systems. I had thought of indexed inode flags as an alternative to the xattr/string parsing thing. Feature flags make their first appearance as part of a per-FS flag-space and are migrated to the common flag-space when there is demand. It would also avoid the need for each fs to create its own flag ioctl. On the other hand, someone suggested I try remaking IOC_[GS]ETFLAG as an xattr, so off I went. :) #define FS_IOC_FLAGS_COMMON 0 #define FS_IOC_FLAGS_COMMON21 #define FS_IOC_FLAGS_EXT4 0xEF53 struct inode_flag_ioctl { u32 flag; u32 value; /* or u64? */ }; #define FS_IOC_GETFLAGS2 _IOR('f', 12, struct inode_flag_ioctl); #define FS_IOC_SETFLAGS2 _IOW('f', 13, struct inode_flag_ioctl); foo() { struct inode_flag_ioctl if; if.flag = FS_IOC_FLAGS_COMMON; ioctl(fd, FS_IOC_GETFLAGS2, &if); printf("%d\n", if.value); if.flag = FS_IOC_FLAGS_EXT4; if.value = EXT5_BONGHITS_FL | EXT4_EA_INODE_FL; ioctl(fd, FS_IOC_SETFLAGS2, &if); } > Personally, I don't mind dealing with codepoint assignments, but my > impression is that this is a minority viewpoint. Al and Linus have > historically hated bitfields, and Al in the past has spoken favorably > of Plan 9's approach of using strings for the system interface. I prefer strings too, but I suppose one pays for the complexity. Given that all the flags so far seem to have been booleans, this could be good enough. > So while I have a preference towards using bitfields, as opposed to > using the xattr approach, what I'd really like is that we make a > decision, one way or another, about what's the best way to move > forward. Agreed. --D > > - Ted > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Tue, Jan 07, 2014 at 07:49:35AM -0800, Christoph Hellwig wrote: > On Tue, Jan 07, 2014 at 01:48:31PM +0100, Jan Kara wrote: > > I have to say I'm not thrilled by the idea of juggling strings in > > userspace and in kernel to set a flag for an inode... > > Nevermind the massive amounts of code that sit in the filesystem. The reason for this patch was to address what Dave Chinner has called "a shitty interface"[1]. Using bitfields that need to be coordinated across file systems, when sometimes a bit assignment is validly a fs specific thing, and then later becomes something that gets shared across file systems. [1] http://thread.gmane.org/gmane.linux.file-systems/80164/focus=80396 If we don't go about it this way, there are alternatives: we could create new ioctls (or a new syscall) as we start running out of bits used by FS_IOC_[GS]ETFLAGS. We can create new ioctls for bits which are intended for fs-specific flags, which then later get promoted to the new syscall when some functionality starts to get shared accross other file systems (probably with a different bit assignment). This is certainly less code, but it does mean more complexity outside of the code when we try to coordinate new functionality across file systems. Personally, I don't mind dealing with codepoint assignments, but my impression is that this is a minority viewpoint. Al and Linus have historically hated bitfields, and Al in the past has spoken favorably of Plan 9's approach of using strings for the system interface. So while I have a preference towards using bitfields, as opposed to using the xattr approach, what I'd really like is that we make a decision, one way or another, about what's the best way to move forward. - Ted -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Tue, Jan 07, 2014 at 01:48:31PM +0100, Jan Kara wrote: > I have to say I'm not thrilled by the idea of juggling strings in > userspace and in kernel to set a flag for an inode... Nevermind the massive amounts of code that sit in the filesystem. Although my recent ACL patches are the first step towards handling the existing semantically overloaded xattrs in common code. Unless Al has a valid reason to disagree I'd like to put a big NAK on adding any new xattrs that aren't stored on disk as-is but provide magic functionality, as they are pain to implement, maintain, and audit. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
On Mon 06-01-14 18:58:55, Darrick J. Wong wrote: > This is a proof of concept interface for replacing the contentious > FS_IOC_[GS]ETFLAGS interface with one that presents itself as the > xattr 'system.iflags'. Instead of using integer inode flags, this > interface uses a comma-separated string of words, such as > "extents,immutable" to describe the inode flags. This ought to enable > all filesystems to introduce arbitrary flags, with any sort of backend > they want, while also taking advantage of generic fs flags. > > The initial conversion is for ext4, though given the similarities of > most filesystems' implementations, converting the rest shouldn't be > difficult. How we get everyone to agree on common flag names is > anyone's guess. > > Includes some helper methods to handle the string<->int conversion, > and a tweak to the generic xattr code to allow setting iflags on an > immutable file. I have to say I'm not thrilled by the idea of juggling strings in userspace and in kernel to set a flag for an inode... Honza > Usage: > # setfattr -n system.iflags -v 'extents,append' /path/file > # getfattr -n system.iflags /path/file > system.iflags="secrm,unrm,sync,immutable,nodump,noatime,journal_data,extents" > > Signed-off-by: Darrick J. Wong > --- > fs/ext4/Makefile |2 > fs/ext4/ext4.h |3 + > fs/ext4/ioctl.c| 198 > > fs/ext4/xattr.c|1 > fs/ext4/xattr.h|1 > fs/ext4/xattr_iflags.c | 90 > fs/xattr.c |9 ++ > include/linux/strflags.h | 27 ++ > include/uapi/linux/xattr.h |2 > lib/Makefile |2 > lib/strflags.c | 117 ++ > 11 files changed, 358 insertions(+), 94 deletions(-) > create mode 100644 fs/ext4/xattr_iflags.c > create mode 100644 include/linux/strflags.h > create mode 100644 lib/strflags.c > > diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile > index 0310fec..7126958 100644 > --- a/fs/ext4/Makefile > +++ b/fs/ext4/Makefile > @@ -8,7 +8,7 @@ ext4-y:= balloc.o bitmap.o dir.o file.o fsync.o > ialloc.o inode.o page-io.o \ > ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ > ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o \ > mmp.o indirect.o extents_status.o xattr.o xattr_user.o \ > - xattr_trusted.o inline.o > + xattr_trusted.o inline.o xattr_iflags.o > > ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o > ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index bf6c5cd..24837ab 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -2660,6 +2660,9 @@ extern void ext4_inline_data_truncate(struct inode > *inode, int *has_inline); > > extern int ext4_convert_inline_data(struct inode *inode); > > +/* ioctl.c */ > +extern int ext4_set_iflags(struct inode *inode, int flags); > + > /* namei.c */ > extern const struct inode_operations ext4_dir_inode_operations; > extern const struct inode_operations ext4_special_inode_operations; > diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c > index 60589b6..c6f21c9 100644 > --- a/fs/ext4/ioctl.c > +++ b/fs/ext4/ioctl.c > @@ -213,12 +213,115 @@ swap_boot_out: > return err; > } > > +/* > + * Set inode flags. Assume we already have mnt_want_write_file and i_mutex. > + */ > +int ext4_set_iflags(struct inode *inode, int flags) > +{ > + handle_t *handle = NULL; > + int err, migrate = 0; > + struct ext4_iloc iloc; > + unsigned int oldflags, mask, i; > + unsigned int jflag; > + struct ext4_inode_info *ei = EXT4_I(inode); > + > + if (!inode_owner_or_capable(inode)) > + return -EACCES; > + > + flags = ext4_mask_flags(inode->i_mode, flags); > + > + err = -EPERM; > + /* Is it quota file? Do not allow user to mess with it */ > + if (IS_NOQUOTA(inode)) > + goto flags_out; > + > + oldflags = ei->i_flags; > + > + /* The JOURNAL_DATA flag is modifiable only by root */ > + jflag = flags & EXT4_JOURNAL_DATA_FL; > + > + /* > + * The IMMUTABLE and APPEND_ONLY flags can only be changed by > + * the relevant capability. > + * > + * This test looks nicer. Thanks to Pauline Middelink > + */ > + if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { > + if (!capable(CAP_LINUX_IMMUTABLE)) > + goto flags_out; > + } > + > + /* > + * The JOURNAL_DATA flag can only be changed by > + * the relevant capability. > + */ > + if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { > + if (!capable(CAP_SYS_RESOURCE)) > + goto flags_out; > + } > + if ((flags ^ oldflags) & EXT4_EXTENTS_FL) > +
[RFC PATCH] fs: xattr-based FS_IOC_[GS]ETFLAGS interface
This is a proof of concept interface for replacing the contentious FS_IOC_[GS]ETFLAGS interface with one that presents itself as the xattr 'system.iflags'. Instead of using integer inode flags, this interface uses a comma-separated string of words, such as "extents,immutable" to describe the inode flags. This ought to enable all filesystems to introduce arbitrary flags, with any sort of backend they want, while also taking advantage of generic fs flags. The initial conversion is for ext4, though given the similarities of most filesystems' implementations, converting the rest shouldn't be difficult. How we get everyone to agree on common flag names is anyone's guess. Includes some helper methods to handle the string<->int conversion, and a tweak to the generic xattr code to allow setting iflags on an immutable file. Usage: # setfattr -n system.iflags -v 'extents,append' /path/file # getfattr -n system.iflags /path/file system.iflags="secrm,unrm,sync,immutable,nodump,noatime,journal_data,extents" Signed-off-by: Darrick J. Wong --- fs/ext4/Makefile |2 fs/ext4/ext4.h |3 + fs/ext4/ioctl.c| 198 fs/ext4/xattr.c|1 fs/ext4/xattr.h|1 fs/ext4/xattr_iflags.c | 90 fs/xattr.c |9 ++ include/linux/strflags.h | 27 ++ include/uapi/linux/xattr.h |2 lib/Makefile |2 lib/strflags.c | 117 ++ 11 files changed, 358 insertions(+), 94 deletions(-) create mode 100644 fs/ext4/xattr_iflags.c create mode 100644 include/linux/strflags.h create mode 100644 lib/strflags.c diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 0310fec..7126958 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -8,7 +8,7 @@ ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \ ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o \ mmp.o indirect.o extents_status.o xattr.o xattr_user.o \ - xattr_trusted.o inline.o + xattr_trusted.o inline.o xattr_iflags.o ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY)+= xattr_security.o diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index bf6c5cd..24837ab 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2660,6 +2660,9 @@ extern void ext4_inline_data_truncate(struct inode *inode, int *has_inline); extern int ext4_convert_inline_data(struct inode *inode); +/* ioctl.c */ +extern int ext4_set_iflags(struct inode *inode, int flags); + /* namei.c */ extern const struct inode_operations ext4_dir_inode_operations; extern const struct inode_operations ext4_special_inode_operations; diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 60589b6..c6f21c9 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -213,12 +213,115 @@ swap_boot_out: return err; } +/* + * Set inode flags. Assume we already have mnt_want_write_file and i_mutex. + */ +int ext4_set_iflags(struct inode *inode, int flags) +{ + handle_t *handle = NULL; + int err, migrate = 0; + struct ext4_iloc iloc; + unsigned int oldflags, mask, i; + unsigned int jflag; + struct ext4_inode_info *ei = EXT4_I(inode); + + if (!inode_owner_or_capable(inode)) + return -EACCES; + + flags = ext4_mask_flags(inode->i_mode, flags); + + err = -EPERM; + /* Is it quota file? Do not allow user to mess with it */ + if (IS_NOQUOTA(inode)) + goto flags_out; + + oldflags = ei->i_flags; + + /* The JOURNAL_DATA flag is modifiable only by root */ + jflag = flags & EXT4_JOURNAL_DATA_FL; + + /* +* The IMMUTABLE and APPEND_ONLY flags can only be changed by +* the relevant capability. +* +* This test looks nicer. Thanks to Pauline Middelink +*/ + if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { + if (!capable(CAP_LINUX_IMMUTABLE)) + goto flags_out; + } + + /* +* The JOURNAL_DATA flag can only be changed by +* the relevant capability. +*/ + if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { + if (!capable(CAP_SYS_RESOURCE)) + goto flags_out; + } + if ((flags ^ oldflags) & EXT4_EXTENTS_FL) + migrate = 1; + + if (flags & EXT4_EOFBLOCKS_FL) { + /* we don't support adding EOFBLOCKS flag */ + if (!(oldflags & EXT4_EOFBLOCKS_FL)) { + err = -EOPNOTSUPP; + goto flags_out; + } + } else if (oldflags & EXT4_EOFBLOCKS_FL) + ext4_truncate(inode); + + handle = ext4_journal_start(inode,