From: Daniel Henrique Debonzi <debonzi@xxxxxxxxxxxxxxxxxx> This patch make possible to set bsoflags using tgtadm to be passed to the backstore open function. Supported bsoflags options are sync and direct. Signed-off-by: Daniel Henrique Debonzi <debonzi@xxxxxxxxxxxxxxxxxx> --- usr/bs_rdwr.c | 3 ++- usr/spc.c | 5 ++++- usr/target.c | 33 +++++++++++++++++++++++++++------ usr/tgtadm.c | 23 +++++++++++++++++------ usr/tgtd.h | 2 ++ usr/util.c | 39 +++++++++++++++++++++++++++++++++++++++ usr/util.h | 2 ++ 7 files changed, 93 insertions(+), 14 deletions(-) diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c index 6068479..5d265e5 100644 --- a/usr/bs_rdwr.c +++ b/usr/bs_rdwr.c @@ -130,7 +130,7 @@ static void bs_rdwr_request(struct scsi_cmd *cmd) static int bs_rdwr_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size) { - *fd = backed_file_open(path, O_RDWR| O_LARGEFILE, size); + *fd = backed_file_open(path, O_RDWR | O_LARGEFILE | lu->bsoflags, size); if (*fd < 0) return *fd; @@ -170,6 +170,7 @@ static struct backingstore_template rdwr_bst = { .bs_exit = bs_rdwr_exit, .bs_cmd_submit = bs_thread_cmd_submit, .bs_cmd_done = bs_rdwr_cmd_done, + .bs_oflags_supported = O_SYNC | O_DIRECT, }; __attribute__((constructor)) static void bs_rdwr_constructor(void) diff --git a/usr/spc.c b/usr/spc.c index 14a3ee1..22fa975 100644 --- a/usr/spc.c +++ b/usr/spc.c @@ -1581,6 +1581,7 @@ enum { Opt_removable, Opt_online, Opt_mode_page, Opt_path, + Opt_bsoflags, Opt_err, }; @@ -1595,6 +1596,7 @@ static match_table_t tokens = { {Opt_online, "online=%s"}, {Opt_mode_page, "mode_page=%s"}, {Opt_path, "path=%s"}, + {Opt_bsoflags, "bsoflags=%s"}, {Opt_err, NULL}, }; @@ -1626,7 +1628,8 @@ int lu_config(struct scsi_lu *lu, char *params, match_fn_t *fn) while ((p = strsep(¶ms, ",")) != NULL) { substring_t args[MAX_OPT_ARGS]; - int token; + int token, lu_bsoflags = 0; + if (!*p) continue; token = match_token(p, tokens, args); diff --git a/usr/target.c b/usr/target.c index 2bc23fe..5fbfb0e 100644 --- a/usr/target.c +++ b/usr/target.c @@ -418,12 +418,13 @@ __device_lookup(int tid, uint64_t lun, struct target **t) } enum { - Opt_path, Opt_bstype, Opt_err, + Opt_path, Opt_bstype, Opt_bsoflags, Opt_err, }; static match_table_t device_tokens = { {Opt_path, "path=%s"}, {Opt_bstype, "bstype=%s"}, + {Opt_bsoflags, "bsoflags=%s"}, {Opt_err, NULL}, }; @@ -432,8 +433,8 @@ static void __cmd_done(struct target *, struct scsi_cmd *); int tgt_device_create(int tid, int dev_type, uint64_t lun, char *params, int backing) { - char *p, *path = NULL, *bstype = NULL; - int ret = 0; + char *p, *path = NULL, *bstype = NULL, *bsoflags = NULL; + int ret = 0, lu_bsoflags; struct target *target; struct scsi_lu *lu, *pos; struct device_type_template *t; @@ -456,6 +457,8 @@ int tgt_device_create(int tid, int dev_type, uint64_t lun, char *params, case Opt_bstype: bstype = match_strdup(&args[0]); break; + case Opt_bsoflags: + bsoflags = match_strdup(&args[0]); default: break; } @@ -487,6 +490,18 @@ int tgt_device_create(int tid, int dev_type, uint64_t lun, char *params, } else bst = get_backingstore_template("null"); + lu_bsoflags = str_to_open_flags(bsoflags); + if (lu_bsoflags == -1) { + ret = TGTADM_INVALID_REQUEST; + goto out; + } + + if (lu_bsoflags && !(bst->bs_oflags_supported & lu_bsoflags)) { + eprintf("bsoflags not supported\n"); + ret = TGTADM_INVALID_REQUEST; + goto out; + } + t = device_type_lookup(dev_type); if (!t) { eprintf("Unknown device type %d\n", dev_type); @@ -504,6 +519,8 @@ int tgt_device_create(int tid, int dev_type, uint64_t lun, char *params, lu->bst = bst; lu->tgt = target; lu->lun = lun; + lu->bsoflags = lu_bsoflags; + tgt_cmd_queue_init(&lu->cmd_queue); INIT_LIST_HEAD(&lu->registration_list); lu->prgeneration = 0; @@ -573,6 +590,8 @@ out: free(bstype); if (path) free(path); + if (bsoflags) + free(bsoflags); return ret; fail_bs_init: if (lu->bst->bs_exit) @@ -1654,10 +1673,10 @@ static char *print_type(int type) return name; } - int tgt_target_show_all(char *buf, int rest) { int total = 0, max = rest; + char strflags[128]; struct target *target; struct scsi_lu *lu; struct acl_entry *acl; @@ -1694,7 +1713,8 @@ int tgt_target_show_all(char *buf, int rest) _TAB3 "Online: %s\n" _TAB3 "Removable media: %s\n" _TAB3 "Backing store type: %s\n" - _TAB3 "Backing store path: %s\n", + _TAB3 "Backing store path: %s\n" + _TAB3 "Backing store flags: %s\n", lu->lun, print_type(lu->attrs.device_type), lu->attrs.scsi_id, @@ -1705,7 +1725,8 @@ int tgt_target_show_all(char *buf, int rest) lu->bst ? (lu->bst->bs_name ? : "Unknown") : "None", - lu->path ? : "None"); + lu->path ? : "None", + open_flags_to_str(strflags, lu->bsoflags)); if (!strcmp(tgt_drivers[target->lid]->name, "iscsi")) { int i, aid; diff --git a/usr/tgtadm.c b/usr/tgtadm.c index 8bcb390..d032aaf 100644 --- a/usr/tgtadm.c +++ b/usr/tgtadm.c @@ -112,6 +112,7 @@ struct option const long_options[] = { {"value", required_argument, NULL, 'v'}, {"backing-store", required_argument, NULL, 'b'}, {"bstype", required_argument, NULL, 'E'}, + {"bsoflags", required_argument, NULL, 'f'}, {"targetname", required_argument, NULL, 'T'}, {"initiator-address", required_argument, NULL, 'I'}, {"user", required_argument, NULL, 'u'}, @@ -126,7 +127,7 @@ struct option const long_options[] = { {NULL, 0, NULL, 0}, }; -static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:E:T:I:u:p:H:P:B:Y:O:C:"; +static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:E:f:T:I:u:p:H:P:B:Y:O:C:"; static void usage(int status) { @@ -153,12 +154,15 @@ Linux SCSI Target Framework Administration Utility, version %s\n\ enable the target to accept the specific initiators.\n\ --lld [driver] --mode target --op unbind --tid=[id] --initiator-address=[src]\n\ disable the specific permitted initiators.\n\ - --lld [driver] --mode logicalunit --op new --tid=[id] --lun=[lun] --backing-store=[path] --bstype=[type]\n\ + --lld [driver] --mode logicalunit --op new --tid=[id] --lun=[lun] \\\n\ + --backing-store=[path] --bstype=[type] --bsoflags=[options]\n\ add a new logical unit with [lun] to the specific\n\ target with [id]. The logical unit is offered\n\ to the initiators. [path] must be block device files\n\ (including LVM and RAID devices) or regular files.\n\ bstype option is optional.\n\ + bsoflags supported options are sync and direct\n\ + (sync:direct for both).\n\ --lld [driver] --mode logicalunit --op delete --tid=[id] --lun=[lun]\n\ delete the specific logical unit with [lun] that\n\ the target with [id] has.\n\ @@ -431,6 +435,7 @@ int main(int argc, char **argv) uint64_t sid, lun; char *name, *value, *path, *targetname, *params, *address, *targetOps; char *bstype; + char *bsoflags; char *user, *password; char *buf; size_t bufsz = BUFSIZE + sizeof(struct tgtadm_req); @@ -445,7 +450,7 @@ int main(int argc, char **argv) ac_dir = ACCOUNT_TYPE_INCOMING; rest = BUFSIZE; name = value = path = targetname = address = targetOps = bstype = NULL; - user = password = NULL; + bsoflags = user = password = NULL; buf = valloc(bufsz); if (!buf) { @@ -516,6 +521,9 @@ int main(int argc, char **argv) case 'H': hostno = strtol(optarg, NULL, 10); break; + case 'f': + bsoflags = optarg; + break; case 'E': bstype = optarg; break; @@ -644,7 +652,7 @@ int main(int argc, char **argv) if (mode == MODE_ACCOUNT) { switch (op) { case OP_NEW: - rc = verify_mode_params(argc, argv, "LmoupC"); + rc = verify_mode_params(argc, argv, "LmoupfC"); if (rc) { eprintf("logicalunit mode: option '-%c' is not " "allowed/supported\n", rc); @@ -717,7 +725,7 @@ int main(int argc, char **argv) } switch (op) { case OP_NEW: - rc = verify_mode_params(argc, argv, "LmotlbEYC"); + rc = verify_mode_params(argc, argv, "LmoftlbEYC"); if (rc) { eprintf("target mode: option '-%c' is not " "allowed/supported\n", rc); @@ -738,7 +746,7 @@ int main(int argc, char **argv) } break; case OP_UPDATE: - rc = verify_mode_params(argc, argv, "LmotlPC"); + rc = verify_mode_params(argc, argv, "LmoftlPC"); if (rc) { eprintf("option '-%c' not supported in " "logicalunit mode\n", rc); @@ -777,6 +785,9 @@ int main(int argc, char **argv) else if (bstype) shprintf(total, params, rest, "%sbstype=%s", rest == BUFSIZE ? "" : ",", bstype); + if (bsoflags) + shprintf(total, params, rest, "%sbsoflags=%s", + rest == BUFSIZE ? "" : ",", bsoflags); if (targetname) shprintf(total, params, rest, "%stargetname=%s", rest == BUFSIZE ? "" : ",", targetname); diff --git a/usr/tgtd.h b/usr/tgtd.h index 9c44994..7a198ef 100644 --- a/usr/tgtd.h +++ b/usr/tgtd.h @@ -124,6 +124,7 @@ struct backingstore_template { void (*bs_exit)(struct scsi_lu *dev); int (*bs_cmd_submit)(struct scsi_cmd *cmd); int (*bs_cmd_done)(struct scsi_cmd *cmd); + int bs_oflags_supported; struct list_head backingstore_siblings; }; @@ -151,6 +152,7 @@ struct scsi_lu { uint64_t size; uint64_t lun; char *path; + int bsoflags; /* the list of devices belonging to a target */ struct list_head device_siblings; diff --git a/usr/util.c b/usr/util.c index e91453d..fdd1805 100644 --- a/usr/util.c +++ b/usr/util.c @@ -136,3 +136,42 @@ int set_non_blocking(int fd) } return err; } + +int str_to_open_flags(char *buf) +{ + char *bsoflags_tok = NULL; + int open_flags = 0; + + bsoflags_tok = strtok(buf, ":\0"); + while (bsoflags_tok != NULL) { + while (*bsoflags_tok == ' ') + bsoflags_tok++; + if (!strncmp(bsoflags_tok, "sync", 4)) + open_flags |= O_SYNC; + else if (!strncmp(bsoflags_tok, "direct", 6)) + open_flags |= O_DIRECT; + else { + eprintf("bsoflag option %s not supported\n", + bsoflags_tok); + return -1; + } + + bsoflags_tok = strtok(NULL, ":"); + } + + return open_flags; +} + +char *open_flags_to_str(char *dest, int flags) +{ + *dest = '\0'; + + if (flags & O_SYNC) + strcat(dest, "sync"); + if (flags & O_DIRECT) { + if (*dest) + strcat(dest, ":"); + strcat(dest, "direct"); + } + return dest; +} diff --git a/usr/util.h b/usr/util.h index 6e1fd6f..24a5eb7 100644 --- a/usr/util.h +++ b/usr/util.h @@ -57,6 +57,8 @@ extern int chrdev_open(char *modname, char *devpath, uint8_t minor, int *fd); extern int backed_file_open(char *path, int oflag, uint64_t *size); extern int set_non_blocking(int fd); +extern int str_to_open_flags(char *buf); +extern char *open_flags_to_str(char *dest, int flags); #define zalloc(size) \ ({ \ -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html