Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4dff304 authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

target/file: Use O_DSYNC by default for FILEIO backends



Convert to use O_DSYNC for all cases at FILEIO backend creation time to
avoid the extra syncing of pure timestamp updates with legacy O_SYNC during
default operation as recommended by hch.  Continue to do this independently of
Write Cache Enable (WCE) bit, as WCE=0 is currently the default for all backend
devices and enabled by user on per device basis via attrib/emulate_write_cache.

This patch drops the now unnecessary fd_buffered_io= token usage that was
originally signalling when to explictly disable O_SYNC at backend creation
time for buffered I/O operation.  This can end up being dangerous for a number
of reasons during physical node failure, so go ahead and drop this option
for now when O_DSYNC is used as the default.

Also allow explict FUA WRITEs -> vfs_fsync_range() call to function in
fd_execute_cmd() independently of WCE bit setting.

Reported-by: default avatarChristoph Hellwig <hch@lst.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 5f2a3d61
Loading
Loading
Loading
Loading
+17 −53
Original line number Original line Diff line number Diff line
@@ -133,16 +133,11 @@ static struct se_device *fd_create_virtdevice(
		ret = PTR_ERR(dev_p);
		ret = PTR_ERR(dev_p);
		goto fail;
		goto fail;
	}
	}

	/* O_DIRECT too? */
	flags = O_RDWR | O_CREAT | O_LARGEFILE;

	/*
	/*
	 * If fd_buffered_io=1 has not been set explicitly (the default),
	 * Use O_DSYNC by default instead of O_SYNC to forgo syncing
	 * use O_SYNC to force FILEIO writes to disk.
	 * of pure timestamp updates.
	 */
	 */
	if (!(fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO))
	flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
		flags |= O_SYNC;


	file = filp_open(dev_p, flags, 0600);
	file = filp_open(dev_p, flags, 0600);
	if (IS_ERR(file)) {
	if (IS_ERR(file)) {
@@ -380,23 +375,6 @@ static void fd_emulate_sync_cache(struct se_cmd *cmd)
	}
	}
}
}


static void fd_emulate_write_fua(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct fd_dev *fd_dev = dev->dev_ptr;
	loff_t start = cmd->t_task_lba *
		dev->se_sub_dev->se_dev_attrib.block_size;
	loff_t end = start + cmd->data_length;
	int ret;

	pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n",
		cmd->t_task_lba, cmd->data_length);

	ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1);
	if (ret != 0)
		pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret);
}

static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
		u32 sgl_nents, enum dma_data_direction data_direction)
		u32 sgl_nents, enum dma_data_direction data_direction)
{
{
@@ -411,19 +389,21 @@ static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
		ret = fd_do_readv(cmd, sgl, sgl_nents);
		ret = fd_do_readv(cmd, sgl, sgl_nents);
	} else {
	} else {
		ret = fd_do_writev(cmd, sgl, sgl_nents);
		ret = fd_do_writev(cmd, sgl, sgl_nents);

		/*
		 * Perform implict vfs_fsync_range() for fd_do_writev() ops
		 * for SCSI WRITEs with Forced Unit Access (FUA) set.
		 * Allow this to happen independent of WCE=0 setting.
		 */
		if (ret > 0 &&
		if (ret > 0 &&
		    dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 &&
		    dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 &&
		    dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 &&
		    (cmd->se_cmd_flags & SCF_FUA)) {
		    (cmd->se_cmd_flags & SCF_FUA)) {
			/*
			struct fd_dev *fd_dev = dev->dev_ptr;
			 * We might need to be a bit smarter here
			loff_t start = cmd->t_task_lba *
			 * and return some sense data to let the initiator
				dev->se_sub_dev->se_dev_attrib.block_size;
			 * know the FUA WRITE cache sync failed..?
			loff_t end = start + cmd->data_length;
			 */
			fd_emulate_write_fua(cmd);
		}


			vfs_fsync_range(fd_dev->fd_file, start, end, 1);
		}
	}
	}


	if (ret < 0) {
	if (ret < 0) {
@@ -442,7 +422,6 @@ enum {
static match_table_t tokens = {
static match_table_t tokens = {
	{Opt_fd_dev_name, "fd_dev_name=%s"},
	{Opt_fd_dev_name, "fd_dev_name=%s"},
	{Opt_fd_dev_size, "fd_dev_size=%s"},
	{Opt_fd_dev_size, "fd_dev_size=%s"},
	{Opt_fd_buffered_io, "fd_buffered_io=%d"},
	{Opt_err, NULL}
	{Opt_err, NULL}
};
};


@@ -454,7 +433,7 @@ static ssize_t fd_set_configfs_dev_params(
	struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
	struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
	char *orig, *ptr, *arg_p, *opts;
	char *orig, *ptr, *arg_p, *opts;
	substring_t args[MAX_OPT_ARGS];
	substring_t args[MAX_OPT_ARGS];
	int ret = 0, arg, token;
	int ret = 0, token;


	opts = kstrdup(page, GFP_KERNEL);
	opts = kstrdup(page, GFP_KERNEL);
	if (!opts)
	if (!opts)
@@ -498,19 +477,6 @@ static ssize_t fd_set_configfs_dev_params(
					" bytes\n", fd_dev->fd_dev_size);
					" bytes\n", fd_dev->fd_dev_size);
			fd_dev->fbd_flags |= FBDF_HAS_SIZE;
			fd_dev->fbd_flags |= FBDF_HAS_SIZE;
			break;
			break;
		case Opt_fd_buffered_io:
			match_int(args, &arg);
			if (arg != 1) {
				pr_err("bogus fd_buffered_io=%d value\n", arg);
				ret = -EINVAL;
				goto out;
			}

			pr_debug("FILEIO: Using buffered I/O"
				" operations for struct fd_dev\n");

			fd_dev->fbd_flags |= FDBD_USE_BUFFERED_IO;
			break;
		default:
		default:
			break;
			break;
		}
		}
@@ -542,10 +508,8 @@ static ssize_t fd_show_configfs_dev_params(
	ssize_t bl = 0;
	ssize_t bl = 0;


	bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id);
	bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id);
	bl += sprintf(b + bl, "        File: %s  Size: %llu  Mode: %s\n",
	bl += sprintf(b + bl, "        File: %s  Size: %llu  Mode: O_DSYNC\n",
		fd_dev->fd_dev_name, fd_dev->fd_dev_size,
		fd_dev->fd_dev_name, fd_dev->fd_dev_size);
		(fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO) ?
		"Buffered" : "Synchronous");
	return bl;
	return bl;
}
}


+0 −1
Original line number Original line Diff line number Diff line
@@ -14,7 +14,6 @@


#define FBDF_HAS_PATH		0x01
#define FBDF_HAS_PATH		0x01
#define FBDF_HAS_SIZE		0x02
#define FBDF_HAS_SIZE		0x02
#define FDBD_USE_BUFFERED_IO	0x04


struct fd_dev {
struct fd_dev {
	u32		fbd_flags;
	u32		fbd_flags;