From: "Darrick J. Wong" <djwong@kernel.org>
To: John Groves <john@jagalactic.com>
Cc: John Groves <John@groves.net>, Miklos Szeredi <miklos@szeredi.hu>,
Dan Williams <djbw@kernel.org>,
Bernd Schubert <bschubert@ddn.com>,
Alison Schofield <alison.schofield@intel.com>,
John Groves <jgroves@micron.com>,
Jonathan Corbet <corbet@lwn.net>, Jake Edge <jake@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Vishal Verma <vishal.l.verma@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
Matthew Wilcox <willy@infradead.org>, Jan Kara <jack@suse.cz>,
Alexander Viro <viro@zeniv.linux.org.uk>,
David Hildenbrand <david@kernel.org>,
Christian Brauner <brauner@kernel.org>,
Randy Dunlap <rdunlap@infradead.org>,
Jeff Layton <jlayton@kernel.org>,
Amir Goldstein <amir73il@gmail.com>,
Jonathan Cameron <jic23@kernel.org>,
Stefan Hajnoczi <shajnocz@redhat.com>,
Joanne Koong <joannelkoong@gmail.com>,
Josef Bacik <josef@toxicpanda.com>,
Bagas Sanjaya <bagasdotme@gmail.com>,
Chen Linxuan <chenlinxuan@uniontech.com>,
James Morse <james.morse@arm.com>, Fuad Tabba <tabba@google.com>,
Sean Christopherson <seanjc@google.com>,
Shivank Garg <shivankg@amd.com>,
Ackerley Tng <ackerleytng@google.com>,
Gregory Price <gourry@gourry.net>,
Andrew Morton <akpm@linux-foundation.org>,
Namjae Jeon <linkinjeon@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Ira Weiny <iweiny@kernel.org>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Haren Myneni <haren@linux.ibm.com>,
Pratyush Yadav <pratyush@kernel.org>,
Giovanni Cabiddu <giovanni.cabiddu@intel.com>,
Jiri Slaby <jirislaby@kernel.org>,
Ethan Nelson-Moore <enelsonmoore@gmail.com>,
Gabriel Whigham <gabewhigham@gmail.com>,
Aravind Ramesh <arramesh@micron.com>,
Ajay Joshi <ajayjoshi@micron.com>,
"venkataravis@micron.com" <venkataravis@micron.com>,
"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"nvdimm@lists.linux.dev" <nvdimm@lists.linux.dev>,
"linux-cxl@vger.kernel.org" <linux-cxl@vger.kernel.org>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"fuse-devel@lists.linux.dev" <fuse-devel@lists.linux.dev>
Subject: Re: [PATCH V12 04/12] famfs: Introduce inode_operations and super_operations
Date: Wed, 5 Aug 2026 22:12:30 -0700 [thread overview]
Message-ID: <20260806051230.GD3560084@frogsfrogsfrogs> (raw)
In-Reply-To: <0100019fc573edf6-93c159df-6197-4bdf-9f1d-74b77a72ce7e-000000@email.amazonses.com>
On Mon, Aug 03, 2026 at 02:28:56AM +0000, John Groves wrote:
> From: John Groves <john@groves.net>
>
> The famfs inode and super operations are generic other than
> show_options, evict_inode and setattr (which prevents truncation..
>
> This commit builds but is still too incomplete to run
>
> Signed-off-by: John Groves <john@groves.net>
> ---
> fs/famfs/famfs_inode.c | 249 +++++++++++++++++++++++++++++++++++++-
> fs/famfs/famfs_internal.h | 6 +
> 2 files changed, 252 insertions(+), 3 deletions(-)
>
> diff --git a/fs/famfs/famfs_inode.c b/fs/famfs/famfs_inode.c
> index ad71e5e7a8e3..efc6b852eca0 100644
> --- a/fs/famfs/famfs_inode.c
> +++ b/fs/famfs/famfs_inode.c
> @@ -29,6 +29,9 @@
>
> #define FAMFS_DEFAULT_MODE 0755
>
> +static const struct inode_operations famfs_file_inode_operations;
> +static const struct inode_operations famfs_dir_inode_operations;
> +
> static struct inode *famfs_get_inode(
> struct super_block *sb,
> const struct inode *dir,
> @@ -54,11 +57,11 @@ static struct inode *famfs_get_inode(
> init_special_inode(inode, mode, dev);
> break;
> case S_IFREG:
> - inode->i_op = NULL /* famfs_file_inode_operations */;
> + inode->i_op = &famfs_file_inode_operations;
> inode->i_fop = NULL /* &famfs_file_operations */;
> break;
> case S_IFDIR:
> - inode->i_op = NULL /* famfs_dir_inode_operations */;
> + inode->i_op = &famfs_dir_inode_operations;
> inode->i_fop = &simple_dir_operations;
>
> /* Directory inodes start off with i_nlink == 2 (for ".") */
> @@ -72,6 +75,246 @@ static struct inode *famfs_get_inode(
> return inode;
> }
>
> +/***************************************************************************
> + * famfs inode_operations
> + */
> +
> +static int
> +famfs_setattr(
> + struct mnt_idmap *idmap,
> + struct dentry *dentry,
> + struct iattr *iattr)
> +{
> + struct inode *inode = d_inode(dentry);
> + struct famfs_fs_info *fsi = inode->i_sb->s_fs_info;
> +
> + /* Resizing a famfs file (its size is pinned to the fmap) */
> + if ((iattr->ia_valid & ATTR_SIZE) &&
> + !famfs_opt_enabled(fsi, FAMFS_OPT_TRUNCATE) &&
Does truncating the file down release the mapped memory?
Can you truncate it up? How does the famfs manager deal with this?
> + iattr->ia_size != i_size_read(inode))
> + return -EPERM;
> + if ((iattr->ia_valid & ATTR_MODE) &&
> + !famfs_opt_enabled(fsi, FAMFS_OPT_CHMOD))
> + return -EPERM;
> + if ((iattr->ia_valid & (ATTR_UID | ATTR_GID)) &&
> + !famfs_opt_enabled(fsi, FAMFS_OPT_CHOWN))
> + return -EPERM;
> + if ((iattr->ia_valid & (ATTR_ATIME | ATTR_MTIME)) &&
> + !famfs_opt_enabled(fsi, FAMFS_OPT_UTIMES))
> + return -EPERM;
> +
> + return simple_setattr(idmap, dentry, iattr);
> +}
> +
> +static const struct inode_operations famfs_file_inode_operations = {
> + /* All generic */
> + .setattr = famfs_setattr,
> + .getattr = simple_getattr,
> +};
> +
> +/*
> + * Internal inode creation helper, shared by ->create, ->mkdir, ->mknod and
> + * ->symlink. Each of those callers is responsible for its own FAMFS_OPT_*
> + * permission check before getting here.
> + */
> +static int
> +famfs_mknod(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry,
> + umode_t mode, dev_t dev)
> +{
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> + struct timespec64 tv;
> + struct inode *inode;
> +
> + if (fsi->deverror)
> + return -ENODEV;
> +
> + inode = famfs_get_inode(dir->i_sb, dir, mode, dev);
> + if (!inode)
> + return -ENOSPC;
> +
> + d_make_persistent(dentry, inode);
> + tv = inode_set_ctime_current(inode);
> + inode_set_mtime_to_ts(inode, tv);
> + inode_set_atime_to_ts(inode, tv);
> +
> + return 0;
> +}
> +
> +static struct dentry *famfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
> + struct dentry *dentry, umode_t mode)
> +{
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> + int rc;
> +
> + if (fsi->deverror)
> + return ERR_PTR(-ENODEV);
> + if (!famfs_opt_enabled(fsi, FAMFS_OPT_MKDIR))
> + return ERR_PTR(-EPERM);
> +
> + rc = famfs_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFDIR, 0);
> + if (rc)
> + return ERR_PTR(rc);
> +
> + inc_nlink(dir);
> +
> + return ERR_PTR(0);
> +}
> +
> +static int famfs_create(struct mnt_idmap *idmap, struct inode *dir,
> + struct dentry *dentry, umode_t mode, bool excl)
> +{
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> +
> + if (fsi->deverror)
> + return -ENODEV;
> + if (!famfs_opt_enabled(fsi, FAMFS_OPT_CREATE))
> + return -EPERM;
> +
> + return famfs_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFREG, 0);
Is the model here that you creat() a file and then the famfs server has
to go find it some cxl memory? I was kinda under the impression that
you'd get the famfs software to map some memory to a name, and then the
famfs server on each node would create it and upload the mapping, and
now the cxlmem-backed file can be mmaped from multiple nodes?
But maybe this is less of a cluster filesystem than I assumed it was.
--D
> +}
> +
> +static int
> +famfs_mknod_op(struct mnt_idmap *idmap, struct inode *dir,
> + struct dentry *dentry, umode_t mode, dev_t dev)
> +{
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> +
> + if (!famfs_opt_enabled(fsi, FAMFS_OPT_MKNOD))
> + return -EPERM;
> +
> + return famfs_mknod(idmap, dir, dentry, mode, dev);
> +}
> +
> +static int
> +famfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
> + struct dentry *dentry, const char *symname)
> +{
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> + struct inode *inode;
> + int len, rc;
> +
> + if (fsi->deverror)
> + return -ENODEV;
> + if (!famfs_opt_enabled(fsi, FAMFS_OPT_SYMLINK))
> + return -EPERM;
> +
> + inode = famfs_get_inode(dir->i_sb, dir, S_IFLNK | 0777, 0);
> + if (!inode)
> + return -ENOSPC;
> +
> + len = strlen(symname) + 1;
> + rc = page_symlink(inode, symname, len);
> + if (rc) {
> + iput(inode);
> + return rc;
> + }
> +
> + d_make_persistent(dentry, inode);
> + inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
> +
> + return 0;
> +}
> +
> +static int
> +famfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
> +{
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> +
> + if (!famfs_opt_enabled(fsi, FAMFS_OPT_LINK))
> + return -EPERM;
> +
> + return simple_link(old_dentry, dir, dentry);
> +}
> +
> +static int famfs_unlink(struct inode *dir, struct dentry *dentry)
> +{
> + struct inode *inode = d_inode(dentry);
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> +
> + /* A file with an fmap may only be unlinked when explicitly enabled */
> + if (inode->i_private && !famfs_opt_enabled(fsi, FAMFS_OPT_UNLINK))
> + return -EPERM;
> +
> + return simple_unlink(dir, dentry);
> +}
> +
> +static int famfs_rmdir(struct inode *dir, struct dentry *dentry)
> +{
> + struct famfs_fs_info *fsi = dir->i_sb->s_fs_info;
> +
> + if (!famfs_opt_enabled(fsi, FAMFS_OPT_RMDIR))
> + return -EPERM;
> +
> + return simple_rmdir(dir, dentry);
> +}
> +
> +static int
> +famfs_rename(
> + struct mnt_idmap *idmap,
> + struct inode *old_dir,
> + struct dentry *old_dentry,
> + struct inode *new_dir,
> + struct dentry *new_dentry,
> + unsigned int flags)
> +{
> + struct famfs_fs_info *fsi = old_dir->i_sb->s_fs_info;
> +
> + if (!famfs_opt_enabled(fsi, FAMFS_OPT_RENAME))
> + return -EPERM;
> +
> + return simple_rename(idmap, old_dir, old_dentry, new_dir, new_dentry,
> + flags);
> +}
> +
> +static const struct inode_operations famfs_dir_inode_operations = {
> + .create = famfs_create,
> + .lookup = simple_lookup,
> + .link = famfs_link,
> + .unlink = famfs_unlink,
> + .symlink = famfs_symlink,
> + .mkdir = famfs_mkdir,
> + .mknod = famfs_mknod_op,
> + .rmdir = famfs_rmdir,
> + .rename = famfs_rename,
> +};
> +
> +/*****************************************************************************
> + * famfs super_operations
> + *
> + * TODO: implement a famfs_statfs() that shows size, free and available space,
> + * etc.
> + */
> +
> +/*
> + * famfs_show_options() - Display the mount options in /proc/mounts.
> + */
> +static int famfs_show_options(struct seq_file *m, struct dentry *root)
> +{
> + struct famfs_fs_info *fsi = root->d_sb->s_fs_info;
> +
> + if (fsi->mount_opts.mode != FAMFS_DEFAULT_MODE)
> + seq_printf(m, ",mode=%o", fsi->mount_opts.mode);
> +
> + return 0;
> +}
> +
> +static void famfs_evict_inode(struct inode *inode)
> +{
> + inode->i_private = NULL;
> + dax_break_layout_final(inode);
> + truncate_inode_pages_final(&inode->i_data);
> + clear_inode(inode);
> +}
> +
> +static const struct super_operations famfs_super_ops = {
> + .statfs = simple_statfs,
> + .drop_inode = inode_just_drop,
> + .show_options = famfs_show_options,
> + .evict_inode = famfs_evict_inode,
> +};
> +
> +/*****************************************************************************/
> +
> /*
> * famfs dax_operations (for famfs-mode dax)
> */
> @@ -305,7 +548,7 @@ famfs_fill_super(struct super_block *sb, struct fs_context *fc)
> sb->s_blocksize = PAGE_SIZE;
> sb->s_blocksize_bits = PAGE_SHIFT;
> sb->s_magic = FAMFS_SUPER_MAGIC;
> - sb->s_op = NULL /* famfs_super_ops */;
> + sb->s_op = &famfs_super_ops;
> sb->s_time_gran = 1;
> }
>
> diff --git a/fs/famfs/famfs_internal.h b/fs/famfs/famfs_internal.h
> index ebb9c499cf69..485087588a11 100644
> --- a/fs/famfs/famfs_internal.h
> +++ b/fs/famfs/famfs_internal.h
> @@ -70,6 +70,12 @@ struct famfs_fs_info {
> struct rw_semaphore devlist_sem;
> };
>
> +/* This stub will be replaced in a later commit
> + * Note: the opt parameter is intentionally unused, and will be used by
> + * the replacement function when that commit lands
> + */
> +#define famfs_opt_enabled(fsi, opt) (fsi != 0)
> +
> int lookup_daxdev(const char *pathname, dev_t *devno);
> int famfs_devlist_alloc(struct famfs_fs_info *fsi);
> int famfs_install_daxdev(struct famfs_fs_info *fsi, struct super_block *sb,
> --
> 2.53.0
>
>
>
next prev parent reply other threads:[~2026-08-06 5:12 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260803022730.75731-1-john@jagalactic.com>
2026-08-03 2:27 ` [PATCH V12 00/12] famfs: the Fabric-Attached Memory File System (standalone) John Groves
2026-08-03 2:28 ` [PATCH V12 01/12] dax: replace exported dax_dev_get() with non-allocating dax_dev_find() John Groves
2026-08-03 2:43 ` sashiko-bot
2026-08-03 19:13 ` Alison Schofield
2026-08-05 20:21 ` John Groves
2026-08-03 2:28 ` [PATCH V12 02/12] famfs: Module operations, fs_context, and mount John Groves
2026-08-03 2:49 ` sashiko-bot
2026-08-06 4:37 ` Darrick J. Wong
2026-08-06 13:22 ` John Groves
2026-08-03 2:28 ` [PATCH V12 03/12] famfs: Add daxdev table and dax notify_failure support John Groves
2026-08-03 2:45 ` sashiko-bot
2026-08-06 5:05 ` Darrick J. Wong
2026-08-06 13:36 ` John Groves
2026-08-03 2:28 ` [PATCH V12 04/12] famfs: Introduce inode_operations and super_operations John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:12 ` Darrick J. Wong [this message]
2026-08-06 16:31 ` John Groves
2026-08-03 2:29 ` [PATCH V12 05/12] famfs: Introduce file_operations read/write John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:14 ` Darrick J. Wong
2026-08-06 20:03 ` John Groves
2026-08-03 2:29 ` [PATCH V12 06/12] famfs: Introduce mmap and VM fault handling John Groves
2026-08-03 2:46 ` sashiko-bot
2026-08-06 5:16 ` Darrick J. Wong
2026-08-06 20:40 ` John Groves
2026-08-03 2:29 ` [PATCH V12 07/12] famfs: MAP_CREATE ioctl and fmap ingest (ABI 44) John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:24 ` Darrick J. Wong
2026-08-06 20:53 ` John Groves
2026-08-07 22:17 ` John Groves
2026-08-03 2:29 ` [PATCH V12 08/12] famfs: iomap_begin and file-to-dax offset resolution John Groves
2026-08-03 2:44 ` sashiko-bot
2026-08-06 5:28 ` Darrick J. Wong
2026-08-06 22:14 ` John Groves
2026-08-03 2:29 ` [PATCH V12 09/12] famfs: Register secondary daxdevs by path (FAMFSIOC_DAXDEV_OPEN) John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:29 ` Darrick J. Wong
2026-08-06 22:22 ` John Groves
2026-08-03 2:29 ` [PATCH V12 10/12] famfs: Add runtime operation-permission (opts) framework John Groves
2026-08-03 2:42 ` sashiko-bot
2026-08-06 5:31 ` Darrick J. Wong
2026-08-06 22:30 ` John Groves
2026-08-03 2:30 ` [PATCH V12 11/12] famfs: Report device capacity via statfs so df works John Groves
2026-08-03 2:58 ` sashiko-bot
2026-08-06 5:33 ` Darrick J. Wong
2026-08-07 13:47 ` John Groves
2026-08-03 2:30 ` [PATCH V12 12/12] famfs: Add documentation John Groves
2026-08-06 5:38 ` Darrick J. Wong
2026-08-07 15:05 ` John Groves
2026-08-03 8:52 ` [PATCH V12 00/12] famfs: the Fabric-Attached Memory File System (standalone) Amir Goldstein
2026-08-06 5:19 ` Matthew Wilcox
2026-08-06 5:34 ` Darrick J. Wong
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=20260806051230.GD3560084@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=John@groves.net \
--cc=ackerleytng@google.com \
--cc=ajayjoshi@micron.com \
--cc=akpm@linux-foundation.org \
--cc=alison.schofield@intel.com \
--cc=amir73il@gmail.com \
--cc=arramesh@micron.com \
--cc=bagasdotme@gmail.com \
--cc=brauner@kernel.org \
--cc=bschubert@ddn.com \
--cc=chenlinxuan@uniontech.com \
--cc=corbet@lwn.net \
--cc=dave.jiang@intel.com \
--cc=david@kernel.org \
--cc=djbw@kernel.org \
--cc=enelsonmoore@gmail.com \
--cc=fuse-devel@lists.linux.dev \
--cc=gabewhigham@gmail.com \
--cc=giovanni.cabiddu@intel.com \
--cc=gourry@gourry.net \
--cc=gregkh@linuxfoundation.org \
--cc=haren@linux.ibm.com \
--cc=iweiny@kernel.org \
--cc=jack@suse.cz \
--cc=jake@lwn.net \
--cc=james.morse@arm.com \
--cc=jgroves@micron.com \
--cc=jic23@kernel.org \
--cc=jirislaby@kernel.org \
--cc=jlayton@kernel.org \
--cc=joannelkoong@gmail.com \
--cc=john@jagalactic.com \
--cc=josef@toxicpanda.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=miklos@szeredi.hu \
--cc=nvdimm@lists.linux.dev \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=rdunlap@infradead.org \
--cc=seanjc@google.com \
--cc=shajnocz@redhat.com \
--cc=shivankg@amd.com \
--cc=skhan@linuxfoundation.org \
--cc=tabba@google.com \
--cc=venkataravis@micron.com \
--cc=viro@zeniv.linux.org.uk \
--cc=vishal.l.verma@intel.com \
--cc=willy@infradead.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.