On Mon, Oct 27, 2014 at 09:09:19AM +0800, Li Xi wrote:
On Mon, Oct 27, 2014 at 5:56 AM, Dave Chinner [off-list ref] wrote:
quoted
On Sun, Oct 26, 2014 at 01:22:53PM +0800, Li Xi wrote:
quoted
This patch adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR ioctl interface
support for ext4. The interface is kept consistent with
XFS_IOC_FSGETXATTR/XFS_IOC_FSGETXATTR.
What you haven't mentioned is that you also changed the fsxattr
interface structure to add functionality and new behaviours that
isn't supported by XFS or existing applications that use the
interface.
There is no need to modify the interface *at all* for ext4 to use
it. Fields that ext4 does not use can be zeroed on getxattr, and
ignored on setxattr - you do not need to add new fields to say what
fields are valid.
Sorry, I don't want to change the interfaces either. But, the problem
is that zero might be valid value for some fields. How can we
distinguish an unsupported attribute and an attribute whose value
is zero?
You don't. Userspace has no concept of what parts of the struct
fsxattr are valid or not, nor what are valid values the filesystem
will accept or reject.
It is common case the only part of the fields are supported.
So, for example, if we don't have valid flags, how can use space
application tell kernel which attributes should be skipped when it
tries to set only a part of atrributes?
It *doesn't*. Userspace requires the kernel to initialise the struct
fsxattr before it tries to modify anything, just like
fcntl(F_[GS]ETFL) and other similar "file flag change" syscall APIs.
IOWs, you have to initialise the struct fsxattr by calling
FS_IOC_FSGETXATTR before you call FS_IOC_FSSETXATTR. The
intialisation sets all the fields to the current (correct) values,
and hence when the set call is made all the fields then have the
same/correct values in them except for what the application changed.
E.g. this code from xfs_quota to clear the project ID on a given
file or directory:
if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1) {
// error handling ....
} else if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx) < 0) {
// error handling ....
}
fsx.fsx_projid = 0;
fsx.fsx_xflags &= ~XFS_XFLAG_PROJINHERIT;
if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx) < 0) {
// error handling ....
}
close(fd);
This ensures that *only* the project ID and the specific project ID
inheritance flag is cleared, and none of the other inode flags or
state are modified....
Cheers,
Dave.
--
Dave Chinner
david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org