diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-09-29 20:15:37 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-10-02 16:15:21 -0400 |
commit | b32f4c7ed85c5cee2a21a55c9f59ebc9d57a2463 (patch) | |
tree | 547896c5f54e03ba8635ae22b35f4d534b2272fe /drivers/target | |
parent | f25590f39d543272f7ae7b00d533359c8d7ff331 (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.c | 41 | ||||
-rw-r--r-- | drivers/target/target_core_file.h | 1 |
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 { | |||
407 | static match_table_t tokens = { | 426 | static 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 | ||
18 | struct fd_dev { | 19 | struct fd_dev { |
19 | u32 fbd_flags; | 20 | u32 fbd_flags; |