Linux Documentation
 help / color / mirror / Atom feed
From: John Groves <john@groves.net>
To: "Darrick J. Wong" <djwong@kernel.org>
Cc: John Groves <john@jagalactic.com>,
	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 11/12] famfs: Report device capacity via statfs so df works
Date: Fri, 7 Aug 2026 08:47:19 -0500	[thread overview]
Message-ID: <anXhywwC-DWjHGRz@groves.net> (raw)
In-Reply-To: <20260806053300.GK3560084@frogsfrogsfrogs>

On 26/08/05 10:33PM, Darrick J. Wong wrote:
> On Mon, Aug 03, 2026 at 02:30:07AM +0000, John Groves wrote:
> > From: John Groves <John@Groves.net>
> > 
> > Replace simple_statfs(), which reports zero blocks (so df omits the mount),
> > with famfs_statfs() reporting real capacity and usage.
> > 
> > Add dax_fsdev_size() in drivers/dax/fsdev.c, returning the size fsdev
> > caches at probe (dev_dax->cached_size - the sum of the device's ranges,
> > stable while bound), exported. It lives in fsdev.c because cached_size is
> > set only by the fsdev driver, and famfs only ever holds fsdev-mode daxdevs
> > (fs_dax_get() enforces DAXDRV_FSDEV_TYPE); famfs.ko therefore depends on
> > fsdev_dax.ko.
> > 
> > famfs tracks two byte counters under a new stats_sem:
> >  - total_capacity: summed in famfs_install_daxdev() from dax_fsdev_size(),
> >    covering the mount primary and every DAXDEV_OPEN secondary, counted once
> >    per daxdev (on the valid 0->1 transition).
> >  - used_capacity: summed in famfs_file_init_dax() from the fmap's mapped
> >    device bytes (superblock + log + data files).
> > 
> > famfs_statfs() reports total and free (total - used). Free is an
> > approximation of the userspace allocator's free space (it ignores allocator
> > gaps and reserved regions), which is adequate for df.
> > 
> > (Side note: I am the maintainer of drivers/dax/fsdev.c)
> > 
> > Signed-off-by: John Groves <john@groves.net>
> > ---
> >  drivers/dax/fsdev.c       | 19 +++++++++++++++++
> >  fs/famfs/famfs_file.c     |  5 +++++
> >  fs/famfs/famfs_inode.c    | 43 ++++++++++++++++++++++++++++++++++++++-
> >  fs/famfs/famfs_internal.h |  8 ++++++++
> >  include/linux/dax.h       |  1 +
> >  5 files changed, 75 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/dax/fsdev.c b/drivers/dax/fsdev.c
> > index 188b2526bee4..a5b4b2d79428 100644
> > --- a/drivers/dax/fsdev.c
> > +++ b/drivers/dax/fsdev.c
> > @@ -104,6 +104,25 @@ static size_t fsdev_dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff
> >  	return _copy_from_iter_flushcache(addr, bytes, i);
> >  }
> >  
> > +/**
> > + * dax_fsdev_size() - total size in bytes of an fsdev dax device
> > + * @dax_dev: the dax device (must be bound to this driver)
> > + *
> > + * Returns the size cached at probe time (sum of all ranges); it cannot change
> > + * while the driver is bound. Only valid for fsdev dax devices - callers
> > + * ensure that (e.g. fs_dax_get() enforces DAXDRV_FSDEV_TYPE). Returns 0 if the
> > + * device is not alive.
> > + */
> > +u64 dax_fsdev_size(struct dax_device *dax_dev)
> > +{
> > +	struct dev_dax *dev_dax = dax_get_private(dax_dev);
> > +
> > +	if (!dev_dax)
> > +		return 0;
> > +	return dev_dax->cached_size;
> > +}
> > +EXPORT_SYMBOL_GPL(dax_fsdev_size);
> > +
> >  static const struct dax_operations dev_dax_ops = {
> >  	.direct_access = fsdev_dax_direct_access,
> >  	.zero_page_range = fsdev_dax_zero_page_range,
> > diff --git a/fs/famfs/famfs_file.c b/fs/famfs/famfs_file.c
> > index abf049b32a4b..5be39d677089 100644
> > --- a/fs/famfs/famfs_file.c
> > +++ b/fs/famfs/famfs_file.c
> > @@ -280,6 +280,11 @@ famfs_file_init_dax(struct file *file, void __user *arg)
> >  	}
> >  	inode_unlock(inode);
> >  
> > +	/* Account the mapped device bytes for statfs (only on success) */
> > +	if (!rc) {
> > +		scoped_guard(rwsem_write, &fsi->stats_sem)
> > +			fsi->used_capacity += extent_total;
> > +	}
> >  out:
> >  	kvfree(fmap_buf);
> >  	if (meta)
> > diff --git a/fs/famfs/famfs_inode.c b/fs/famfs/famfs_inode.c
> > index 6cbd7d657fd8..3c0d1094d653 100644
> > --- a/fs/famfs/famfs_inode.c
> > +++ b/fs/famfs/famfs_inode.c
> > @@ -24,6 +24,7 @@
> >  #include <linux/iomap.h>
> >  #include <linux/path.h>
> >  #include <linux/namei.h>
> > +#include <linux/statfs.h>
> >  
> >  #include "famfs_internal.h"
> >  
> > @@ -307,8 +308,37 @@ static void famfs_evict_inode(struct inode *inode)
> >  	clear_inode(inode);
> >  }
> >  
> > +/*
> > + * famfs_statfs() - report device capacity and consumption so 'df' works.
> > + * @total_capacity is the sum of installed daxdev sizes; @used_capacity is the
> > + * sum of device bytes mapped by fmaps (superblock + log + data files). Free is
> > + * the difference - an approximation of the userspace allocator's free space
> > + * (it ignores allocator gaps / reserved regions), which is fine for df.
> > + */
> > +static int famfs_statfs(struct dentry *dentry, struct kstatfs *buf)
> > +{
> > +	struct famfs_fs_info *fsi = dentry->d_sb->s_fs_info;
> > +	u64 total, used, free;
> > +
> > +	scoped_guard(rwsem_read, &fsi->stats_sem) {
> > +		total = fsi->total_capacity;
> > +		used  = fsi->used_capacity;
> > +	}
> > +	free = total > used ? total - used : 0;
> > +
> > +	buf->f_type    = FAMFS_SUPER_MAGIC;
> > +	buf->f_bsize   = PAGE_SIZE;
> > +	buf->f_frsize  = PAGE_SIZE;
> > +	buf->f_blocks  = total >> PAGE_SHIFT;
> > +	buf->f_bfree   = free  >> PAGE_SHIFT;
> > +	buf->f_bavail  = free  >> PAGE_SHIFT;	/* no root reservation */
> > +	buf->f_namelen = NAME_MAX;
> > +	buf->f_fsid    = u64_to_fsid(huge_encode_dev(dentry->d_sb->s_dev));
> > +	return 0;
> > +}
> > +
> >  static const struct super_operations famfs_super_ops = {
> > -	.statfs		= simple_statfs,
> > +	.statfs		= famfs_statfs,
> >  	.drop_inode	= inode_just_drop,
> >  	.show_options	= famfs_show_options,
> >  	.evict_inode    = famfs_evict_inode,
> > @@ -399,6 +429,7 @@ int famfs_install_daxdev(
> >  		const char *name)
> >  {
> >  	struct famfs_daxdev *daxdev;
> > +	struct dax_device *devp = NULL;
> >  	int rc = 0;
> >  
> >  	if (index >= fsi->dax_devlist->nslots) {
> > @@ -462,6 +493,15 @@ int famfs_install_daxdev(
> >  
> >  		wmb(); /* All other fields must be visible before valid */
> >  		daxdev->valid = 1;
> > +		devp = daxdev->devp;
> > +	}
> > +
> > +	/* Freshly installed: add its capacity to the statfs accounting */
> > +	if (devp) {
> > +		u64 sz = dax_fsdev_size(devp);
> > +
> > +		scoped_guard(rwsem_write, &fsi->stats_sem)
> > +			fsi->total_capacity += sz;
> 
> Can dax devices change size the same way block devices can?
> 
> Though for statfs that hardly matters; a bdev shrinkage rarely causes
> b_avail to be updated even if the filesystem starts barfing IO errors
> due to invalid LBA range.
> 
> The code in here looks good to me otherwise.
> 
> --D

There are cases where a daxdev can change size, but fsdev/famfs mode
explicitly prohibits that.

Since the whole idea is that daxdevs probably point to shared memory,
We can't let the size change because it might not happen at the same
instant everywhere. Because special relativity ;)

I watched a video of Leslie Lamport some time back where he said software
concurrency was like special relativity: you often *cannot* know whether
A happened after B, etc.

Thanks!
John

<snip>

  reply	other threads:[~2026-08-07 13:47 UTC|newest]

Thread overview: 40+ 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 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-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-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-06  5:12     ` Darrick J. Wong
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-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-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-06  5:24     ` Darrick J. Wong
2026-08-06 20:53       ` John Groves
2026-08-03  2:29   ` [PATCH V12 08/12] famfs: iomap_begin and file-to-dax offset resolution John Groves
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-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-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-06  5:33     ` Darrick J. Wong
2026-08-07 13:47       ` John Groves [this message]
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=anXhywwC-DWjHGRz@groves.net \
    --to=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=djwong@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox