linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] fs: Add support for Windows file attributes
@ 2025-02-16 16:40 Pali Rohár
  2025-02-16 16:40 ` [RFC PATCH 1/4] fs: Add FS_XFLAG_COMPRESSED & FS_XFLAG_ENCRYPTED for FS_IOC_FS[GS]ETXATTR API Pali Rohár
                   ` (3 more replies)
  0 siblings, 4 replies; 33+ messages in thread
From: Pali Rohár @ 2025-02-16 16:40 UTC (permalink / raw)
  To: Amir Goldstein, Darrick J. Wong, ronnie sahlberg, Chuck Lever,
	Christian Brauner, Jan Kara, Steve French, Alexander Viro
  Cc: linux-fsdevel, linux-cifs, linux-kernel

This is RFC patch series, first attempt to implement support for
additional file attributes via FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR
ioctl APIs, which are used by Windows applications and Windows
filesystems. It is not final, nor precise implementation, it is mean to
show how the API can look like and how it can be used. Please let me
know what do you think about it, if it is the right direction, or how to
move forward.

This RFC patch series contains API definition, VFS integration and
implementation only for SMB client / cifs.ko filesystem. Note that
cifs.ko does not set S_IMMUTABLE flag on local inode because
enforcement of immutable flag has to be done on server.

Design of this API comes from slightly longer discussion:
https://lore.kernel.org/linux-fsdevel/20241227121508.nofy6bho66pc5ry5@pali/t/#u

And conclusion was to abandon any idea of xattr APIs and uses
exclusively only the FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR ioctls.

There is no statx API extension yet.

Simple test client attrs which uses this new API is bellow.

$ cat attrs.c
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#define FS_XFLAG_IMMUTABLEUSER	0x00000004
#define FS_XFLAG_COMPRESSED	0x00020000
#define FS_XFLAG_ENCRYPTED	0x00040000
#define FS_XFLAG_CHECKSUMS	0x00080000
#define FS_XFLAG_HASEXTFIELDS	0x40000000

#define FS_XFLAG2_HIDDEN	0x0001
#define FS_XFLAG2_SYSTEM	0x0002
#define FS_XFLAG2_ARCHIVE	0x0004
#define FS_XFLAG2_TEMPORARY	0x0008
#define FS_XFLAG2_NOTINDEXED	0x0010
#define FS_XFLAG2_NOSCRUBDATA	0x0020
#define FS_XFLAG2_OFFLINE	0x0040
#define FS_XFLAG2_PINNED	0x0080
#define FS_XFLAG2_UNPINNED	0x0100

int main(int argc, char *argv[]) {
	struct fsxattr fsxattr;
	int bit, is2, set;
	int fd;

	if (argc != 2 && argc != 3) {
		printf("Usage %s path [+|-attr]\n", argv[0]);
		return 1;
	}

	if (argc == 3) {
		if (argv[2][0] != '-' && argv[2][0] != '+') {
			printf("Attr must start with + or -\n");
			return 1;
		}
		set = argv[2][0] == '+';
		is2 = 1;
		if (strcmp(&argv[2][1], "readonly") == 0)
			bit = FS_XFLAG_IMMUTABLEUSER, is2 = 0;
		else if (strcmp(&argv[2][1], "hidden") == 0)
			bit = FS_XFLAG2_HIDDEN;
		else if (strcmp(&argv[2][1], "system") == 0)
			bit = FS_XFLAG2_SYSTEM;
		else if (strcmp(&argv[2][1], "archive") == 0)
			bit = FS_XFLAG2_ARCHIVE;
		else if (strcmp(&argv[2][1], "temporary") == 0)
			bit = FS_XFLAG2_TEMPORARY;
		else if (strcmp(&argv[2][1], "compressed") == 0)
			bit = FS_XFLAG_COMPRESSED, is2 = 0;
		else if (strcmp(&argv[2][1], "offline") == 0)
			bit = FS_XFLAG2_OFFLINE;
		else if (strcmp(&argv[2][1], "notindexed") == 0)
			bit = FS_XFLAG2_NOTINDEXED;
		else if (strcmp(&argv[2][1], "encrypted") == 0)
			bit = FS_XFLAG_ENCRYPTED, is2 = 0;
		else if (strcmp(&argv[2][1], "integrity") == 0)
			bit = FS_XFLAG_CHECKSUMS, is2 = 0;
		else if (strcmp(&argv[2][1], "noscrubdata") == 0)
			bit = FS_XFLAG2_NOSCRUBDATA;
		else if (strcmp(&argv[2][1], "pinned") == 0)
			bit = FS_XFLAG2_PINNED;
		else if (strcmp(&argv[2][1], "unpinned") == 0)
			bit = FS_XFLAG2_UNPINNED;
		else {
			printf("Unknown attr '%s'\n", &argv[2][1]);
			return 1;
		}
	}

	fd = open(argv[1], O_RDONLY | O_NONBLOCK);
	if (fd < 0) {
		printf("Cannot open '%s': %s\n", argv[1], strerror(errno));
		return 1;
	}

	if (ioctl(fd, FS_IOC_FSGETXATTR, &fsxattr) != 0) {
		printf("FS_IOC_FSGETXATTR for '%s' failed: %s\n", argv[1], strerror(errno));
		return 1;
	}

	if (!(fsxattr.fsx_xflags & FS_XFLAG_HASEXTFIELDS)) {
		printf("FS_XFLAG_HASEXTFIELDS is not supported\n");
		return 1;
	}

	if (argc == 2) {
		printf("readonly=%d\n", !!(fsxattr.fsx_xflags & FS_XFLAG_IMMUTABLEUSER));
		printf("hidden=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_HIDDEN));
		printf("system=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_SYSTEM));
		printf("archive=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_ARCHIVE));
		printf("temporary=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_TEMPORARY));
		printf("compressed=%d\n", !!(fsxattr.fsx_xflags & FS_XFLAG_COMPRESSED));
		printf("offline=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_OFFLINE));
		printf("notindexed=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_NOTINDEXED));
		printf("encrypted=%d\n", !!(fsxattr.fsx_xflags & FS_XFLAG_ENCRYPTED));
		printf("integrity=%d\n", !!(fsxattr.fsx_xflags & FS_XFLAG_CHECKSUMS));
		printf("noscrubdata=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_NOSCRUBDATA));
		printf("pinned=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_PINNED));
		printf("unpinned=%d\n", !!(*(__u16 *)&fsxattr.fsx_pad[0] & FS_XFLAG2_UNPINNED));
		return 0;
	}

	if (is2) {
		if (set)
			*(__u16 *)&fsxattr.fsx_pad[0] |= bit; /* fsx2_xflags */
		else
			*(__u16 *)&fsxattr.fsx_pad[0] &= ~bit; /* fsx2_xflags */
		*(__u16 *)&fsxattr.fsx_pad[2] = bit; /* fsx_xflags2_mask */
		*(__u32 *)&fsxattr.fsx_pad[4] = 0; /* fsx_xflags_mask */
	} else {
		if (set)
			fsxattr.fsx_xflags |= bit;
		else
			fsxattr.fsx_xflags &= ~bit;
		*(__u32 *)&fsxattr.fsx_pad[4] = bit; /* fsx_xflags_mask */
		*(__u16 *)&fsxattr.fsx_pad[2] = 0; /* fsx_xflags2_mask */
	}

	if (ioctl(fd, FS_IOC_FSSETXATTR, &fsxattr) != 0) {
		printf("FS_IOC_FSSETXATTR for '%s' failed: %s\n", argv[1], strerror(errno));
		return 1;
	}

	return 0;
}


Pali Rohár (4):
  fs: Add FS_XFLAG_COMPRESSED & FS_XFLAG_ENCRYPTED for
    FS_IOC_FS[GS]ETXATTR API
  fs: Extend FS_IOC_FS[GS]ETXATTR API for Windows attributes
  fs: Implement support for fsx_xflags_mask, fsx_xflags2 and
    fsx_xflags2_mask into vfs
  cifs: Implement FS_IOC_FS[GS]ETXATTR API for Windows attributes

 fs/btrfs/ioctl.c          |   9 +-
 fs/efivarfs/inode.c       |   3 +-
 fs/ext2/ioctl.c           |   2 +-
 fs/ext4/ioctl.c           |   2 +-
 fs/f2fs/file.c            |   2 +-
 fs/fuse/ioctl.c           |  13 ++-
 fs/gfs2/file.c            |  14 ++-
 fs/hfsplus/inode.c        |   3 +-
 fs/ioctl.c                |  73 +++++++++++++--
 fs/jfs/ioctl.c            |  14 ++-
 fs/nilfs2/ioctl.c         |   2 +-
 fs/ntfs3/file.c           |   3 +-
 fs/ocfs2/ioctl.c          |   2 +-
 fs/orangefs/inode.c       |   2 +-
 fs/smb/client/cifsfs.c    |   4 +
 fs/smb/client/cifsfs.h    |   2 +
 fs/smb/client/cifsglob.h  |   4 +-
 fs/smb/client/cifsproto.h |   2 +-
 fs/smb/client/cifssmb.c   |   4 +-
 fs/smb/client/inode.c     | 181 ++++++++++++++++++++++++++++++++++++++
 fs/smb/client/ioctl.c     |   8 +-
 fs/smb/client/smb1ops.c   |   4 +-
 fs/smb/client/smb2ops.c   |   8 +-
 fs/smb/client/smb2pdu.c   |   4 +-
 fs/smb/client/smb2proto.h |   2 +-
 fs/smb/common/smb2pdu.h   |   2 +
 fs/ubifs/ioctl.c          |   3 +-
 fs/xfs/xfs_ioctl.c        |   5 +-
 include/linux/fileattr.h  |  15 ++--
 include/uapi/linux/fs.h   |  34 ++++++-
 mm/shmem.c                |   2 +-
 31 files changed, 380 insertions(+), 48 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2025-02-25 20:15 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-16 16:40 [RFC PATCH 0/4] fs: Add support for Windows file attributes Pali Rohár
2025-02-16 16:40 ` [RFC PATCH 1/4] fs: Add FS_XFLAG_COMPRESSED & FS_XFLAG_ENCRYPTED for FS_IOC_FS[GS]ETXATTR API Pali Rohár
2025-02-16 18:34   ` Eric Biggers
2025-02-16 18:49     ` Pali Rohár
2025-02-16 20:17     ` Amir Goldstein
2025-02-16 20:24       ` Pali Rohár
2025-02-16 20:43         ` Amir Goldstein
2025-02-16 21:17           ` Pali Rohár
2025-02-17  8:27             ` Amir Goldstein
2025-02-18  1:33           ` Dave Chinner
2025-02-18  9:13             ` Amir Goldstein
2025-02-18 19:27               ` Pali Rohár
2025-02-18 22:56                 ` Dave Chinner
2025-02-18 23:06                   ` Pali Rohár
2025-02-19  7:55                     ` Amir Goldstein
2025-02-21 16:34                       ` Theodore Ts'o
2025-02-21 17:11                         ` Amir Goldstein
2025-02-25  5:41                           ` Dave Chinner
2025-02-25 20:14                             ` Pali Rohár
2025-02-21 18:55                         ` Andreas Dilger
2025-02-25  3:42                         ` Dave Chinner
2025-02-18 22:45               ` Dave Chinner
2025-02-16 16:40 ` [RFC PATCH 2/4] fs: Extend FS_IOC_FS[GS]ETXATTR API for Windows attributes Pali Rohár
2025-02-16 19:55   ` Amir Goldstein
2025-02-16 20:01     ` Pali Rohár
2025-02-16 20:34       ` Amir Goldstein
2025-02-16 21:01         ` Pali Rohár
2025-02-16 16:40 ` [RFC PATCH 3/4] fs: Implement support for fsx_xflags_mask, fsx_xflags2 and fsx_xflags2_mask into vfs Pali Rohár
2025-02-21 18:24   ` Theodore Ts'o
2025-02-25 20:07     ` Pali Rohár
2025-02-16 16:40 ` [RFC PATCH 4/4] cifs: Implement FS_IOC_FS[GS]ETXATTR API for Windows attributes Pali Rohár
2025-02-16 20:21   ` Amir Goldstein
2025-02-16 20:25     ` Pali Rohár

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).