All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: John Groves <John@Groves.net>
Cc: John Groves <jgroves@micron.com>,
	Jonathan Corbet <corbet@lwn.net>,
	"Dan Williams" <dan.j.williams@intel.com>,
	Vishal Verma <vishal.l.verma@intel.com>,
	Dave Jiang <dave.jiang@intel.com>,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>, "Jan Kara" <jack@suse.cz>,
	Matthew Wilcox <willy@infradead.org>, <linux-cxl@vger.kernel.org>,
	<linux-fsdevel@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <nvdimm@lists.linux.dev>,
	<john@jagalactic.com>, Dave Chinner <david@fromorbit.com>,
	Christoph Hellwig <hch@infradead.org>,
	<dave.hansen@linux.intel.com>, <gregory.price@memverge.com>
Subject: Re: [RFC PATCH 15/20] famfs: Add ioctl to file_operations
Date: Mon, 26 Feb 2024 13:44:08 +0000	[thread overview]
Message-ID: <20240226134408.00005576@Huawei.com> (raw)
In-Reply-To: <a5d0969403ca02af6593b6789a21b230b2436800.1708709155.git.john@groves.net>

On Fri, 23 Feb 2024 11:41:59 -0600
John Groves <John@Groves.net> wrote:

> This commit introduces the per-file ioctl function famfs_file_ioctl()
> into struct file_operations, and introduces the famfs_file_init_dax()
> function (which is called by famfs_file_ioct())
> 
> famfs_file_init_dax() associates a dax extent list with a file, making
> it into a proper famfs file. It is called from the FAMFSIOC_MAP_CREATE
> ioctl. Starting with an empty file (which is basically a ramfs file),
> this turns the file into a DAX file backed by the specified extent list.
> 
> The other ioctls are:
> 
> FAMFSIOC_NOP - A convenient way for user space to verify it's a famfs file
> FAMFSIOC_MAP_GET - Get the header of the metadata for a file
> FAMFSIOC_MAP_GETEXT - Get the extents for a file
> 
> The latter two, together, are comparable to xfs_bmap. Our user space tools
> use them primarly in testing.
> 
> Signed-off-by: John Groves <john@groves.net>
A few more comments inline. Nothing fundamental just nice to have
simplifications of the code.

> ---
>  fs/famfs/famfs_file.c | 226 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 226 insertions(+)
> 
> diff --git a/fs/famfs/famfs_file.c b/fs/famfs/famfs_file.c
> index 5228e9de1e3b..fd42d5966982 100644
> --- a/fs/famfs/famfs_file.c
> +++ b/fs/famfs/famfs_file.c
> @@ -19,6 +19,231 @@
>  #include <uapi/linux/famfs_ioctl.h>
>  #include "famfs_internal.h"
>  
> +/**
> + * famfs_map_meta_alloc() - Allocate famfs file metadata
> + * @mapp:       Pointer to an mcache_map_meta pointer
> + * @ext_count:  The number of extents needed
> + */
> +static int
> +famfs_meta_alloc(
> +	struct famfs_file_meta  **metap,
> +	size_t                    ext_count)
> +{
> +	struct famfs_file_meta *meta;
> +	size_t                  metasz;
> +
> +	*metap = NULL;

Not responsibility of caller?

> +
> +	metasz = sizeof(*meta) + sizeof(*(meta->tfs_extents)) * ext_count;

Looks like struct_size() would be appropriate.


> +
> +	meta = kzalloc(metasz, GFP_KERNEL);
> +	if (!meta)
> +		return -ENOMEM;
> +
> +	meta->tfs_extent_ct = ext_count;
> +	*metap = meta;
> +
> +	return 0;
> +}
> +
> +static void
> +famfs_meta_free(
> +	struct famfs_file_meta *map)
> +{
> +	kfree(map);
Given this is just kfree you can use __free magic to simplify things below.

> +}
> +
> +/**
> + * famfs_file_init_dax() - FAMFSIOC_MAP_CREATE ioctl handler
> + * @file:
> + * @arg:        ptr to struct mcioc_map in user space
> + *
> + * Setup the dax mapping for a file. Files are created empty, and then function is called
> + * (by famfs_file_ioctl()) to setup the mapping and set the file size.
> + */
> +static int
> +famfs_file_init_dax(
> +	struct file    *file,
> +	void __user    *arg)
> +{
> +	struct famfs_extent    *tfs_extents = NULL;
> +	struct famfs_file_meta *meta = NULL;
> +	struct inode           *inode;
> +	struct famfs_ioc_map    imap;
> +	struct famfs_fs_info   *fsi;
> +	struct super_block     *sb;
> +	int    alignment_errs = 0;
> +	size_t extent_total = 0;
> +	size_t ext_count;
> +	int    rc = 0;
> +	int    i;
> +
> +	rc = copy_from_user(&imap, arg, sizeof(imap));
> +	if (rc)
> +		return -EFAULT;
> +
> +	ext_count = imap.ext_list_count;
> +	if (ext_count < 1) {
> +		rc = -ENOSPC;
> +		goto errout;
		meta data not yet allocated.
		return -ENOSPC;

> +	}
> +
> +	if (ext_count > FAMFS_MAX_EXTENTS) {
> +		rc = -E2BIG;
> +		goto errout;	
		return 

> +	}
> +
> +	inode = file_inode(file);
> +	if (!inode) {
> +		rc = -EBADF;
> +		goto errout;
		return;

> +	}
> +	sb  = inode->i_sb;
> +	fsi = inode->i_sb->s_fs_info;
> +
> +	tfs_extents = &imap.ext_list[0];
> +
> +	rc = famfs_meta_alloc(&meta, ext_count);
> +	if (rc)
> +		goto errout;
	return ...

	only after this point should there be any
	meta data to free on exit?

> +
> +	meta->file_type = imap.file_type;
> +	meta->file_size = imap.file_size;
> +
> +	/* Fill in the internal file metadata structure */
> +	for (i = 0; i < imap.ext_list_count; i++) {
> +		size_t len;
> +		off_t  offset;
> +
> +		offset = imap.ext_list[i].offset;
> +		len    = imap.ext_list[i].len;
> +
> +		extent_total += len;
> +
> +		if (WARN_ON(offset == 0 && meta->file_type != FAMFS_SUPERBLOCK)) {
> +			rc = -EINVAL;
> +			goto errout;
> +		}
> +
> +		meta->tfs_extents[i].offset = offset;
> +		meta->tfs_extents[i].len    = len;
> +
> +		/* All extent addresses/offsets must be 2MiB aligned,
> +		 * and all but the last length must be a 2MiB multiple.
> +		 */
> +		if (!IS_ALIGNED(offset, PMD_SIZE)) {
> +			pr_err("%s: error ext %d hpa %lx not aligned\n",
> +			       __func__, i, offset);
> +			alignment_errs++;
> +		}
> +		if (i < (imap.ext_list_count - 1) && !IS_ALIGNED(len, PMD_SIZE)) {
> +			pr_err("%s: error ext %d length %ld not aligned\n",
> +			       __func__, i, len);
> +			alignment_errs++;
> +		}
> +	}
> +
> +	/*
> +	 * File size can be <= ext list size, since extent sizes are constrained
> +	 * to PMD multiples
> +	 */
> +	if (imap.file_size > extent_total) {
> +		pr_err("%s: file size %lld larger than ext list size %lld\n",
> +		       __func__, (u64)imap.file_size, (u64)extent_total);
> +		rc = -EINVAL;
> +		goto errout;
> +	}
> +
> +	if (alignment_errs > 0) {
> +		pr_err("%s: there were %d alignment errors in the extent list\n",
> +		       __func__, alignment_errs);
> +		rc = -EINVAL;
> +		goto errout;
> +	}
> +
> +	/* Publish the famfs metadata on inode->i_private */
> +	inode_lock(inode);

Easy to add a guard definition - maybe useful enough to bother as can then do
this which makes the error handling align with other cases.

	scoped_guard(inode_sem, inode) {
		if (inode->i_private) {
			rc = -EEXIST;
			goto errout;
		}
		inode->...

	}
> +	if (inode->i_private) {
> +		rc = -EEXIST; /* file already has famfs metadata */
> +	} else {
> +		inode->i_private = meta;

You could use __free on the meta data and 
		inode->i_private = no_ptr_free(meta);
here. Then all your earlier error paths become direct returns.

> +		i_size_write(inode, imap.file_size);
> +		inode->i_flags |= S_DAX;
> +	}
> +	inode_unlock(inode);
> +
> + errout:
> +	if (rc)
> +		famfs_meta_free(meta);
A separate error path is going to be easier to follow as no if (rc)

> +
> +	return rc;
> +}
> +
> +/**
> + * famfs_file_ioctl() -  top-level famfs file ioctl handler
> + * @file:
> + * @cmd:
> + * @arg:
> + */
> +static
> +long
> +famfs_file_ioctl(
> +	struct file    *file,
> +	unsigned int    cmd,
> +	unsigned long   arg)
> +{
> +	long rc;
> +
> +	switch (cmd) {
> +	case FAMFSIOC_NOP:
> +		rc = 0;
		return 0;
> +		break;
> +
> +	case FAMFSIOC_MAP_CREATE:
> +		rc = famfs_file_init_dax(file, (void *)arg);
		return famfs_file_init_dax()

> +		break;
> +
> +	case FAMFSIOC_MAP_GET: {
> +		struct inode *inode = file_inode(file);
> +		struct famfs_file_meta *meta = inode->i_private;
> +		struct famfs_ioc_map umeta;
> +
> +		memset(&umeta, 0, sizeof(umeta));
> +
> +		if (meta) {
> +			/* TODO: do more to harmonize these structures */
> +			umeta.extent_type    = meta->tfs_extent_type;
> +			umeta.file_size      = i_size_read(inode);
> +			umeta.ext_list_count = meta->tfs_extent_ct;
> +
> +			rc = copy_to_user((void __user *)arg, &umeta, sizeof(umeta));
> +			if (rc)
> +				pr_err("%s: copy_to_user returned %ld\n", __func__, rc);
> +
> +		} else {
> +			rc = -EINVAL;
> +		}
Flip logic.

		if (!meta)
			return -EINVAL;

		umeta ...
		return 0;

> +	}
> +		break;
> +	case FAMFSIOC_MAP_GETEXT: {
> +		struct inode *inode = file_inode(file);
> +		struct famfs_file_meta *meta = inode->i_private;
> +
> +		if (meta)
> +			rc = copy_to_user((void __user *)arg, meta->tfs_extents,
> +					  meta->tfs_extent_ct * sizeof(struct famfs_extent));
> +		else
> +			rc = -EINVAL;
		if (!meta)
			return -EINVAL;

		return copy_to_user

> +	}
> +		break;
> +	default:
> +		rc = -ENOTTY;
return -ENOTTY;

> +		break;
> +	}
> +
> +	return rc;
Early returns will simplify the flow for anyone reading this.

> +}


  reply	other threads:[~2024-02-26 13:44 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-23 17:41 [RFC PATCH 00/20] Introduce the famfs shared-memory file system John Groves
2024-02-23 17:41 ` [RFC PATCH 01/20] famfs: Documentation John Groves
2024-02-23 17:41 ` [RFC PATCH 02/20] dev_dax_iomap: Add fs_dax_get() func to prepare dax for fs-dax usage John Groves
2024-02-26 12:05   ` Jonathan Cameron
2024-02-26 15:00     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 03/20] dev_dax_iomap: Move dax_pgoff_to_phys from device.c to bus.c since both need it now John Groves
2024-02-26 12:10   ` Jonathan Cameron
2024-02-26 15:13     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 04/20] dev_dax_iomap: Save the kva from memremap John Groves
2024-02-26 12:21   ` Jonathan Cameron
2024-02-26 15:48     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 05/20] dev_dax_iomap: Add dax_operations for use by fs-dax on devdax John Groves
2024-02-26 12:32   ` Jonathan Cameron
2024-02-26 16:09     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 06/20] dev_dax_iomap: Add CONFIG_DEV_DAX_IOMAP kernel build parameter John Groves
2024-02-26 12:34   ` Jonathan Cameron
2024-02-26 16:12     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 07/20] famfs: Add include/linux/famfs_ioctl.h John Groves
2024-02-24  1:39   ` Randy Dunlap
2024-02-24  2:23     ` John Groves
2024-02-24  3:27       ` Randy Dunlap
2024-02-24 23:32         ` John Groves
2024-02-24 23:40           ` Randy Dunlap
2024-02-26 12:39   ` Jonathan Cameron
2024-02-26 16:44     ` John Groves
2024-02-26 16:56       ` Jonathan Cameron
2024-02-26 18:04         ` John Groves
2024-02-23 17:41 ` [RFC PATCH 08/20] famfs: Add famfs_internal.h John Groves
2024-02-26 12:48   ` Jonathan Cameron
2024-02-26 17:35     ` John Groves
2024-02-27 10:28       ` Jonathan Cameron
2024-02-28  1:06         ` John Groves
2024-02-27 13:38   ` Christian Brauner
2024-02-27 14:12     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 09/20] famfs: Add super_operations John Groves
2024-02-26 12:51   ` Jonathan Cameron
2024-02-26 21:47     ` John Groves
2024-02-27 10:34       ` Jonathan Cameron
2024-02-27 17:48     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 10/20] famfs: famfs_open_device() & dax_holder_operations John Groves
2024-02-26 12:56   ` Jonathan Cameron
2024-02-26 22:22     ` John Groves
2024-02-27 13:39   ` Christian Brauner
2024-02-27 18:38     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 11/20] famfs: Add fs_context_operations John Groves
2024-02-26 13:20   ` Jonathan Cameron
2024-02-26 22:43     ` John Groves
2024-02-27 13:41   ` Christian Brauner
2024-02-28  0:59     ` John Groves
2024-02-28  1:49       ` Randy Dunlap
2024-02-28  8:17         ` Christian Brauner
2024-02-28 10:07       ` Christian Brauner
2024-02-28 12:01         ` Christian Brauner
2024-02-23 17:41 ` [RFC PATCH 12/20] famfs: Add inode_operations and file_system_type John Groves
2024-02-26 13:25   ` Jonathan Cameron
2024-02-26 22:53     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 13/20] famfs: Add iomap_ops John Groves
2024-02-26 13:30   ` Jonathan Cameron
2024-02-26 23:00     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 14/20] famfs: Add struct file_operations John Groves
2024-02-26 13:32   ` Jonathan Cameron
2024-02-26 23:09     ` John Groves
2024-02-23 17:41 ` [RFC PATCH 15/20] famfs: Add ioctl to file_operations John Groves
2024-02-26 13:44   ` Jonathan Cameron [this message]
2024-02-23 17:42 ` [RFC PATCH 16/20] famfs: Add fault counters John Groves
2024-02-23 18:23   ` Dave Hansen
2024-02-23 19:56     ` John Groves
2024-02-23 20:04       ` Dan Williams
2024-02-23 20:39         ` John Groves
2024-02-23 21:19           ` Dave Hansen
2024-02-23 23:50             ` Dan Williams
2024-02-24  3:59               ` Matthew Wilcox
2024-02-24  4:30                 ` Dan Williams
2024-02-23 17:42 ` [RFC PATCH 17/20] famfs: Add module stuff John Groves
2024-02-26 13:47   ` Jonathan Cameron
2024-02-27 22:15     ` John Groves
2024-02-23 17:42 ` [RFC PATCH 18/20] famfs: Support character dax via the dev_dax_iomap patch John Groves
2024-02-26 13:52   ` Jonathan Cameron
2024-02-27 22:27     ` John Groves
2024-02-23 17:42 ` [RFC PATCH 19/20] famfs: Update MAINTAINERS file John Groves
2024-02-23 17:42 ` [RFC PATCH 20/20] famfs: Add Kconfig and Makefile plumbing John Groves
2024-02-24  1:50   ` Randy Dunlap
2024-02-24  2:24     ` John Groves
2024-02-24  0:07 ` [RFC PATCH 00/20] Introduce the famfs shared-memory file system Luis Chamberlain
2024-02-26 13:27   ` John Groves
2024-02-26 15:53     ` Luis Chamberlain
2024-02-26 21:16       ` John Groves
2024-02-27  0:58         ` Luis Chamberlain
2024-02-27  2:05           ` John Groves
2024-02-29  2:15             ` Dave Chinner
2024-02-29 14:52               ` John Groves
2024-03-11  1:29                 ` Dave Chinner
2024-02-29  6:52 ` Amir Goldstein
2024-02-29 22:16   ` John Groves
2024-05-17  9:55   ` Miklos Szeredi
2024-05-19  5:59     ` Amir Goldstein
2024-05-22  2:05       ` John Groves
2024-05-22  8:58         ` Miklos Szeredi
2024-05-22 10:16           ` Amir Goldstein
2024-05-22 11:28             ` Miklos Szeredi
2024-05-22 13:41               ` Amir Goldstein
2024-05-23  2:49           ` John Groves
2024-05-23 13:57             ` Miklos Szeredi
2024-05-24  0:47               ` John Groves
2024-05-24  7:55                 ` Miklos Szeredi
2024-05-25 22:54                   ` Dave Chinner
2024-06-24 12:43               ` John Groves

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=20240226134408.00005576@Huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=John@Groves.net \
    --cc=brauner@kernel.org \
    --cc=corbet@lwn.net \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dave.jiang@intel.com \
    --cc=david@fromorbit.com \
    --cc=gregory.price@memverge.com \
    --cc=hch@infradead.org \
    --cc=jack@suse.cz \
    --cc=jgroves@micron.com \
    --cc=john@jagalactic.com \
    --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=nvdimm@lists.linux.dev \
    --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.