mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Baolin Liu <liubaolin12138@163.com>
To: linkinjeon@kernel.org, hyc.lee@gmail.com
Cc: ntfs@lists.linux.dev, linux-kernel@vger.kernel.org,
	liubaolin12138@163.com, Baolin Liu <liubaolin@kylinos.cn>
Subject: [PATCH 1/2] ntfs: implement fileattr_get and fileattr_set
Date: Tue,  1 Sep 2026 17:15:17 +0800	[thread overview]
Message-ID: <20260901091519.2885376-2-liubaolin12138@163.com> (raw)
In-Reply-To: <20260901091519.2885376-1-liubaolin12138@163.com>

From: Baolin Liu <liubaolin@kylinos.cn>

Wire up the fileattr inode operations so that lsattr(1) and chattr(1)
work on ntfs.

fileattr_get reports the compressed and encrypted state of the attribute
and the immutable and append-only flags, the same states ntfs_getattr()
already reports through STATX_ATTR_*.

fileattr_set accepts only FS_IMMUTABLE_FL and FS_APPEND_FL. Compression
and encryption are rejected because changing them would require
rewriting the attribute data. Both accepted flags go to inode->i_flags,
so the VFS enforces them.

Neither flag has an on-disk representation of its own, so a value set
through fileattr_set only lives for the lifetime of the mount. Note also
that S_IMMUTABLE is re-derived on every mount, from FILE_ATTR_SYSTEM when
mounted with sys_immutable and unconditionally for system files, so
clearing it on such a file does not survive a remount either.

Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
---
 fs/ntfs/file.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ntfs/ntfs.h |  4 ++++
 2 files changed, 60 insertions(+)

diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 1969e4f444f7..b7a0fb2d8229 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -15,6 +15,7 @@
 #include <linux/posix_acl_xattr.h>
 #include <linux/compat.h>
 #include <linux/falloc.h>
+#include <linux/fileattr.h>
 
 #include "lcnalloc.h"
 #include "ntfs.h"
@@ -135,6 +136,59 @@ static int ntfs_file_release(struct inode *vi, struct file *filp)
 	return 0;
 }
 
+/*
+ * ntfs_fileattr_get - inode_operations::fileattr_get
+ * @dentry:	dentry to report the flags of
+ * @fa:		filled in with the flags of @dentry
+ */
+int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
+{
+	struct inode *vi = d_inode(dentry);
+	struct ntfs_inode *ni = NTFS_I(vi);
+	u32 flags = 0;
+
+	if (NInoCompressed(ni) || NInoWofCompressed(ni))
+		flags |= FS_COMPR_FL;
+	if (NInoEncrypted(ni))
+		flags |= FS_ENCRYPT_FL;
+	if (vi->i_flags & S_IMMUTABLE)
+		flags |= FS_IMMUTABLE_FL;
+	if (vi->i_flags & S_APPEND)
+		flags |= FS_APPEND_FL;
+
+	fileattr_fill_flags(fa, flags);
+	return 0;
+}
+
+/*
+ * ntfs_fileattr_set - inode_operations::fileattr_set
+ * @idmap:	idmap of the mount @dentry was found from
+ * @dentry:	dentry to set the flags of
+ * @fa:		flags to set
+ */
+int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
+		      struct file_kattr *fa)
+{
+	struct inode *vi = d_inode(dentry);
+	unsigned int new_fl = 0;
+
+	if (fileattr_has_fsx(fa))
+		return -EOPNOTSUPP;
+	if (fa->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL))
+		return -EOPNOTSUPP;
+
+	if (fa->flags & FS_IMMUTABLE_FL)
+		new_fl |= S_IMMUTABLE;
+	if (fa->flags & FS_APPEND_FL)
+		new_fl |= S_APPEND;
+
+	inode_set_flags(vi, new_fl, S_IMMUTABLE | S_APPEND);
+
+	inode_set_ctime_current(vi);
+	mark_inode_dirty(vi);
+	return 0;
+}
+
 /*
  * ntfs_file_fsync - sync a file to disk
  * @filp:	file to be synced
@@ -1215,6 +1269,8 @@ const struct file_operations ntfs_file_ops = {
 const struct inode_operations ntfs_file_inode_ops = {
 	.setattr	= ntfs_setattr,
 	.getattr	= ntfs_getattr,
+	.fileattr_get	= ntfs_fileattr_get,
+	.fileattr_set	= ntfs_fileattr_set,
 	.listxattr	= ntfs_listxattr,
 	.get_acl	= ntfs_get_acl,
 	.set_acl	= ntfs_set_acl,
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index 45f77848a9cf..6a8d5c1aeedc 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -183,6 +183,10 @@ extern const struct inode_operations ntfs_dir_inode_ops;
 extern const struct  file_operations ntfs_empty_file_ops;
 extern const struct inode_operations ntfs_empty_inode_ops;
 
+extern int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
+extern int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
+			     struct file_kattr *fa);
+
 extern const struct export_operations ntfs_export_ops;
 
 /*
-- 
2.51.0


  reply	other threads:[~2026-09-01  9:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-01  9:15 [PATCH 0/2] ntfs: wire up the fileattr API Baolin Liu
2026-09-01  9:15 ` Baolin Liu [this message]
2026-09-02  1:22   ` [PATCH 1/2] ntfs: implement fileattr_get and fileattr_set Namjae Jeon
2026-09-02  6:44     ` liubaolin
2026-09-02  2:00   ` Hyunchul Lee
2026-09-02  7:25     ` liubaolin
2026-09-01  9:15 ` [PATCH 2/2] ntfs: support the nodump flag Baolin Liu
2026-09-02  1:44 ` [PATCH 0/2] ntfs: wire up the fileattr API Namjae Jeon
2026-09-02  7:26   ` liubaolin
2026-09-08  8:31   ` liubaolin
2026-09-09  4:48     ` Namjae Jeon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260901091519.2885376-2-liubaolin12138@163.com \
    --to=liubaolin12138@163.com \
    --cc=hyc.lee@gmail.com \
    --cc=linkinjeon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liubaolin@kylinos.cn \
    --cc=ntfs@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®