Commit 230a0c3b authored by Nicholas Bellinger's avatar Nicholas Bellinger Committed by Greg Kroah-Hartman

target/file: Re-enable optional fd_buffered_io=1 operation

commit b32f4c7e upstream.

This patch re-adds the ability to optionally run in buffered FILEIO mode
(eg: w/o O_DSYNC) for device backends in order to once again use the
Linux buffered cache as a write-back storage mechanism.

This logic was originally dropped with mainline v3.5-rc commit:

commit a4dff304
Author: Nicholas Bellinger <nab@linux-iscsi.org>
Date:   Wed May 30 16:25:41 2012 -0700

    target/file: Use O_DSYNC by default for FILEIO backends

This difference with this patch is that fd_create_virtdevice() now
forces the explicit setting of emulate_write_cache=1 when buffered FILEIO
operation has been enabled.

(v2: Switch to FDBD_HAS_BUFFERED_IO_WCE + add more detailed
     comment as requested by hch)
Reported-by: default avatarFerry <iscsitmp@bananateam.nl>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
Cc: Li Zefan <lizefan@huawei.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 45a0374f
...@@ -138,6 +138,19 @@ static struct se_device *fd_create_virtdevice( ...@@ -138,6 +138,19 @@ static struct se_device *fd_create_virtdevice(
* of pure timestamp updates. * of pure timestamp updates.
*/ */
flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
/*
* Optionally allow fd_buffered_io=1 to be enabled for people
* who want use the fs buffer cache as an WriteCache mechanism.
*
* This means that in event of a hard failure, there is a risk
* of silent data-loss if the SCSI client has *not* performed a
* forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE
* to write-out the entire device cache.
*/
if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n");
flags &= ~O_DSYNC;
}
file = filp_open(dev_p, flags, 0600); file = filp_open(dev_p, flags, 0600);
if (IS_ERR(file)) { if (IS_ERR(file)) {
...@@ -205,6 +218,12 @@ static struct se_device *fd_create_virtdevice( ...@@ -205,6 +218,12 @@ static struct se_device *fd_create_virtdevice(
if (!dev) if (!dev)
goto fail; goto fail;
if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
pr_debug("FILEIO: Forcing setting of emulate_write_cache=1"
" with FDBD_HAS_BUFFERED_IO_WCE\n");
dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1;
}
fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
fd_dev->fd_queue_depth = dev->queue_depth; fd_dev->fd_queue_depth = dev->queue_depth;
...@@ -449,6 +468,7 @@ enum { ...@@ -449,6 +468,7 @@ 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}
}; };
...@@ -460,7 +480,7 @@ static ssize_t fd_set_configfs_dev_params( ...@@ -460,7 +480,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, token; int ret = 0, arg, token;
opts = kstrdup(page, GFP_KERNEL); opts = kstrdup(page, GFP_KERNEL);
if (!opts) if (!opts)
...@@ -504,6 +524,19 @@ static ssize_t fd_set_configfs_dev_params( ...@@ -504,6 +524,19 @@ 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_HAS_BUFFERED_IO_WCE;
break;
default: default:
break; break;
} }
...@@ -535,8 +568,10 @@ static ssize_t fd_show_configfs_dev_params( ...@@ -535,8 +568,10 @@ 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: O_DSYNC\n", bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\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_HAS_BUFFERED_IO_WCE) ?
"Buffered-WCE" : "O_DSYNC");
return bl; return bl;
} }
......
...@@ -18,6 +18,7 @@ struct fd_request { ...@@ -18,6 +18,7 @@ struct fd_request {
#define FBDF_HAS_PATH 0x01 #define FBDF_HAS_PATH 0x01
#define FBDF_HAS_SIZE 0x02 #define FBDF_HAS_SIZE 0x02
#define FDBD_HAS_BUFFERED_IO_WCE 0x04
struct fd_dev { struct fd_dev {
u32 fbd_flags; u32 fbd_flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment