[PATCH 1/1] rpdfs: Add basic getattr and setattr support.
Chris Kirby <[email protected]> Tue, 24 Feb 2026 14:56:43 -0600
| Newsgroups | dev.linux.lists.rpdfs-devel |
|---|---|
| Message-ID | <54a592917350a76c96d28afdb6ac5b7d4fb6d061.1771966471.git.ckirby@versity.com> |
Add basic getattr and setattr support. For now, the only statx request supported by getattr is STATX_BTIME. All other stat info is filled in from the vfs inode using generic_fillattr(). setattr lacks support for ATTR_SIZE, since we don't have a truncate operation yet. Signed-off-by: Chris Kirby <[email protected]> --- fs/rpdfs/balloc.c | 2 +- fs/rpdfs/dir.c | 2 ++ fs/rpdfs/file.c | 3 ++ fs/rpdfs/inode.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ fs/rpdfs/inode.h | 7 +++++ 5 files changed, 84 insertions(+), 1 deletion(-) diff --git a/fs/rpdfs/balloc.c b/fs/rpdfs/balloc.c index ab14b812297c..09ed17d995f0 100644 --- a/fs/rpdfs/balloc.c +++ b/fs/rpdfs/balloc.c @@ -96,7 +96,7 @@ void rpdfs_balloc_start_apply(struct rpdfs_fs_info *rfi, struct rpdfs_transactio /* * Apply and return the result of an allocation that was prepared by - * _prepare_alloc. The caller can use _txn_use_prepare() to get the + * _prepare_alloc. The caller can use _txn_use_prepared() to get the * allocated block. */ int rpdfs_balloc_apply_alloc(struct rpdfs_fs_info *rfi, struct rpdfs_transaction *txn, diff --git a/fs/rpdfs/dir.c b/fs/rpdfs/dir.c index 115f879d8fb1..7ae8faf74161 100644 --- a/fs/rpdfs/dir.c +++ b/fs/rpdfs/dir.c @@ -677,9 +677,11 @@ static int rpdfs_readdir(struct file *file, struct dir_context *ctx) const struct inode_operations rpdfs_dir_iops = { .create = rpdfs_create, + .getattr = rpdfs_getattr, .lookup = rpdfs_lookup, .mkdir = rpdfs_mkdir, .rename = rpdfs_rename, + .setattr = rpdfs_setattr, }; const struct file_operations rpdfs_dir_fops = { diff --git a/fs/rpdfs/file.c b/fs/rpdfs/file.c index 4c62d5e85caf..22532d8cdf63 100644 --- a/fs/rpdfs/file.c +++ b/fs/rpdfs/file.c @@ -3,8 +3,11 @@ #include <linux/fs.h> #include "file.h" +#include "inode.h" const struct inode_operations rpdfs_file_iops = { + .getattr = rpdfs_getattr, + .setattr = rpdfs_setattr, }; const struct file_operations rpdfs_file_fops = { diff --git a/fs/rpdfs/inode.c b/fs/rpdfs/inode.c index 02d6b6b07c14..3f9a8e9d993f 100644 --- a/fs/rpdfs/inode.c +++ b/fs/rpdfs/inode.c @@ -4,6 +4,7 @@ #include <linux/slab.h> #include <linux/rcupdate.h> #include <linux/writeback.h> +#include <linux/iversion.h> #include "dir.h" #include "file.h" @@ -116,6 +117,7 @@ void rpdfs_inode_init_ops(struct inode *inode) break; default: init_special_inode(inode, inode->i_mode, inode->i_rdev); + break; } } @@ -364,6 +366,75 @@ int rpdfs_write_inode(struct inode *inode, struct writeback_control *wbc) return ret; } +int rpdfs_getattr(struct mnt_idmap *idmap, const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags) +{ + struct inode *inode = d_inode(path->dentry); + struct rpdfs_fs_info *rfi = RPDFS_INODE_FS(inode); + struct rpdfs_block_handle *hnd = NULL; + DECLARE_RPDFS_TXN(txn); + int ret; + + do { + ret = rpdfs_inode_txn_prepare(rfi, &txn, inode, 0); + } while (rpdfs_txn_retry(rfi, &txn, &ret)); + + if (ret < 0) + goto out; + + if (request_mask & STATX_BTIME) { + struct rpdfs_inode *rinode; + + ret = rpdfs_txn_use_prepared(rfi, &txn, rpdfs_inode_bnr(inode), + &hnd, 0); + if (ret < 0) + goto out; + + rinode = hnd->data; + + stat->result_mask |= STATX_BTIME; + stat->btime = ns_to_timespec64(le64_to_cpu(rinode->crtime_nsec)); + } + + generic_fillattr(idmap, request_mask, inode, stat); + +out: + rpdfs_txn_reset(rfi, &txn); + + return ret; +} + +int rpdfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + struct iattr *attr) +{ + struct inode *inode = d_inode(dentry); + struct rpdfs_fs_info *rfi = RPDFS_INODE_FS(inode); + DECLARE_RPDFS_TXN(txn); + int ret; + + do { + ret = rpdfs_inode_txn_prepare(rfi, &txn, inode, RBAF_WRITE); + } while (rpdfs_txn_retry(rfi, &txn, &ret)); + + if (ret < 0) + goto out; + + ret = setattr_prepare(idmap, dentry, attr); + if (ret) + goto out; + + setattr_copy(idmap, inode, attr); + inode_inc_iversion(inode); + + rpdfs_inode_txn_update(rfi, &txn, inode); + +out: + rpdfs_txn_reset(rfi, &txn); + + return ret; +} + int rpdfs_inode_init(void) { rpdfs_inode_cache = kmem_cache_create("rpdfs_inode_cache", sizeof(struct rpdfs_inode_info), diff --git a/fs/rpdfs/inode.h b/fs/rpdfs/inode.h index 28edaf01f542..a57017a4fca0 100644 --- a/fs/rpdfs/inode.h +++ b/fs/rpdfs/inode.h @@ -52,6 +52,13 @@ int rpdfs_write_inode(struct inode *inode, struct writeback_control *wbc); void rpdfs_inode_init_ops(struct inode *inode); +int rpdfs_getattr(struct mnt_idmap *idmap, const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags); + +int rpdfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + struct iattr *attr); + struct inode *rpdfs_iget(struct super_block *sb, struct rpdfs_ino_gen *ig); struct inode *rpdfs_new_inode(struct super_block *sb, struct rpdfs_ino_gen *ig); int rpdfs_inode_txn_prepare(struct rpdfs_fs_info *rfi, struct rpdfs_transaction *txn, -- 2.53.0