diff options
author | Alex Elder <elder@inktank.com> | 2012-08-10 16:12:07 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2012-10-01 15:30:50 -0400 |
commit | cc0538b62c839c2df7b9f8378bb37e3b35faa608 (patch) | |
tree | a721584161916d3ba4ebe62cd919a4248b966145 | |
parent | f8c3892911145db7cf895cc26f53ad73dd4e7b1f (diff) |
rbd: add read_only rbd map option
Add the ability to map an rbd image read-only, by specifying either
"read_only" or "ro" as an option on the rbd "command line." Also
allow the inverse to be explicitly specified using "read_write" or
"rw".
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | drivers/block/rbd.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 839ab730a1f3..2db51cef9560 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -69,7 +69,8 @@ | |||
69 | #define DEV_NAME_LEN 32 | 69 | #define DEV_NAME_LEN 32 |
70 | #define MAX_INT_FORMAT_WIDTH ((5 * sizeof (int)) / 2 + 1) | 70 | #define MAX_INT_FORMAT_WIDTH ((5 * sizeof (int)) / 2 + 1) |
71 | 71 | ||
72 | #define RBD_NOTIFY_TIMEOUT_DEFAULT 10 | 72 | #define RBD_NOTIFY_TIMEOUT_DEFAULT 10 |
73 | #define RBD_READ_ONLY_DEFAULT false | ||
73 | 74 | ||
74 | /* | 75 | /* |
75 | * block device image metadata (in-memory version) | 76 | * block device image metadata (in-memory version) |
@@ -91,6 +92,7 @@ struct rbd_image_header { | |||
91 | 92 | ||
92 | struct rbd_options { | 93 | struct rbd_options { |
93 | int notify_timeout; | 94 | int notify_timeout; |
95 | bool read_only; | ||
94 | }; | 96 | }; |
95 | 97 | ||
96 | /* | 98 | /* |
@@ -176,7 +178,7 @@ struct rbd_device { | |||
176 | u64 snap_id; /* current snapshot id */ | 178 | u64 snap_id; /* current snapshot id */ |
177 | /* whether the snap_id this device reads from still exists */ | 179 | /* whether the snap_id this device reads from still exists */ |
178 | bool snap_exists; | 180 | bool snap_exists; |
179 | int read_only; | 181 | bool read_only; |
180 | 182 | ||
181 | struct list_head node; | 183 | struct list_head node; |
182 | 184 | ||
@@ -351,12 +353,21 @@ enum { | |||
351 | /* int args above */ | 353 | /* int args above */ |
352 | Opt_last_string, | 354 | Opt_last_string, |
353 | /* string args above */ | 355 | /* string args above */ |
356 | Opt_read_only, | ||
357 | Opt_read_write, | ||
358 | /* Boolean args above */ | ||
359 | Opt_last_bool, | ||
354 | }; | 360 | }; |
355 | 361 | ||
356 | static match_table_t rbd_opts_tokens = { | 362 | static match_table_t rbd_opts_tokens = { |
357 | {Opt_notify_timeout, "notify_timeout=%d"}, | 363 | {Opt_notify_timeout, "notify_timeout=%d"}, |
358 | /* int args above */ | 364 | /* int args above */ |
359 | /* string args above */ | 365 | /* string args above */ |
366 | {Opt_read_only, "read_only"}, | ||
367 | {Opt_read_only, "ro"}, /* Alternate spelling */ | ||
368 | {Opt_read_write, "read_write"}, | ||
369 | {Opt_read_write, "rw"}, /* Alternate spelling */ | ||
370 | /* Boolean args above */ | ||
360 | {-1, NULL} | 371 | {-1, NULL} |
361 | }; | 372 | }; |
362 | 373 | ||
@@ -381,6 +392,8 @@ static int parse_rbd_opts_token(char *c, void *private) | |||
381 | } else if (token > Opt_last_int && token < Opt_last_string) { | 392 | } else if (token > Opt_last_int && token < Opt_last_string) { |
382 | dout("got string token %d val %s\n", token, | 393 | dout("got string token %d val %s\n", token, |
383 | argstr[0].from); | 394 | argstr[0].from); |
395 | } else if (token > Opt_last_string && token < Opt_last_bool) { | ||
396 | dout("got Boolean token %d\n", token); | ||
384 | } else { | 397 | } else { |
385 | dout("got token %d\n", token); | 398 | dout("got token %d\n", token); |
386 | } | 399 | } |
@@ -389,6 +402,12 @@ static int parse_rbd_opts_token(char *c, void *private) | |||
389 | case Opt_notify_timeout: | 402 | case Opt_notify_timeout: |
390 | rbd_opts->notify_timeout = intval; | 403 | rbd_opts->notify_timeout = intval; |
391 | break; | 404 | break; |
405 | case Opt_read_only: | ||
406 | rbd_opts->read_only = true; | ||
407 | break; | ||
408 | case Opt_read_write: | ||
409 | rbd_opts->read_only = false; | ||
410 | break; | ||
392 | default: | 411 | default: |
393 | BUG_ON(token); | 412 | BUG_ON(token); |
394 | } | 413 | } |
@@ -407,6 +426,7 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr, | |||
407 | struct rbd_client *rbdc; | 426 | struct rbd_client *rbdc; |
408 | 427 | ||
409 | rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT; | 428 | rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT; |
429 | rbd_opts->read_only = RBD_READ_ONLY_DEFAULT; | ||
410 | 430 | ||
411 | ceph_opts = ceph_parse_options(options, mon_addr, | 431 | ceph_opts = ceph_parse_options(options, mon_addr, |
412 | mon_addr + mon_addr_len, | 432 | mon_addr + mon_addr_len, |
@@ -620,7 +640,7 @@ static int rbd_header_set_snap(struct rbd_device *rbd_dev, u64 *size) | |||
620 | sizeof (RBD_SNAP_HEAD_NAME))) { | 640 | sizeof (RBD_SNAP_HEAD_NAME))) { |
621 | rbd_dev->snap_id = CEPH_NOSNAP; | 641 | rbd_dev->snap_id = CEPH_NOSNAP; |
622 | rbd_dev->snap_exists = false; | 642 | rbd_dev->snap_exists = false; |
623 | rbd_dev->read_only = 0; | 643 | rbd_dev->read_only = rbd_dev->rbd_opts.read_only; |
624 | if (size) | 644 | if (size) |
625 | *size = rbd_dev->header.image_size; | 645 | *size = rbd_dev->header.image_size; |
626 | } else { | 646 | } else { |
@@ -632,7 +652,7 @@ static int rbd_header_set_snap(struct rbd_device *rbd_dev, u64 *size) | |||
632 | goto done; | 652 | goto done; |
633 | rbd_dev->snap_id = snap_id; | 653 | rbd_dev->snap_id = snap_id; |
634 | rbd_dev->snap_exists = true; | 654 | rbd_dev->snap_exists = true; |
635 | rbd_dev->read_only = 1; | 655 | rbd_dev->read_only = true; /* No choice for snapshots */ |
636 | } | 656 | } |
637 | 657 | ||
638 | ret = 0; | 658 | ret = 0; |