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
next prev parent 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®