aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-09-29 20:15:37 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-10-02 16:15:21 -0400
commitb32f4c7ed85c5cee2a21a55c9f59ebc9d57a2463 (patch)
tree547896c5f54e03ba8635ae22b35f4d534b2272fe /drivers/target
parentf25590f39d543272f7ae7b00d533359c8d7ff331 (diff)
target/file: Re-enable optional fd_buffered_io=1 operation
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 a4dff3043c231d57f982af635c9d2192ee40e5ae 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: Ferry <iscsitmp@bananateam.nl> Cc: Christoph Hellwig <hch@lst.de> Cc: <stable@vger.kernel.org> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_file.c41
-rw-r--r--drivers/target/target_core_file.h1
2 files changed, 39 insertions, 3 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 11119257e514..0360383dfb94 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -125,6 +125,19 @@ static struct se_device *fd_create_virtdevice(
125 * of pure timestamp updates. 125 * of pure timestamp updates.
126 */ 126 */
127 flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; 127 flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
128 /*
129 * Optionally allow fd_buffered_io=1 to be enabled for people
130 * who want use the fs buffer cache as an WriteCache mechanism.
131 *
132 * This means that in event of a hard failure, there is a risk
133 * of silent data-loss if the SCSI client has *not* performed a
134 * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE
135 * to write-out the entire device cache.
136 */
137 if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
138 pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n");
139 flags &= ~O_DSYNC;
140 }
128 141
129 file = filp_open(fd_dev->fd_dev_name, flags, 0600); 142 file = filp_open(fd_dev->fd_dev_name, flags, 0600);
130 if (IS_ERR(file)) { 143 if (IS_ERR(file)) {
@@ -188,6 +201,12 @@ static struct se_device *fd_create_virtdevice(
188 if (!dev) 201 if (!dev)
189 goto fail; 202 goto fail;
190 203
204 if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
205 pr_debug("FILEIO: Forcing setting of emulate_write_cache=1"
206 " with FDBD_HAS_BUFFERED_IO_WCE\n");
207 dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1;
208 }
209
191 fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; 210 fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
192 fd_dev->fd_queue_depth = dev->queue_depth; 211 fd_dev->fd_queue_depth = dev->queue_depth;
193 212
@@ -407,6 +426,7 @@ enum {
407static match_table_t tokens = { 426static match_table_t tokens = {
408 {Opt_fd_dev_name, "fd_dev_name=%s"}, 427 {Opt_fd_dev_name, "fd_dev_name=%s"},
409 {Opt_fd_dev_size, "fd_dev_size=%s"}, 428 {Opt_fd_dev_size, "fd_dev_size=%s"},
429 {Opt_fd_buffered_io, "fd_buffered_io=%d"},
410 {Opt_err, NULL} 430 {Opt_err, NULL}
411}; 431};
412 432
@@ -418,7 +438,7 @@ static ssize_t fd_set_configfs_dev_params(
418 struct fd_dev *fd_dev = se_dev->se_dev_su_ptr; 438 struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
419 char *orig, *ptr, *arg_p, *opts; 439 char *orig, *ptr, *arg_p, *opts;
420 substring_t args[MAX_OPT_ARGS]; 440 substring_t args[MAX_OPT_ARGS];
421 int ret = 0, token; 441 int ret = 0, arg, token;
422 442
423 opts = kstrdup(page, GFP_KERNEL); 443 opts = kstrdup(page, GFP_KERNEL);
424 if (!opts) 444 if (!opts)
@@ -459,6 +479,19 @@ static ssize_t fd_set_configfs_dev_params(
459 " bytes\n", fd_dev->fd_dev_size); 479 " bytes\n", fd_dev->fd_dev_size);
460 fd_dev->fbd_flags |= FBDF_HAS_SIZE; 480 fd_dev->fbd_flags |= FBDF_HAS_SIZE;
461 break; 481 break;
482 case Opt_fd_buffered_io:
483 match_int(args, &arg);
484 if (arg != 1) {
485 pr_err("bogus fd_buffered_io=%d value\n", arg);
486 ret = -EINVAL;
487 goto out;
488 }
489
490 pr_debug("FILEIO: Using buffered I/O"
491 " operations for struct fd_dev\n");
492
493 fd_dev->fbd_flags |= FDBD_HAS_BUFFERED_IO_WCE;
494 break;
462 default: 495 default:
463 break; 496 break;
464 } 497 }
@@ -490,8 +523,10 @@ static ssize_t fd_show_configfs_dev_params(
490 ssize_t bl = 0; 523 ssize_t bl = 0;
491 524
492 bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id); 525 bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id);
493 bl += sprintf(b + bl, " File: %s Size: %llu Mode: O_DSYNC\n", 526 bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n",
494 fd_dev->fd_dev_name, fd_dev->fd_dev_size); 527 fd_dev->fd_dev_name, fd_dev->fd_dev_size,
528 (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) ?
529 "Buffered-WCE" : "O_DSYNC");
495 return bl; 530 return bl;
496} 531}
497 532
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h
index 70ce7fd7111d..876ae53ef5b8 100644
--- a/drivers/target/target_core_file.h
+++ b/drivers/target/target_core_file.h
@@ -14,6 +14,7 @@
14 14
15#define FBDF_HAS_PATH 0x01 15#define FBDF_HAS_PATH 0x01
16#define FBDF_HAS_SIZE 0x02 16#define FBDF_HAS_SIZE 0x02
17#define FDBD_HAS_BUFFERED_IO_WCE 0x04
17 18
18struct fd_dev { 19struct fd_dev {
19 u32 fbd_flags; 20 u32 fbd_flags;