Commit b32f4c7ed85c5cee2a21a55c9f59ebc9d57a2463

Authored by Nicholas Bellinger
1 parent f25590f39d

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>

Showing 2 changed files with 39 additions and 3 deletions Side-by-side Diff

drivers/target/target_core_file.c
... ... @@ -125,6 +125,19 @@
125 125 * of pure timestamp updates.
126 126 */
127 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 142 file = filp_open(fd_dev->fd_dev_name, flags, 0600);
130 143 if (IS_ERR(file)) {
... ... @@ -188,6 +201,12 @@
188 201 if (!dev)
189 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 210 fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
192 211 fd_dev->fd_queue_depth = dev->queue_depth;
193 212  
... ... @@ -407,6 +426,7 @@
407 426 static match_table_t tokens = {
408 427 {Opt_fd_dev_name, "fd_dev_name=%s"},
409 428 {Opt_fd_dev_size, "fd_dev_size=%s"},
  429 + {Opt_fd_buffered_io, "fd_buffered_io=%d"},
410 430 {Opt_err, NULL}
411 431 };
412 432  
... ... @@ -418,7 +438,7 @@
418 438 struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
419 439 char *orig, *ptr, *arg_p, *opts;
420 440 substring_t args[MAX_OPT_ARGS];
421   - int ret = 0, token;
  441 + int ret = 0, arg, token;
422 442  
423 443 opts = kstrdup(page, GFP_KERNEL);
424 444 if (!opts)
... ... @@ -459,6 +479,19 @@
459 479 " bytes\n", fd_dev->fd_dev_size);
460 480 fd_dev->fbd_flags |= FBDF_HAS_SIZE;
461 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 495 default:
463 496 break;
464 497 }
... ... @@ -490,8 +523,10 @@
490 523 ssize_t bl = 0;
491 524  
492 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",
494   - fd_dev->fd_dev_name, fd_dev->fd_dev_size);
  526 + bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n",
  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 530 return bl;
496 531 }
497 532  
drivers/target/target_core_file.h
... ... @@ -14,6 +14,7 @@
14 14  
15 15 #define FBDF_HAS_PATH 0x01
16 16 #define FBDF_HAS_SIZE 0x02
  17 +#define FDBD_HAS_BUFFERED_IO_WCE 0x04
17 18  
18 19 struct fd_dev {
19 20 u32 fbd_flags;