diff mbox

[5/6] statx: Make windows attributes available for CIFS, NTFS and FAT to use

Message ID 20160429125813.23636.49830.stgit@warthog.procyon.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

David Howells April 29, 2016, 12:58 p.m. UTC
Make windows attributes available for CIFS, NTFS and FAT to use in the
statx struct.  The attribute flags map directly by value to those in the
CIFS PDU flags.  Some of these bits can also be used by JFS, UFS and HPFS.

The statx struct acquires:

	__u32	st_win_attrs;

The value in this is present if STATX_WIN_ATTRS is set.

The defined flags in this are:

	STATX_WIN_ATTR_READONLY
	STATX_WIN_ATTR_HIDDEN
	STATX_WIN_ATTR_SYSTEM
	STATX_WIN_ATTR_DIRECTORY
	STATX_WIN_ATTR_ARCHIVE
	STATX_WIN_ATTR_NORMAL
	STATX_WIN_ATTR_TEMPORARY
	STATX_WIN_ATTR_SPARSE_FILE
	STATX_WIN_ATTR_REPARSE_POINT
	STATX_WIN_ATTR_COMPRESSED
	STATX_WIN_ATTR_OFFLINE
	STATX_WIN_ATTR_NOT_CONTENT_INDEXED
	STATX_WIN_ATTR_ENCRYPTED
	STATX_WIN_ATTR_INTEGRITY_STREAM
	STATX_WIN_ATTR_NO_SCRUB_DATA

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/stat.c                  |    5 ++++-
 include/uapi/linux/stat.h  |   30 ++++++++++++++++++++++++++++--
 samples/statx/test-statx.c |   31 +++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 3 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Andreas Dilger May 2, 2016, 10:52 p.m. UTC | #1
On Apr 29, 2016, at 6:58 AM, David Howells <dhowells@redhat.com> wrote:
> 
> Make windows attributes available for CIFS, NTFS and FAT to use in the
> statx struct.  The attribute flags map directly by value to those in the
> CIFS PDU flags.  Some of these bits can also be used by JFS, UFS and HPFS.
> 
> The statx struct acquires:
> 
> 	__u32	st_win_attrs;

It seems some of these flags are duplicated with the st_information field,
and some are duplicate with FS_IOC_GETFLAGS values, and returning the same
information in multiple ways is confusing.

If these flags are part of the CIFS protocol, and are directly usable by
Samba then I can understand we wouldn't want to change them once in the
kernel and then convert them back in userspace, but I'm a bit reluctant
to have flags only for CIFS/NTFS/FAT that might also be useful for other filesystems.  Would we want to be able to get translated st_win_attrs
flags in ext4 attrs when it is being exported by Samba?

> The value in this is present if STATX_WIN_ATTRS is set.
> 
> The defined flags in this are:
> 
> 	STATX_WIN_ATTR_READONLY
> 	STATX_WIN_ATTR_HIDDEN
> 	STATX_WIN_ATTR_SYSTEM
> 	STATX_WIN_ATTR_DIRECTORY

How does this differ from (st_mode & S_IFMT) == S_IFDIR)?

> 	STATX_WIN_ATTR_ARCHIVE
> 	STATX_WIN_ATTR_NORMAL

How does this differ from (st_mode & S_IFMT) == S_IFREG)?

> 	STATX_WIN_ATTR_TEMPORARY

How does this differ from STATX_INFO_TEMPORARY?

> 	STATX_WIN_ATTR_SPARSE_FILE
> 	STATX_WIN_ATTR_REPARSE_POINT
> 	STATX_WIN_ATTR_COMPRESSED
> 	STATX_WIN_ATTR_OFFLINE
> 	STATX_WIN_ATTR_NOT_CONTENT_INDEXED
> 	STATX_WIN_ATTR_ENCRYPTED

How does this differ from STATX_INFO_ENCRYPTED?

Cheers, Andreas

> 	STATX_WIN_ATTR_INTEGRITY_STREAM
> 	STATX_WIN_ATTR_NO_SCRUB_DATA
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
> fs/stat.c                  |    5 ++++-
> include/uapi/linux/stat.h  |   30 ++++++++++++++++++++++++++++--
> samples/statx/test-statx.c |   31 +++++++++++++++++++++++++++++++
> 3 files changed, 63 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/stat.c b/fs/stat.c
> index c2f8370dab13..1552bff154e6 100644
> --- a/fs/stat.c
> +++ b/fs/stat.c
> @@ -83,6 +83,7 @@ int vfs_xgetattr_nosec(struct path *path, struct kstat *stat)
> 
> 	stat->result_mask = 0;
> 	stat->information = 0;
> +	stat->win_attrs = 0;
> 	if (inode->i_op->getattr)
> 		return inode->i_op->getattr(path->mnt, path->dentry, stat);
> 
> @@ -643,7 +644,9 @@ static long statx_set_result(struct kstat *stat, struct statx __user *buffer)
> 	    __put_user(stat->blocks,		&buffer->st_blocks	) ||
> 	    __put_user(stat->version,		&buffer->st_version	) ||
> 	    __put_user(stat->gen,		&buffer->st_gen		) ||
> -	    __clear_user(&buffer->__spare1, sizeof(buffer->__spare1)))
> +	    __put_user(stat->win_attrs,		&buffer->st_win_attrs	) ||
> +	    __clear_user(&buffer->__spare1,
> +			 sizeof(buffer->__spare1) + sizeof(buffer->__spare2)))
> 		return -EFAULT;
> 
> 	return 0;
> diff --git a/include/uapi/linux/stat.h b/include/uapi/linux/stat.h
> index 55ce6607dab6..64729b0785bf 100644
> --- a/include/uapi/linux/stat.h
> +++ b/include/uapi/linux/stat.h
> @@ -106,7 +106,10 @@ struct statx {
> 	__u32	st_dev_major;	/* ID of device containing file [uncond] */
> 	__u32	st_dev_minor;
> 	/* 0x80 */
> -	__u64	__spare1[16];	/* Spare space for future expansion */
> +	__u32	st_win_attrs;	/* Windows file attributes */
> +	__u32	__spare1[3];
> +	/* 0x90 */
> +	__u64	__spare2[14];	/* Spare space for future expansion */
> 	/* 0x100 */
> };
> 
> @@ -133,7 +136,8 @@ struct statx {
> #define STATX_BTIME		0x00000800U	/* Want/got st_btime */
> #define STATX_VERSION		0x00001000U	/* Want/got st_version */
> #define STATX_GEN		0x00002000U	/* Want/got st_gen */
> -#define STATX_ALL_STATS		0x00003fffU	/* All supported stats */
> +#define STATX_WIN_ATTRS		0x00004000U	/* Want/got st_win_attrs */
> +#define STATX_ALL_STATS		0x00007fffU	/* All supported stats */
> 
> /*
>  * Flags to be found in st_information
> @@ -151,4 +155,26 @@ struct statx {
> #define STATX_INFO_AUTODIR		0x00000040U /* Dir provides unlisted automounts */
> #define STATX_INFO_NONSYSTEM_OWNERSHIP	0x00000080U /* File has non-system ownership details */
> 
> +/*
> + * Flags to be found in st_win_attrs.
> + *
> + * These give information about the state of a file on a Windows filesystem
> + * (such as. FAT, NTFS, CIFS).  These values are borrowed from the CIFS fs.
> + */
> +#define STATX_WIN_ATTR_READONLY			0x00000001
> +#define STATX_WIN_ATTR_HIDDEN			0x00000002
> +#define STATX_WIN_ATTR_SYSTEM			0x00000004
> +#define STATX_WIN_ATTR_DIRECTORY		0x00000010
> +#define STATX_WIN_ATTR_ARCHIVE			0x00000020
> +#define STATX_WIN_ATTR_NORMAL			0x00000080
> +#define STATX_WIN_ATTR_TEMPORARY		0x00000100
> +#define STATX_WIN_ATTR_SPARSE_FILE		0x00000200
> +#define STATX_WIN_ATTR_REPARSE_POINT		0x00000400
> +#define STATX_WIN_ATTR_COMPRESSED		0x00000800
> +#define STATX_WIN_ATTR_OFFLINE			0x00001000
> +#define STATX_WIN_ATTR_NOT_CONTENT_INDEXED	0x00002000
> +#define STATX_WIN_ATTR_ENCRYPTED		0x00004000
> +#define STATX_WIN_ATTR_INTEGRITY_STREAM		0x00008000
> +#define STATX_WIN_ATTR_NO_SCRUB_DATA		0x00020000
> +
> #endif /* _UAPI_LINUX_STAT_H */
> diff --git a/samples/statx/test-statx.c b/samples/statx/test-statx.c
> index 38ef23c12e7d..86eac7d16c32 100644
> --- a/samples/statx/test-statx.c
> +++ b/samples/statx/test-statx.c
> @@ -134,6 +134,37 @@ static void dump_statx(struct statx *stx)
> 	if (stx->st_mask & STATX_GEN)
> 		printf("Inode gen   : %xh\n", stx->st_gen);
> 
> +	if (stx->st_mask & STATX_WIN_ATTRS) {
> +		unsigned char bits;
> +		int loop, byte;
> +
> +		static char wattr_representation[32 + 1] =
> +			/* STATX_WIN_ATTR_ flags: */
> +			"????????"	/* 31-24	0x00000000-ff000000 */
> +			"??????N?"	/* 23-16	0x00000000-00ff0000 */
> +			"ieNocrst"	/* 15- 8	0x00000000-0000ff00 */
> +			"n?Ad?SHR"	/*  7- 0	0x00000000-000000ff */
> +			;
> +
> +		printf("Win attrs  : %08llx (",
> +		       (unsigned long long)stx->st_win_attrs);
> +		for (byte = 32 - 8; byte >= 0; byte -= 8) {
> +			bits = stx->st_win_attrs >> byte;
> +			for (loop = 7; loop >= 0; loop--) {
> +				int bit = byte + loop;
> +
> +				if (bits & 0x80)
> +					putchar(wattr_representation[31 - bit]);
> +				else
> +					putchar('-');
> +				bits <<= 1;
> +			}
> +			if (byte)
> +				putchar(' ');
> +		}
> +		printf(")\n");
> +	}
> +
> 	if (stx->st_information) {
> 		unsigned char bits;
> 		int loop, byte;
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Cheers, Andreas
David Howells May 3, 2016, 8:23 p.m. UTC | #2
Andreas Dilger <adilger@dilger.ca> wrote:

> > 	__u32	st_win_attrs;
> 
> It seems some of these flags are duplicated with the st_information field,
> and some are duplicate with FS_IOC_GETFLAGS values, and returning the same
> information in multiple ways is confusing.
>
> If these flags are part of the CIFS protocol,

They're part of the Windows API.  CIFS/SMB and NTFS have them at the same
values.

> and are directly usable by Samba then I can understand we wouldn't want to
> change them once in the kernel and then convert them back in userspace, but
> I'm a bit reluctant to have flags only for CIFS/NTFS/FAT that might also be
> useful for other filesystems.

Where said "other filesystems" have some support for Windows or OS/2 and have
bits defined that map directly in semantics, if not in value, to these bits.

JFS, for example, has IREADONLY, IHIDDEN, ISYSTEM, IDIRECTORY, IARCHIVE and
ISPARSE.

> Would we want to be able to get translated
> st_win_attrs flags in ext4 attrs when it is being exported by Samba?

Actually, I was thinking of proposing an ext4 patch that stored windows flags
in a separate word in the inode on disk.  There isn't sufficient bit space to
map all the windows flags to FS_IOC_GETFLAGS.  However, as you say, there is a
certain amount of overlap...

David
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Christoph Hellwig May 8, 2016, 8:39 a.m. UTC | #3
On Fri, Apr 29, 2016 at 01:58:14PM +0100, David Howells wrote:
> Make windows attributes available for CIFS, NTFS and FAT to use in the
> statx struct.  The attribute flags map directly by value to those in the
> CIFS PDU flags.  Some of these bits can also be used by JFS, UFS and HPFS.

Err, no way.  Not that I disagree that some of these might be useful,
but we should define our own set of flags, which would include the
generic part of the IOC_GETFLAGS flags amd whatever we want to add to
them.  And we should probably go for 64-bit flags while we're at it.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Steve French Oct. 3, 2016, 9:03 p.m. UTC | #4
On Mon, May 2, 2016 at 5:52 PM, Andreas Dilger <adilger@dilger.ca> wrote:
> On Apr 29, 2016, at 6:58 AM, David Howells <dhowells@redhat.com> wrote:
>>
>> Make windows attributes available for CIFS, NTFS and FAT to use in the
>> statx struct.  The attribute flags map directly by value to those in the
>> CIFS PDU flags.  Some of these bits can also be used by JFS, UFS and HPFS.
>>
>> The statx struct acquires:
>>
>>       __u32   st_win_attrs;
>
> It seems some of these flags are duplicated with the st_information field,
> and some are duplicate with FS_IOC_GETFLAGS values, and returning the same
> information in multiple ways is confusing.
>
> If these flags are part of the CIFS protocol, and are directly usable by
> Samba then I can understand we wouldn't want to change them once in the
> kernel and then convert them back in userspace, but I'm a bit reluctant
> to have flags only for CIFS/NTFS/FAT that might also be useful for other filesystems.  Would we want to be able to get translated st_win_attrs
> flags in ext4 attrs when it is being exported by Samba?

It could be useful to have them in statx in an fs neutral way (and
could be implemented by CIFS/NTFS/FAT and probably NFS), but I am ok
with doing this via file system specific xattrs as we do now: NTFS has
an ntfs specific pseudo-xattr for these and for birth time (and now
cifs with recent patches can return the SMB3 inode attributes,
including the older DOS attributes noted below).  Samba server also
stores them in an xattr (although they ndr encode them so it is not
useful to us in the kernel) in local file systems.  NFS v4 (and later)
can also return (in theory) some of these flags but they are optional.

>> The value in this is present if STATX_WIN_ATTRS is set.
>>
>> The defined flags in this are:
>>
>>       STATX_WIN_ATTR_READONLY
>>       STATX_WIN_ATTR_HIDDEN
>>       STATX_WIN_ATTR_SYSTEM
>>       STATX_WIN_ATTR_DIRECTORY
>
> How does this differ from (st_mode & S_IFMT) == S_IFDIR)?
>
>>       STATX_WIN_ATTR_ARCHIVE
>>       STATX_WIN_ATTR_NORMAL
>
> How does this differ from (st_mode & S_IFMT) == S_IFREG)?
>
>>       STATX_WIN_ATTR_TEMPORARY
>
> How does this differ from STATX_INFO_TEMPORARY?
>
>>       STATX_WIN_ATTR_SPARSE_FILE
>>       STATX_WIN_ATTR_REPARSE_POINT
>>       STATX_WIN_ATTR_COMPRESSED
>>       STATX_WIN_ATTR_OFFLINE
>>       STATX_WIN_ATTR_NOT_CONTENT_INDEXED
>>       STATX_WIN_ATTR_ENCRYPTED
>
> How does this differ from STATX_INFO_ENCRYPTED?

As you noted, directory, compressed, encrypted overlap with existing
posix file type (directory vs. file) and FS_IOC_FLAGS (although
cifs.ko does not allow you to set encrypted yet as we do with
compressed through the IOC flags, I could add a patch for setting the
encrypted flag since it should be trivial as it does not affect
reads/writes/open/close over the network fs since the file would be
only encrypted at rest on the server fs)
diff mbox

Patch

diff --git a/fs/stat.c b/fs/stat.c
index c2f8370dab13..1552bff154e6 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -83,6 +83,7 @@  int vfs_xgetattr_nosec(struct path *path, struct kstat *stat)
 
 	stat->result_mask = 0;
 	stat->information = 0;
+	stat->win_attrs = 0;
 	if (inode->i_op->getattr)
 		return inode->i_op->getattr(path->mnt, path->dentry, stat);
 
@@ -643,7 +644,9 @@  static long statx_set_result(struct kstat *stat, struct statx __user *buffer)
 	    __put_user(stat->blocks,		&buffer->st_blocks	) ||
 	    __put_user(stat->version,		&buffer->st_version	) ||
 	    __put_user(stat->gen,		&buffer->st_gen		) ||
-	    __clear_user(&buffer->__spare1, sizeof(buffer->__spare1)))
+	    __put_user(stat->win_attrs,		&buffer->st_win_attrs	) ||
+	    __clear_user(&buffer->__spare1,
+			 sizeof(buffer->__spare1) + sizeof(buffer->__spare2)))
 		return -EFAULT;
 
 	return 0;
diff --git a/include/uapi/linux/stat.h b/include/uapi/linux/stat.h
index 55ce6607dab6..64729b0785bf 100644
--- a/include/uapi/linux/stat.h
+++ b/include/uapi/linux/stat.h
@@ -106,7 +106,10 @@  struct statx {
 	__u32	st_dev_major;	/* ID of device containing file [uncond] */
 	__u32	st_dev_minor;
 	/* 0x80 */
-	__u64	__spare1[16];	/* Spare space for future expansion */
+	__u32	st_win_attrs;	/* Windows file attributes */
+	__u32	__spare1[3];
+	/* 0x90 */
+	__u64	__spare2[14];	/* Spare space for future expansion */
 	/* 0x100 */
 };
 
@@ -133,7 +136,8 @@  struct statx {
 #define STATX_BTIME		0x00000800U	/* Want/got st_btime */
 #define STATX_VERSION		0x00001000U	/* Want/got st_version */
 #define STATX_GEN		0x00002000U	/* Want/got st_gen */
-#define STATX_ALL_STATS		0x00003fffU	/* All supported stats */
+#define STATX_WIN_ATTRS		0x00004000U	/* Want/got st_win_attrs */
+#define STATX_ALL_STATS		0x00007fffU	/* All supported stats */
 
 /*
  * Flags to be found in st_information
@@ -151,4 +155,26 @@  struct statx {
 #define STATX_INFO_AUTODIR		0x00000040U /* Dir provides unlisted automounts */
 #define STATX_INFO_NONSYSTEM_OWNERSHIP	0x00000080U /* File has non-system ownership details */
 
+/*
+ * Flags to be found in st_win_attrs.
+ *
+ * These give information about the state of a file on a Windows filesystem
+ * (such as. FAT, NTFS, CIFS).  These values are borrowed from the CIFS fs.
+ */
+#define STATX_WIN_ATTR_READONLY			0x00000001
+#define STATX_WIN_ATTR_HIDDEN			0x00000002
+#define STATX_WIN_ATTR_SYSTEM			0x00000004
+#define STATX_WIN_ATTR_DIRECTORY		0x00000010
+#define STATX_WIN_ATTR_ARCHIVE			0x00000020
+#define STATX_WIN_ATTR_NORMAL			0x00000080
+#define STATX_WIN_ATTR_TEMPORARY		0x00000100
+#define STATX_WIN_ATTR_SPARSE_FILE		0x00000200
+#define STATX_WIN_ATTR_REPARSE_POINT		0x00000400
+#define STATX_WIN_ATTR_COMPRESSED		0x00000800
+#define STATX_WIN_ATTR_OFFLINE			0x00001000
+#define STATX_WIN_ATTR_NOT_CONTENT_INDEXED	0x00002000
+#define STATX_WIN_ATTR_ENCRYPTED		0x00004000
+#define STATX_WIN_ATTR_INTEGRITY_STREAM		0x00008000
+#define STATX_WIN_ATTR_NO_SCRUB_DATA		0x00020000
+
 #endif /* _UAPI_LINUX_STAT_H */
diff --git a/samples/statx/test-statx.c b/samples/statx/test-statx.c
index 38ef23c12e7d..86eac7d16c32 100644
--- a/samples/statx/test-statx.c
+++ b/samples/statx/test-statx.c
@@ -134,6 +134,37 @@  static void dump_statx(struct statx *stx)
 	if (stx->st_mask & STATX_GEN)
 		printf("Inode gen   : %xh\n", stx->st_gen);
 
+	if (stx->st_mask & STATX_WIN_ATTRS) {
+		unsigned char bits;
+		int loop, byte;
+
+		static char wattr_representation[32 + 1] =
+			/* STATX_WIN_ATTR_ flags: */
+			"????????"	/* 31-24	0x00000000-ff000000 */
+			"??????N?"	/* 23-16	0x00000000-00ff0000 */
+			"ieNocrst"	/* 15- 8	0x00000000-0000ff00 */
+			"n?Ad?SHR"	/*  7- 0	0x00000000-000000ff */
+			;
+
+		printf("Win attrs  : %08llx (",
+		       (unsigned long long)stx->st_win_attrs);
+		for (byte = 32 - 8; byte >= 0; byte -= 8) {
+			bits = stx->st_win_attrs >> byte;
+			for (loop = 7; loop >= 0; loop--) {
+				int bit = byte + loop;
+
+				if (bits & 0x80)
+					putchar(wattr_representation[31 - bit]);
+				else
+					putchar('-');
+				bits <<= 1;
+			}
+			if (byte)
+				putchar(' ');
+		}
+		printf(")\n");
+	}
+
 	if (stx->st_information) {
 		unsigned char bits;
 		int loop, byte;