* [PATCH 1/8] rbd: get rid of snap_name_len
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
@ 2012-10-26 23:00 ` Alex Elder
2012-10-29 21:14 ` Josh Durgin
2012-10-26 23:00 ` [PATCH 2/8] rbd: remove options args from rbd_add_parse_args() Alex Elder
` (6 subsequent siblings)
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:00 UTC (permalink / raw)
To: ceph-devel
The value returned in the "snap_name_len" argument to
rbd_add_parse_args() is never actually used, so get rid of it.
The snap_name_len recorded in *rbd_dev_v2_snap_name() is not
useful either, so get rid of that too.
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4fe14ff..cae7423 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2408,7 +2408,6 @@ static char *rbd_dev_v2_snap_name(struct
rbd_device *rbd_dev, u32 which)
int ret;
void *p;
void *end;
- size_t snap_name_len;
char *snap_name;
size = sizeof (__le32) + RBD_MAX_SNAP_NAME_LEN;
@@ -2428,9 +2427,7 @@ static char *rbd_dev_v2_snap_name(struct
rbd_device *rbd_dev, u32 which)
p = reply_buf;
end = (char *) reply_buf + size;
- snap_name_len = 0;
- snap_name = ceph_extract_encoded_string(&p, end, &snap_name_len,
- GFP_KERNEL);
+ snap_name = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL);
if (IS_ERR(snap_name)) {
ret = PTR_ERR(snap_name);
goto out;
@@ -2849,8 +2846,7 @@ static struct ceph_options
*rbd_add_parse_args(struct rbd_device *rbd_dev,
const char *buf,
char *options,
size_t options_size,
- char **snap_name,
- size_t *snap_name_len)
+ char **snap_name)
{
size_t len;
const char *mon_addrs;
@@ -2898,7 +2894,7 @@ static struct ceph_options
*rbd_add_parse_args(struct rbd_device *rbd_dev,
goto out_err;
memcpy(*snap_name, buf, len);
*(*snap_name + len) = '\0';
- *snap_name_len = len;
+
/* Initialize all rbd options to the defaults */
rbd_opts.read_only = RBD_READ_ONLY_DEFAULT;
@@ -3131,7 +3127,6 @@ static ssize_t rbd_add(struct bus_type *bus,
char *options;
struct rbd_device *rbd_dev = NULL;
char *snap_name;
- size_t snap_name_len = 0;
struct ceph_options *ceph_opts;
struct ceph_osd_client *osdc;
int rc = -ENOMEM;
@@ -3154,7 +3149,7 @@ static ssize_t rbd_add(struct bus_type *bus,
/* parse add command */
ceph_opts = rbd_add_parse_args(rbd_dev, buf, options, count,
- &snap_name, &snap_name_len);
+ &snap_name);
if (IS_ERR(ceph_opts)) {
rc = PTR_ERR(ceph_opts);
goto err_out_mem;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 1/8] rbd: get rid of snap_name_len
2012-10-26 23:00 ` [PATCH 1/8] rbd: get rid of snap_name_len Alex Elder
@ 2012-10-29 21:14 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 21:14 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
On 10/26/2012 04:00 PM, Alex Elder wrote:
> The value returned in the "snap_name_len" argument to
> rbd_add_parse_args() is never actually used, so get rid of it.
>
> The snap_name_len recorded in *rbd_dev_v2_snap_name() is not
> useful either, so get rid of that too.
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 13 ++++---------
> 1 file changed, 4 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 4fe14ff..cae7423 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -2408,7 +2408,6 @@ static char *rbd_dev_v2_snap_name(struct
> rbd_device *rbd_dev, u32 which)
> int ret;
> void *p;
> void *end;
> - size_t snap_name_len;
> char *snap_name;
>
> size = sizeof (__le32) + RBD_MAX_SNAP_NAME_LEN;
> @@ -2428,9 +2427,7 @@ static char *rbd_dev_v2_snap_name(struct
> rbd_device *rbd_dev, u32 which)
>
> p = reply_buf;
> end = (char *) reply_buf + size;
> - snap_name_len = 0;
> - snap_name = ceph_extract_encoded_string(&p, end, &snap_name_len,
> - GFP_KERNEL);
> + snap_name = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL);
> if (IS_ERR(snap_name)) {
> ret = PTR_ERR(snap_name);
> goto out;
> @@ -2849,8 +2846,7 @@ static struct ceph_options
> *rbd_add_parse_args(struct rbd_device *rbd_dev,
> const char *buf,
> char *options,
> size_t options_size,
> - char **snap_name,
> - size_t *snap_name_len)
> + char **snap_name)
> {
> size_t len;
> const char *mon_addrs;
> @@ -2898,7 +2894,7 @@ static struct ceph_options
> *rbd_add_parse_args(struct rbd_device *rbd_dev,
> goto out_err;
> memcpy(*snap_name, buf, len);
> *(*snap_name + len) = '\0';
> - *snap_name_len = len;
> +
> /* Initialize all rbd options to the defaults */
>
> rbd_opts.read_only = RBD_READ_ONLY_DEFAULT;
> @@ -3131,7 +3127,6 @@ static ssize_t rbd_add(struct bus_type *bus,
> char *options;
> struct rbd_device *rbd_dev = NULL;
> char *snap_name;
> - size_t snap_name_len = 0;
> struct ceph_options *ceph_opts;
> struct ceph_osd_client *osdc;
> int rc = -ENOMEM;
> @@ -3154,7 +3149,7 @@ static ssize_t rbd_add(struct bus_type *bus,
>
> /* parse add command */
> ceph_opts = rbd_add_parse_args(rbd_dev, buf, options, count,
> - &snap_name, &snap_name_len);
> + &snap_name);
> if (IS_ERR(ceph_opts)) {
> rc = PTR_ERR(ceph_opts);
> goto err_out_mem;
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 2/8] rbd: remove options args from rbd_add_parse_args()
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
2012-10-26 23:00 ` [PATCH 1/8] rbd: get rid of snap_name_len Alex Elder
@ 2012-10-26 23:00 ` Alex Elder
2012-10-29 21:17 ` Josh Durgin
2012-10-26 23:01 ` [PATCH 3/8] rbd: remove snap_name arg " Alex Elder
` (5 subsequent siblings)
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:00 UTC (permalink / raw)
To: ceph-devel
They "options" argument to rbd_add_parse_args() (and it's partner
options_size) is now only needed within the function, so there's no
need to have the caller allocate and pass the options buffer. Just
allocate the options buffer within the function using dup_token().
Also distinguish between failures due to failed memory allocation
and failing because a required argument was missing.
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 58
+++++++++++++++++++++++++--------------------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index cae7423..f900f3b 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2844,54 +2844,58 @@ static inline char *dup_token(const char **buf,
size_t *lenp)
*/
static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
const char *buf,
- char *options,
- size_t options_size,
char **snap_name)
{
size_t len;
const char *mon_addrs;
size_t mon_addrs_size;
+ char *options;
+ struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
struct rbd_options rbd_opts;
struct ceph_options *ceph_opts;
- struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
/* The first four tokens are required */
len = next_token(&buf);
if (!len)
- return err_ptr;
- mon_addrs_size = len + 1;
+ return err_ptr; /* Missing monitor address(es) */
mon_addrs = buf;
-
+ mon_addrs_size = len + 1;
buf += len;
- len = copy_token(&buf, options, options_size);
- if (!len || len >= options_size)
- return err_ptr;
+ options = dup_token(&buf, NULL);
+ if (!options)
+ goto out_mem;
+ if (!*options)
+ goto out_err; /* Missing options */
- err_ptr = ERR_PTR(-ENOMEM);
rbd_dev->pool_name = dup_token(&buf, NULL);
if (!rbd_dev->pool_name)
- goto out_err;
+ goto out_mem;
+ if (!*rbd_dev->pool_name)
+ goto out_err; /* Missing pool name */
rbd_dev->image_name = dup_token(&buf, &rbd_dev->image_name_len);
if (!rbd_dev->image_name)
- goto out_err;
-
- /* Snapshot name is optional; default is to use "head" */
+ goto out_mem;
+ if (!*rbd_dev->image_name)
+ goto out_err; /* Missing image name */
+ /*
+ * Snapshot name is optional; default is to use "-"
+ * (indicating the head/no snapshot).
+ */
len = next_token(&buf);
- if (len > RBD_MAX_SNAP_NAME_LEN) {
- err_ptr = ERR_PTR(-ENAMETOOLONG);
- goto out_err;
- }
if (!len) {
buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
+ } else if (len > RBD_MAX_SNAP_NAME_LEN) {
+ err_ptr = ERR_PTR(-ENAMETOOLONG);
+ goto out_err;
}
*snap_name = kmalloc(len + 1, GFP_KERNEL);
if (!*snap_name)
- goto out_err;
+ goto out_mem;
memcpy(*snap_name, buf, len);
*(*snap_name + len) = '\0';
@@ -2902,20 +2906,23 @@ static struct ceph_options
*rbd_add_parse_args(struct rbd_device *rbd_dev,
ceph_opts = ceph_parse_options(options, mon_addrs,
mon_addrs + mon_addrs_size - 1,
parse_rbd_opts_token, &rbd_opts);
+ kfree(options);
/* Record the parsed rbd options */
- if (!IS_ERR(ceph_opts)) {
+ if (!IS_ERR(ceph_opts))
rbd_dev->mapping.read_only = rbd_opts.read_only;
- }
return ceph_opts;
+out_mem:
+ err_ptr = ERR_PTR(-ENOMEM);
out_err:
kfree(rbd_dev->image_name);
rbd_dev->image_name = NULL;
rbd_dev->image_name_len = 0;
kfree(rbd_dev->pool_name);
rbd_dev->pool_name = NULL;
+ kfree(options);
return err_ptr;
}
@@ -3124,7 +3131,6 @@ static ssize_t rbd_add(struct bus_type *bus,
const char *buf,
size_t count)
{
- char *options;
struct rbd_device *rbd_dev = NULL;
char *snap_name;
struct ceph_options *ceph_opts;
@@ -3134,9 +3140,6 @@ static ssize_t rbd_add(struct bus_type *bus,
if (!try_module_get(THIS_MODULE))
return -ENODEV;
- options = kmalloc(count, GFP_KERNEL);
- if (!options)
- goto err_out_mem;
rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
if (!rbd_dev)
goto err_out_mem;
@@ -3148,8 +3151,7 @@ static ssize_t rbd_add(struct bus_type *bus,
init_rwsem(&rbd_dev->header_rwsem);
/* parse add command */
- ceph_opts = rbd_add_parse_args(rbd_dev, buf, options, count,
- &snap_name);
+ ceph_opts = rbd_add_parse_args(rbd_dev, buf, &snap_name);
if (IS_ERR(ceph_opts)) {
rc = PTR_ERR(ceph_opts);
goto err_out_mem;
@@ -3233,7 +3235,6 @@ err_out_bus:
/* this will also clean up rest of rbd_dev stuff */
rbd_bus_del_dev(rbd_dev);
- kfree(options);
return rc;
err_out_disk:
@@ -3258,7 +3259,6 @@ err_out_args:
kfree(rbd_dev->pool_name);
err_out_mem:
kfree(rbd_dev);
- kfree(options);
dout("Error adding device %s\n", buf);
module_put(THIS_MODULE);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 2/8] rbd: remove options args from rbd_add_parse_args()
2012-10-26 23:00 ` [PATCH 2/8] rbd: remove options args from rbd_add_parse_args() Alex Elder
@ 2012-10-29 21:17 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 21:17 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
On 10/26/2012 04:00 PM, Alex Elder wrote:
> They "options" argument to rbd_add_parse_args() (and it's partner
> options_size) is now only needed within the function, so there's no
> need to have the caller allocate and pass the options buffer. Just
> allocate the options buffer within the function using dup_token().
>
> Also distinguish between failures due to failed memory allocation
> and failing because a required argument was missing.
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 58
> +++++++++++++++++++++++++--------------------------
> 1 file changed, 29 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index cae7423..f900f3b 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -2844,54 +2844,58 @@ static inline char *dup_token(const char **buf,
> size_t *lenp)
> */
> static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
> const char *buf,
> - char *options,
> - size_t options_size,
> char **snap_name)
> {
> size_t len;
> const char *mon_addrs;
> size_t mon_addrs_size;
> + char *options;
> + struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
> struct rbd_options rbd_opts;
> struct ceph_options *ceph_opts;
> - struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
>
> /* The first four tokens are required */
>
> len = next_token(&buf);
> if (!len)
> - return err_ptr;
> - mon_addrs_size = len + 1;
> + return err_ptr; /* Missing monitor address(es) */
> mon_addrs = buf;
> -
> + mon_addrs_size = len + 1;
> buf += len;
>
> - len = copy_token(&buf, options, options_size);
> - if (!len || len >= options_size)
> - return err_ptr;
> + options = dup_token(&buf, NULL);
> + if (!options)
> + goto out_mem;
> + if (!*options)
> + goto out_err; /* Missing options */
>
> - err_ptr = ERR_PTR(-ENOMEM);
> rbd_dev->pool_name = dup_token(&buf, NULL);
> if (!rbd_dev->pool_name)
> - goto out_err;
> + goto out_mem;
> + if (!*rbd_dev->pool_name)
> + goto out_err; /* Missing pool name */
>
> rbd_dev->image_name = dup_token(&buf, &rbd_dev->image_name_len);
> if (!rbd_dev->image_name)
> - goto out_err;
> -
> - /* Snapshot name is optional; default is to use "head" */
> + goto out_mem;
> + if (!*rbd_dev->image_name)
> + goto out_err; /* Missing image name */
>
> + /*
> + * Snapshot name is optional; default is to use "-"
> + * (indicating the head/no snapshot).
> + */
> len = next_token(&buf);
> - if (len > RBD_MAX_SNAP_NAME_LEN) {
> - err_ptr = ERR_PTR(-ENAMETOOLONG);
> - goto out_err;
> - }
> if (!len) {
> buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
> len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
> + } else if (len > RBD_MAX_SNAP_NAME_LEN) {
> + err_ptr = ERR_PTR(-ENAMETOOLONG);
> + goto out_err;
> }
> *snap_name = kmalloc(len + 1, GFP_KERNEL);
> if (!*snap_name)
> - goto out_err;
> + goto out_mem;
> memcpy(*snap_name, buf, len);
> *(*snap_name + len) = '\0';
>
> @@ -2902,20 +2906,23 @@ static struct ceph_options
> *rbd_add_parse_args(struct rbd_device *rbd_dev,
> ceph_opts = ceph_parse_options(options, mon_addrs,
> mon_addrs + mon_addrs_size - 1,
> parse_rbd_opts_token, &rbd_opts);
> + kfree(options);
>
> /* Record the parsed rbd options */
>
> - if (!IS_ERR(ceph_opts)) {
> + if (!IS_ERR(ceph_opts))
> rbd_dev->mapping.read_only = rbd_opts.read_only;
> - }
>
> return ceph_opts;
> +out_mem:
> + err_ptr = ERR_PTR(-ENOMEM);
> out_err:
> kfree(rbd_dev->image_name);
> rbd_dev->image_name = NULL;
> rbd_dev->image_name_len = 0;
> kfree(rbd_dev->pool_name);
> rbd_dev->pool_name = NULL;
> + kfree(options);
>
> return err_ptr;
> }
> @@ -3124,7 +3131,6 @@ static ssize_t rbd_add(struct bus_type *bus,
> const char *buf,
> size_t count)
> {
> - char *options;
> struct rbd_device *rbd_dev = NULL;
> char *snap_name;
> struct ceph_options *ceph_opts;
> @@ -3134,9 +3140,6 @@ static ssize_t rbd_add(struct bus_type *bus,
> if (!try_module_get(THIS_MODULE))
> return -ENODEV;
>
> - options = kmalloc(count, GFP_KERNEL);
> - if (!options)
> - goto err_out_mem;
> rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
> if (!rbd_dev)
> goto err_out_mem;
> @@ -3148,8 +3151,7 @@ static ssize_t rbd_add(struct bus_type *bus,
> init_rwsem(&rbd_dev->header_rwsem);
>
> /* parse add command */
> - ceph_opts = rbd_add_parse_args(rbd_dev, buf, options, count,
> - &snap_name);
> + ceph_opts = rbd_add_parse_args(rbd_dev, buf, &snap_name);
> if (IS_ERR(ceph_opts)) {
> rc = PTR_ERR(ceph_opts);
> goto err_out_mem;
> @@ -3233,7 +3235,6 @@ err_out_bus:
> /* this will also clean up rest of rbd_dev stuff */
>
> rbd_bus_del_dev(rbd_dev);
> - kfree(options);
> return rc;
>
> err_out_disk:
> @@ -3258,7 +3259,6 @@ err_out_args:
> kfree(rbd_dev->pool_name);
> err_out_mem:
> kfree(rbd_dev);
> - kfree(options);
>
> dout("Error adding device %s\n", buf);
> module_put(THIS_MODULE);
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 3/8] rbd: remove snap_name arg from rbd_add_parse_args()
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
2012-10-26 23:00 ` [PATCH 1/8] rbd: get rid of snap_name_len Alex Elder
2012-10-26 23:00 ` [PATCH 2/8] rbd: remove options args from rbd_add_parse_args() Alex Elder
@ 2012-10-26 23:01 ` Alex Elder
2012-10-29 21:26 ` Josh Durgin
2012-10-26 23:02 ` [PATCH 4/8] rbd: pass and populate rbd_options structure Alex Elder
` (4 subsequent siblings)
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:01 UTC (permalink / raw)
To: ceph-devel
The snapshot name returned by rbd_add_parse_args() just gets saved
in the rbd_dev eventually. So just do that inside that function and
do away with the snap_name argument, both in rbd_add_parse_args()
and rbd_dev_set_mapping().
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index f900f3b..948a084 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -665,23 +665,22 @@ static int snap_by_name(struct rbd_device
*rbd_dev, const char *snap_name)
return -ENOENT;
}
-static int rbd_dev_set_mapping(struct rbd_device *rbd_dev, char *snap_name)
+static int rbd_dev_set_mapping(struct rbd_device *rbd_dev)
{
int ret;
- if (!memcmp(snap_name, RBD_SNAP_HEAD_NAME,
+ if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
sizeof (RBD_SNAP_HEAD_NAME))) {
rbd_dev->snap_id = CEPH_NOSNAP;
rbd_dev->mapping.size = rbd_dev->header.image_size;
rbd_dev->mapping.features = rbd_dev->header.features;
ret = 0;
} else {
- ret = snap_by_name(rbd_dev, snap_name);
+ ret = snap_by_name(rbd_dev, rbd_dev->snap_name);
if (ret < 0)
goto done;
rbd_dev->mapping.read_only = true;
}
- rbd_dev->snap_name = snap_name;
rbd_dev->exists = true;
done:
return ret;
@@ -2843,8 +2842,7 @@ static inline char *dup_token(const char **buf,
size_t *lenp)
* Note: rbd_dev is assumed to have been initially zero-filled.
*/
static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
- const char *buf,
- char **snap_name)
+ const char *buf)
{
size_t len;
const char *mon_addrs;
@@ -2893,11 +2891,11 @@ static struct ceph_options
*rbd_add_parse_args(struct rbd_device *rbd_dev,
err_ptr = ERR_PTR(-ENAMETOOLONG);
goto out_err;
}
- *snap_name = kmalloc(len + 1, GFP_KERNEL);
- if (!*snap_name)
+ rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL);
+ if (!rbd_dev->snap_name)
goto out_mem;
- memcpy(*snap_name, buf, len);
- *(*snap_name + len) = '\0';
+ memcpy(rbd_dev->snap_name, buf, len);
+ *(rbd_dev->snap_name + len) = '\0';
/* Initialize all rbd options to the defaults */
@@ -3132,7 +3130,6 @@ static ssize_t rbd_add(struct bus_type *bus,
size_t count)
{
struct rbd_device *rbd_dev = NULL;
- char *snap_name;
struct ceph_options *ceph_opts;
struct ceph_osd_client *osdc;
int rc = -ENOMEM;
@@ -3151,7 +3148,7 @@ static ssize_t rbd_add(struct bus_type *bus,
init_rwsem(&rbd_dev->header_rwsem);
/* parse add command */
- ceph_opts = rbd_add_parse_args(rbd_dev, buf, &snap_name);
+ ceph_opts = rbd_add_parse_args(rbd_dev, buf);
if (IS_ERR(ceph_opts)) {
rc = PTR_ERR(ceph_opts);
goto err_out_mem;
@@ -3178,7 +3175,7 @@ static ssize_t rbd_add(struct bus_type *bus,
if (rc)
goto err_out_probe;
- rc = rbd_dev_set_mapping(rbd_dev, snap_name);
+ rc = rbd_dev_set_mapping(rbd_dev);
if (rc)
goto err_out_snaps;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 3/8] rbd: remove snap_name arg from rbd_add_parse_args()
2012-10-26 23:01 ` [PATCH 3/8] rbd: remove snap_name arg " Alex Elder
@ 2012-10-29 21:26 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 21:26 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
On 10/26/2012 04:01 PM, Alex Elder wrote:
> The snapshot name returned by rbd_add_parse_args() just gets saved
> in the rbd_dev eventually. So just do that inside that function and
> do away with the snap_name argument, both in rbd_add_parse_args()
> and rbd_dev_set_mapping().
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 23 ++++++++++-------------
> 1 file changed, 10 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index f900f3b..948a084 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -665,23 +665,22 @@ static int snap_by_name(struct rbd_device
> *rbd_dev, const char *snap_name)
> return -ENOENT;
> }
>
> -static int rbd_dev_set_mapping(struct rbd_device *rbd_dev, char *snap_name)
> +static int rbd_dev_set_mapping(struct rbd_device *rbd_dev)
> {
> int ret;
>
> - if (!memcmp(snap_name, RBD_SNAP_HEAD_NAME,
> + if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
> sizeof (RBD_SNAP_HEAD_NAME))) {
> rbd_dev->snap_id = CEPH_NOSNAP;
> rbd_dev->mapping.size = rbd_dev->header.image_size;
> rbd_dev->mapping.features = rbd_dev->header.features;
> ret = 0;
> } else {
> - ret = snap_by_name(rbd_dev, snap_name);
> + ret = snap_by_name(rbd_dev, rbd_dev->snap_name);
> if (ret < 0)
> goto done;
> rbd_dev->mapping.read_only = true;
> }
> - rbd_dev->snap_name = snap_name;
> rbd_dev->exists = true;
> done:
> return ret;
> @@ -2843,8 +2842,7 @@ static inline char *dup_token(const char **buf,
> size_t *lenp)
> * Note: rbd_dev is assumed to have been initially zero-filled.
> */
> static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
> - const char *buf,
> - char **snap_name)
> + const char *buf)
> {
> size_t len;
> const char *mon_addrs;
> @@ -2893,11 +2891,11 @@ static struct ceph_options
> *rbd_add_parse_args(struct rbd_device *rbd_dev,
> err_ptr = ERR_PTR(-ENAMETOOLONG);
> goto out_err;
> }
> - *snap_name = kmalloc(len + 1, GFP_KERNEL);
> - if (!*snap_name)
> + rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL);
> + if (!rbd_dev->snap_name)
> goto out_mem;
> - memcpy(*snap_name, buf, len);
> - *(*snap_name + len) = '\0';
> + memcpy(rbd_dev->snap_name, buf, len);
> + *(rbd_dev->snap_name + len) = '\0';
>
> /* Initialize all rbd options to the defaults */
>
> @@ -3132,7 +3130,6 @@ static ssize_t rbd_add(struct bus_type *bus,
> size_t count)
> {
> struct rbd_device *rbd_dev = NULL;
> - char *snap_name;
> struct ceph_options *ceph_opts;
> struct ceph_osd_client *osdc;
> int rc = -ENOMEM;
> @@ -3151,7 +3148,7 @@ static ssize_t rbd_add(struct bus_type *bus,
> init_rwsem(&rbd_dev->header_rwsem);
>
> /* parse add command */
> - ceph_opts = rbd_add_parse_args(rbd_dev, buf, &snap_name);
> + ceph_opts = rbd_add_parse_args(rbd_dev, buf);
> if (IS_ERR(ceph_opts)) {
> rc = PTR_ERR(ceph_opts);
> goto err_out_mem;
> @@ -3178,7 +3175,7 @@ static ssize_t rbd_add(struct bus_type *bus,
> if (rc)
> goto err_out_probe;
>
> - rc = rbd_dev_set_mapping(rbd_dev, snap_name);
> + rc = rbd_dev_set_mapping(rbd_dev);
> if (rc)
> goto err_out_snaps;
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 4/8] rbd: pass and populate rbd_options structure
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
` (2 preceding siblings ...)
2012-10-26 23:01 ` [PATCH 3/8] rbd: remove snap_name arg " Alex Elder
@ 2012-10-26 23:02 ` Alex Elder
2012-10-29 21:27 ` Josh Durgin
2012-10-26 23:02 ` [PATCH 5/8] rbd: have rbd_add_parse_args() return error Alex Elder
` (3 subsequent siblings)
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:02 UTC (permalink / raw)
To: ceph-devel
Have the caller pass the address of an rbd_options structure to
rbd_add_parse_args(), to be initialized with the information
gleaned as a result of the parse.
I know, this is another near-reversal of a recent change...
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 948a084..392dded 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2842,15 +2842,16 @@ static inline char *dup_token(const char **buf,
size_t *lenp)
* Note: rbd_dev is assumed to have been initially zero-filled.
*/
static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
- const char *buf)
+ const char *buf,
+ struct rbd_options **opts)
{
size_t len;
const char *mon_addrs;
size_t mon_addrs_size;
char *options;
struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
- struct rbd_options rbd_opts;
struct ceph_options *ceph_opts;
+ struct rbd_options *rbd_opts = NULL;
/* The first four tokens are required */
@@ -2899,17 +2900,17 @@ static struct ceph_options
*rbd_add_parse_args(struct rbd_device *rbd_dev,
/* Initialize all rbd options to the defaults */
- rbd_opts.read_only = RBD_READ_ONLY_DEFAULT;
+ rbd_opts = kzalloc(sizeof (*rbd_opts), GFP_KERNEL);
+ if (!rbd_opts)
+ goto out_mem;
+
+ rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
ceph_opts = ceph_parse_options(options, mon_addrs,
mon_addrs + mon_addrs_size - 1,
- parse_rbd_opts_token, &rbd_opts);
+ parse_rbd_opts_token, rbd_opts);
kfree(options);
-
- /* Record the parsed rbd options */
-
- if (!IS_ERR(ceph_opts))
- rbd_dev->mapping.read_only = rbd_opts.read_only;
+ *opts = rbd_opts;
return ceph_opts;
out_mem:
@@ -3131,6 +3132,7 @@ static ssize_t rbd_add(struct bus_type *bus,
{
struct rbd_device *rbd_dev = NULL;
struct ceph_options *ceph_opts;
+ struct rbd_options *rbd_opts = NULL;
struct ceph_osd_client *osdc;
int rc = -ENOMEM;
@@ -3139,7 +3141,7 @@ static ssize_t rbd_add(struct bus_type *bus,
rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
if (!rbd_dev)
- goto err_out_mem;
+ return -ENOMEM;
/* static rbd_device initialization */
spin_lock_init(&rbd_dev->lock);
@@ -3148,11 +3150,12 @@ static ssize_t rbd_add(struct bus_type *bus,
init_rwsem(&rbd_dev->header_rwsem);
/* parse add command */
- ceph_opts = rbd_add_parse_args(rbd_dev, buf);
+ ceph_opts = rbd_add_parse_args(rbd_dev, buf, &rbd_opts);
if (IS_ERR(ceph_opts)) {
rc = PTR_ERR(ceph_opts);
goto err_out_mem;
}
+ rbd_dev->mapping.read_only = rbd_opts->read_only;
rc = rbd_get_client(rbd_dev, ceph_opts);
if (rc < 0)
@@ -3219,6 +3222,8 @@ static ssize_t rbd_add(struct bus_type *bus,
if (rc)
goto err_out_bus;
+ kfree(rbd_opts);
+
/* Everything's ready. Announce the disk to the world. */
add_disk(rbd_dev->disk);
@@ -3232,6 +3237,8 @@ err_out_bus:
/* this will also clean up rest of rbd_dev stuff */
rbd_bus_del_dev(rbd_dev);
+ kfree(rbd_opts);
+
return rc;
err_out_disk:
@@ -3254,6 +3261,7 @@ err_out_args:
kfree(rbd_dev->snap_name);
kfree(rbd_dev->image_name);
kfree(rbd_dev->pool_name);
+ kfree(rbd_opts);
err_out_mem:
kfree(rbd_dev);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 4/8] rbd: pass and populate rbd_options structure
2012-10-26 23:02 ` [PATCH 4/8] rbd: pass and populate rbd_options structure Alex Elder
@ 2012-10-29 21:27 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 21:27 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
On 10/26/2012 04:02 PM, Alex Elder wrote:
> Have the caller pass the address of an rbd_options structure to
> rbd_add_parse_args(), to be initialized with the information
> gleaned as a result of the parse.
>
> I know, this is another near-reversal of a recent change...
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 30 +++++++++++++++++++-----------
> 1 file changed, 19 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 948a084..392dded 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -2842,15 +2842,16 @@ static inline char *dup_token(const char **buf,
> size_t *lenp)
> * Note: rbd_dev is assumed to have been initially zero-filled.
> */
> static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
> - const char *buf)
> + const char *buf,
> + struct rbd_options **opts)
> {
> size_t len;
> const char *mon_addrs;
> size_t mon_addrs_size;
> char *options;
> struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
> - struct rbd_options rbd_opts;
> struct ceph_options *ceph_opts;
> + struct rbd_options *rbd_opts = NULL;
>
> /* The first four tokens are required */
>
> @@ -2899,17 +2900,17 @@ static struct ceph_options
> *rbd_add_parse_args(struct rbd_device *rbd_dev,
>
> /* Initialize all rbd options to the defaults */
>
> - rbd_opts.read_only = RBD_READ_ONLY_DEFAULT;
> + rbd_opts = kzalloc(sizeof (*rbd_opts), GFP_KERNEL);
> + if (!rbd_opts)
> + goto out_mem;
> +
> + rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
>
> ceph_opts = ceph_parse_options(options, mon_addrs,
> mon_addrs + mon_addrs_size - 1,
> - parse_rbd_opts_token, &rbd_opts);
> + parse_rbd_opts_token, rbd_opts);
> kfree(options);
> -
> - /* Record the parsed rbd options */
> -
> - if (!IS_ERR(ceph_opts))
> - rbd_dev->mapping.read_only = rbd_opts.read_only;
> + *opts = rbd_opts;
>
> return ceph_opts;
> out_mem:
> @@ -3131,6 +3132,7 @@ static ssize_t rbd_add(struct bus_type *bus,
> {
> struct rbd_device *rbd_dev = NULL;
> struct ceph_options *ceph_opts;
> + struct rbd_options *rbd_opts = NULL;
> struct ceph_osd_client *osdc;
> int rc = -ENOMEM;
>
> @@ -3139,7 +3141,7 @@ static ssize_t rbd_add(struct bus_type *bus,
>
> rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
> if (!rbd_dev)
> - goto err_out_mem;
> + return -ENOMEM;
>
> /* static rbd_device initialization */
> spin_lock_init(&rbd_dev->lock);
> @@ -3148,11 +3150,12 @@ static ssize_t rbd_add(struct bus_type *bus,
> init_rwsem(&rbd_dev->header_rwsem);
>
> /* parse add command */
> - ceph_opts = rbd_add_parse_args(rbd_dev, buf);
> + ceph_opts = rbd_add_parse_args(rbd_dev, buf, &rbd_opts);
> if (IS_ERR(ceph_opts)) {
> rc = PTR_ERR(ceph_opts);
> goto err_out_mem;
> }
> + rbd_dev->mapping.read_only = rbd_opts->read_only;
>
> rc = rbd_get_client(rbd_dev, ceph_opts);
> if (rc < 0)
> @@ -3219,6 +3222,8 @@ static ssize_t rbd_add(struct bus_type *bus,
> if (rc)
> goto err_out_bus;
>
> + kfree(rbd_opts);
> +
> /* Everything's ready. Announce the disk to the world. */
>
> add_disk(rbd_dev->disk);
> @@ -3232,6 +3237,8 @@ err_out_bus:
> /* this will also clean up rest of rbd_dev stuff */
>
> rbd_bus_del_dev(rbd_dev);
> + kfree(rbd_opts);
> +
> return rc;
>
> err_out_disk:
> @@ -3254,6 +3261,7 @@ err_out_args:
> kfree(rbd_dev->snap_name);
> kfree(rbd_dev->image_name);
> kfree(rbd_dev->pool_name);
> + kfree(rbd_opts);
> err_out_mem:
> kfree(rbd_dev);
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 5/8] rbd: have rbd_add_parse_args() return error
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
` (3 preceding siblings ...)
2012-10-26 23:02 ` [PATCH 4/8] rbd: pass and populate rbd_options structure Alex Elder
@ 2012-10-26 23:02 ` Alex Elder
2012-10-29 21:28 ` Josh Durgin
2012-10-26 23:03 ` [PATCH 6/8] rbd: define image specification structure Alex Elder
` (2 subsequent siblings)
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:02 UTC (permalink / raw)
To: ceph-devel
Change the interface to rbd_add_parse_args() so it returns an
error code rather than a pointer. Return the ceph_options result
via a pointer whose address is passed as an argument.
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 392dded..388dd47 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2841,30 +2841,31 @@ static inline char *dup_token(const char **buf,
size_t *lenp)
*
* Note: rbd_dev is assumed to have been initially zero-filled.
*/
-static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
- const char *buf,
- struct rbd_options **opts)
+static int rbd_add_parse_args(struct rbd_device *rbd_dev,
+ const char *buf,
+ struct ceph_options **ceph_opts,
+ struct rbd_options **opts)
{
size_t len;
const char *mon_addrs;
size_t mon_addrs_size;
char *options;
- struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
- struct ceph_options *ceph_opts;
struct rbd_options *rbd_opts = NULL;
+ int ret;
/* The first four tokens are required */
len = next_token(&buf);
if (!len)
- return err_ptr; /* Missing monitor address(es) */
+ return -EINVAL; /* Missing monitor address(es) */
mon_addrs = buf;
mon_addrs_size = len + 1;
buf += len;
+ ret = -EINVAL;
options = dup_token(&buf, NULL);
if (!options)
- goto out_mem;
+ return -ENOMEM;
if (!*options)
goto out_err; /* Missing options */
@@ -2889,7 +2890,7 @@ static struct ceph_options
*rbd_add_parse_args(struct rbd_device *rbd_dev,
buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
} else if (len > RBD_MAX_SNAP_NAME_LEN) {
- err_ptr = ERR_PTR(-ENAMETOOLONG);
+ ret = -ENAMETOOLONG;
goto out_err;
}
rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL);
@@ -2906,15 +2907,19 @@ static struct ceph_options
*rbd_add_parse_args(struct rbd_device *rbd_dev,
rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
- ceph_opts = ceph_parse_options(options, mon_addrs,
+ *ceph_opts = ceph_parse_options(options, mon_addrs,
mon_addrs + mon_addrs_size - 1,
parse_rbd_opts_token, rbd_opts);
kfree(options);
+ if (IS_ERR(*ceph_opts)) {
+ ret = PTR_ERR(*ceph_opts);
+ goto out_err;
+ }
*opts = rbd_opts;
- return ceph_opts;
+ return 0;
out_mem:
- err_ptr = ERR_PTR(-ENOMEM);
+ ret = -ENOMEM;
out_err:
kfree(rbd_dev->image_name);
rbd_dev->image_name = NULL;
@@ -2923,7 +2928,7 @@ out_err:
rbd_dev->pool_name = NULL;
kfree(options);
- return err_ptr;
+ return ret;
}
/*
@@ -3131,7 +3136,7 @@ static ssize_t rbd_add(struct bus_type *bus,
size_t count)
{
struct rbd_device *rbd_dev = NULL;
- struct ceph_options *ceph_opts;
+ struct ceph_options *ceph_opts = NULL;
struct rbd_options *rbd_opts = NULL;
struct ceph_osd_client *osdc;
int rc = -ENOMEM;
@@ -3150,11 +3155,9 @@ static ssize_t rbd_add(struct bus_type *bus,
init_rwsem(&rbd_dev->header_rwsem);
/* parse add command */
- ceph_opts = rbd_add_parse_args(rbd_dev, buf, &rbd_opts);
- if (IS_ERR(ceph_opts)) {
- rc = PTR_ERR(ceph_opts);
+ rc = rbd_add_parse_args(rbd_dev, buf, &ceph_opts, &rbd_opts);
+ if (rc < 0)
goto err_out_mem;
- }
rbd_dev->mapping.read_only = rbd_opts->read_only;
rc = rbd_get_client(rbd_dev, ceph_opts);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 5/8] rbd: have rbd_add_parse_args() return error
2012-10-26 23:02 ` [PATCH 5/8] rbd: have rbd_add_parse_args() return error Alex Elder
@ 2012-10-29 21:28 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 21:28 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
On 10/26/2012 04:02 PM, Alex Elder wrote:
> Change the interface to rbd_add_parse_args() so it returns an
> error code rather than a pointer. Return the ceph_options result
> via a pointer whose address is passed as an argument.
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 37 ++++++++++++++++++++-----------------
> 1 file changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 392dded..388dd47 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -2841,30 +2841,31 @@ static inline char *dup_token(const char **buf,
> size_t *lenp)
> *
> * Note: rbd_dev is assumed to have been initially zero-filled.
> */
> -static struct ceph_options *rbd_add_parse_args(struct rbd_device *rbd_dev,
> - const char *buf,
> - struct rbd_options **opts)
> +static int rbd_add_parse_args(struct rbd_device *rbd_dev,
> + const char *buf,
> + struct ceph_options **ceph_opts,
> + struct rbd_options **opts)
> {
> size_t len;
> const char *mon_addrs;
> size_t mon_addrs_size;
> char *options;
> - struct ceph_options *err_ptr = ERR_PTR(-EINVAL);
> - struct ceph_options *ceph_opts;
> struct rbd_options *rbd_opts = NULL;
> + int ret;
>
> /* The first four tokens are required */
>
> len = next_token(&buf);
> if (!len)
> - return err_ptr; /* Missing monitor address(es) */
> + return -EINVAL; /* Missing monitor address(es) */
> mon_addrs = buf;
> mon_addrs_size = len + 1;
> buf += len;
>
> + ret = -EINVAL;
> options = dup_token(&buf, NULL);
> if (!options)
> - goto out_mem;
> + return -ENOMEM;
> if (!*options)
> goto out_err; /* Missing options */
>
> @@ -2889,7 +2890,7 @@ static struct ceph_options
> *rbd_add_parse_args(struct rbd_device *rbd_dev,
> buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
> len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
> } else if (len > RBD_MAX_SNAP_NAME_LEN) {
> - err_ptr = ERR_PTR(-ENAMETOOLONG);
> + ret = -ENAMETOOLONG;
> goto out_err;
> }
> rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL);
> @@ -2906,15 +2907,19 @@ static struct ceph_options
> *rbd_add_parse_args(struct rbd_device *rbd_dev,
>
> rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
>
> - ceph_opts = ceph_parse_options(options, mon_addrs,
> + *ceph_opts = ceph_parse_options(options, mon_addrs,
> mon_addrs + mon_addrs_size - 1,
> parse_rbd_opts_token, rbd_opts);
> kfree(options);
> + if (IS_ERR(*ceph_opts)) {
> + ret = PTR_ERR(*ceph_opts);
> + goto out_err;
> + }
> *opts = rbd_opts;
>
> - return ceph_opts;
> + return 0;
> out_mem:
> - err_ptr = ERR_PTR(-ENOMEM);
> + ret = -ENOMEM;
> out_err:
> kfree(rbd_dev->image_name);
> rbd_dev->image_name = NULL;
> @@ -2923,7 +2928,7 @@ out_err:
> rbd_dev->pool_name = NULL;
> kfree(options);
>
> - return err_ptr;
> + return ret;
> }
>
> /*
> @@ -3131,7 +3136,7 @@ static ssize_t rbd_add(struct bus_type *bus,
> size_t count)
> {
> struct rbd_device *rbd_dev = NULL;
> - struct ceph_options *ceph_opts;
> + struct ceph_options *ceph_opts = NULL;
> struct rbd_options *rbd_opts = NULL;
> struct ceph_osd_client *osdc;
> int rc = -ENOMEM;
> @@ -3150,11 +3155,9 @@ static ssize_t rbd_add(struct bus_type *bus,
> init_rwsem(&rbd_dev->header_rwsem);
>
> /* parse add command */
> - ceph_opts = rbd_add_parse_args(rbd_dev, buf, &rbd_opts);
> - if (IS_ERR(ceph_opts)) {
> - rc = PTR_ERR(ceph_opts);
> + rc = rbd_add_parse_args(rbd_dev, buf, &ceph_opts, &rbd_opts);
> + if (rc < 0)
> goto err_out_mem;
> - }
> rbd_dev->mapping.read_only = rbd_opts->read_only;
>
> rc = rbd_get_client(rbd_dev, ceph_opts);
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 6/8] rbd: define image specification structure
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
` (4 preceding siblings ...)
2012-10-26 23:02 ` [PATCH 5/8] rbd: have rbd_add_parse_args() return error Alex Elder
@ 2012-10-26 23:03 ` Alex Elder
2012-10-29 22:13 ` Josh Durgin
2012-10-26 23:03 ` [PATCH 7/8] rbd: add reference counting to rbd_spec Alex Elder
2012-10-26 23:03 ` [PATCH 8/8] rbd: fill rbd_spec in rbd_add_parse_args() Alex Elder
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:03 UTC (permalink / raw)
To: ceph-devel
Group the fields that uniquely specify an rbd image into a new
reference-counted rbd_spec structure. This structure will be used
to describe the desired image when mapping an image, and when
probing parent images in layered rbd devices. Replace the set of
fields in the rbd device structure with a pointer to a dynamically
allocated rbd_spec.
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 158
+++++++++++++++++++++++++++++----------------------
1 file changed, 90 insertions(+), 68 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 388dd47..c39e238 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -112,6 +112,27 @@ struct rbd_image_header {
u64 obj_version;
};
+/*
+ * An rbd image specification.
+ *
+ * The tuple (pool_id, image_id, snap_id) is sufficient to uniquely
+ * identify an image.
+ */
+struct rbd_spec {
+ u64 pool_id;
+ char *pool_name;
+
+ char *image_id;
+ size_t image_id_len;
+ char *image_name;
+ size_t image_name_len;
+
+ u64 snap_id;
+ char *snap_name;
+
+ struct kref kref;
+};
+
struct rbd_options {
bool read_only;
};
@@ -189,16 +210,9 @@ struct rbd_device {
struct rbd_image_header header;
bool exists;
- char *image_id;
- size_t image_id_len;
- char *image_name;
- size_t image_name_len;
- char *header_name;
- char *pool_name;
- u64 pool_id;
+ struct rbd_spec *spec;
- char *snap_name;
- u64 snap_id;
+ char *header_name;
struct ceph_osd_event *watch_event;
struct ceph_osd_request *watch_request;
@@ -654,7 +668,7 @@ static int snap_by_name(struct rbd_device *rbd_dev,
const char *snap_name)
list_for_each_entry(snap, &rbd_dev->snaps, node) {
if (!strcmp(snap_name, snap->name)) {
- rbd_dev->snap_id = snap->id;
+ rbd_dev->spec->snap_id = snap->id;
rbd_dev->mapping.size = snap->size;
rbd_dev->mapping.features = snap->features;
@@ -669,14 +683,14 @@ static int rbd_dev_set_mapping(struct rbd_device
*rbd_dev)
{
int ret;
- if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
+ if (!memcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME,
sizeof (RBD_SNAP_HEAD_NAME))) {
- rbd_dev->snap_id = CEPH_NOSNAP;
+ rbd_dev->spec->snap_id = CEPH_NOSNAP;
rbd_dev->mapping.size = rbd_dev->header.image_size;
rbd_dev->mapping.features = rbd_dev->header.features;
ret = 0;
} else {
- ret = snap_by_name(rbd_dev, rbd_dev->snap_name);
+ ret = snap_by_name(rbd_dev, rbd_dev->spec->snap_name);
if (ret < 0)
goto done;
rbd_dev->mapping.read_only = true;
@@ -1096,7 +1110,7 @@ static int rbd_do_request(struct request *rq,
layout->fl_stripe_unit = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
layout->fl_stripe_count = cpu_to_le32(1);
layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
- layout->fl_pg_pool = cpu_to_le32((int) rbd_dev->pool_id);
+ layout->fl_pg_pool = cpu_to_le32((int) rbd_dev->spec->pool_id);
ret = ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
req, ops);
rbd_assert(ret == 0);
@@ -1261,7 +1275,7 @@ static int rbd_do_op(struct request *rq,
opcode = CEPH_OSD_OP_READ;
flags = CEPH_OSD_FLAG_READ;
snapc = NULL;
- snapid = rbd_dev->snap_id;
+ snapid = rbd_dev->spec->snap_id;
payload_len = 0;
}
@@ -1545,7 +1559,7 @@ static void rbd_rq_fn(struct request_queue *q)
down_read(&rbd_dev->header_rwsem);
if (!rbd_dev->exists) {
- rbd_assert(rbd_dev->snap_id != CEPH_NOSNAP);
+ rbd_assert(rbd_dev->spec->snap_id != CEPH_NOSNAP);
up_read(&rbd_dev->header_rwsem);
dout("request for non-existent snapshot");
spin_lock_irq(q->queue_lock);
@@ -1726,13 +1740,13 @@ rbd_dev_v1_header_read(struct rbd_device
*rbd_dev, u64 *version)
ret = -ENXIO;
pr_warning("short header read for image %s"
" (want %zd got %d)\n",
- rbd_dev->image_name, size, ret);
+ rbd_dev->spec->image_name, size, ret);
goto out_err;
}
if (!rbd_dev_ondisk_valid(ondisk)) {
ret = -ENXIO;
pr_warning("invalid header for image %s\n",
- rbd_dev->image_name);
+ rbd_dev->spec->image_name);
goto out_err;
}
@@ -1783,7 +1797,7 @@ static void rbd_update_mapping_size(struct
rbd_device *rbd_dev)
{
sector_t size;
- if (rbd_dev->snap_id != CEPH_NOSNAP)
+ if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
return;
size = (sector_t) rbd_dev->header.image_size / SECTOR_SIZE;
@@ -1957,7 +1971,7 @@ static ssize_t rbd_pool_show(struct device *dev,
{
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
- return sprintf(buf, "%s\n", rbd_dev->pool_name);
+ return sprintf(buf, "%s\n", rbd_dev->spec->pool_name);
}
static ssize_t rbd_pool_id_show(struct device *dev,
@@ -1965,7 +1979,8 @@ static ssize_t rbd_pool_id_show(struct device *dev,
{
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
- return sprintf(buf, "%llu\n", (unsigned long long) rbd_dev->pool_id);
+ return sprintf(buf, "%llu\n",
+ (unsigned long long) rbd_dev->spec->pool_id);
}
static ssize_t rbd_name_show(struct device *dev,
@@ -1973,7 +1988,7 @@ static ssize_t rbd_name_show(struct device *dev,
{
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
- return sprintf(buf, "%s\n", rbd_dev->image_name);
+ return sprintf(buf, "%s\n", rbd_dev->spec->image_name);
}
static ssize_t rbd_image_id_show(struct device *dev,
@@ -1981,7 +1996,7 @@ static ssize_t rbd_image_id_show(struct device *dev,
{
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
- return sprintf(buf, "%s\n", rbd_dev->image_id);
+ return sprintf(buf, "%s\n", rbd_dev->spec->image_id);
}
/*
@@ -1994,7 +2009,7 @@ static ssize_t rbd_snap_show(struct device *dev,
{
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
- return sprintf(buf, "%s\n", rbd_dev->snap_name);
+ return sprintf(buf, "%s\n", rbd_dev->spec->snap_name);
}
static ssize_t rbd_image_refresh(struct device *dev,
@@ -2547,11 +2562,12 @@ static int rbd_dev_snaps_update(struct
rbd_device *rbd_dev)
/* Existing snapshot not in the new snap context */
- if (rbd_dev->snap_id == snap->id)
+ if (rbd_dev->spec->snap_id == snap->id)
rbd_dev->exists = false;
__rbd_remove_snap_dev(snap);
dout("%ssnap id %llu has been removed\n",
- rbd_dev->snap_id == snap->id ? "mapped " : "",
+ rbd_dev->spec->snap_id == snap->id ?
+ "mapped " : "",
(unsigned long long) snap->id);
/* Done with this list entry; advance */
@@ -2869,16 +2885,17 @@ static int rbd_add_parse_args(struct rbd_device
*rbd_dev,
if (!*options)
goto out_err; /* Missing options */
- rbd_dev->pool_name = dup_token(&buf, NULL);
- if (!rbd_dev->pool_name)
+ rbd_dev->spec->pool_name = dup_token(&buf, NULL);
+ if (!rbd_dev->spec->pool_name)
goto out_mem;
- if (!*rbd_dev->pool_name)
+ if (!*rbd_dev->spec->pool_name)
goto out_err; /* Missing pool name */
- rbd_dev->image_name = dup_token(&buf, &rbd_dev->image_name_len);
- if (!rbd_dev->image_name)
+ rbd_dev->spec->image_name =
+ dup_token(&buf, &rbd_dev->spec->image_name_len);
+ if (!rbd_dev->spec->image_name)
goto out_mem;
- if (!*rbd_dev->image_name)
+ if (!*rbd_dev->spec->image_name)
goto out_err; /* Missing image name */
/*
@@ -2893,11 +2910,11 @@ static int rbd_add_parse_args(struct rbd_device
*rbd_dev,
ret = -ENAMETOOLONG;
goto out_err;
}
- rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL);
- if (!rbd_dev->snap_name)
+ rbd_dev->spec->snap_name = kmalloc(len + 1, GFP_KERNEL);
+ if (!rbd_dev->spec->snap_name)
goto out_mem;
- memcpy(rbd_dev->snap_name, buf, len);
- *(rbd_dev->snap_name + len) = '\0';
+ memcpy(rbd_dev->spec->snap_name, buf, len);
+ *(rbd_dev->spec->snap_name + len) = '\0';
/* Initialize all rbd options to the defaults */
@@ -2921,11 +2938,11 @@ static int rbd_add_parse_args(struct rbd_device
*rbd_dev,
out_mem:
ret = -ENOMEM;
out_err:
- kfree(rbd_dev->image_name);
- rbd_dev->image_name = NULL;
- rbd_dev->image_name_len = 0;
- kfree(rbd_dev->pool_name);
- rbd_dev->pool_name = NULL;
+ kfree(rbd_dev->spec->image_name);
+ rbd_dev->spec->image_name = NULL;
+ rbd_dev->spec->image_name_len = 0;
+ kfree(rbd_dev->spec->pool_name);
+ rbd_dev->spec->pool_name = NULL;
kfree(options);
return ret;
@@ -2957,11 +2974,11 @@ static int rbd_dev_image_id(struct rbd_device
*rbd_dev)
* First, see if the format 2 image id file exists, and if
* so, get the image's persistent id from it.
*/
- size = sizeof (RBD_ID_PREFIX) + rbd_dev->image_name_len;
+ size = sizeof (RBD_ID_PREFIX) + rbd_dev->spec->image_name_len;
object_name = kmalloc(size, GFP_NOIO);
if (!object_name)
return -ENOMEM;
- sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->image_name);
+ sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->spec->image_name);
dout("rbd id object name is %s\n", object_name);
/* Response will be an encoded string, which includes a length */
@@ -2984,15 +3001,15 @@ static int rbd_dev_image_id(struct rbd_device
*rbd_dev)
ret = 0; /* rbd_req_sync_exec() can return positive */
p = response;
- rbd_dev->image_id = ceph_extract_encoded_string(&p,
+ rbd_dev->spec->image_id = ceph_extract_encoded_string(&p,
p + RBD_IMAGE_ID_LEN_MAX,
- &rbd_dev->image_id_len,
+ &rbd_dev->spec->image_id_len,
GFP_NOIO);
- if (IS_ERR(rbd_dev->image_id)) {
- ret = PTR_ERR(rbd_dev->image_id);
- rbd_dev->image_id = NULL;
+ if (IS_ERR(rbd_dev->spec->image_id)) {
+ ret = PTR_ERR(rbd_dev->spec->image_id);
+ rbd_dev->spec->image_id = NULL;
} else {
- dout("image_id is %s\n", rbd_dev->image_id);
+ dout("image_id is %s\n", rbd_dev->spec->image_id);
}
out:
kfree(response);
@@ -3008,20 +3025,21 @@ static int rbd_dev_v1_probe(struct rbd_device
*rbd_dev)
/* Version 1 images have no id; empty string is used */
- rbd_dev->image_id = kstrdup("", GFP_KERNEL);
- if (!rbd_dev->image_id)
+ rbd_dev->spec->image_id = kstrdup("", GFP_KERNEL);
+ if (!rbd_dev->spec->image_id)
return -ENOMEM;
- rbd_dev->image_id_len = 0;
+ rbd_dev->spec->image_id_len = 0;
/* Record the header object name for this rbd image. */
- size = rbd_dev->image_name_len + sizeof (RBD_SUFFIX);
+ size = rbd_dev->spec->image_name_len + sizeof (RBD_SUFFIX);
rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
if (!rbd_dev->header_name) {
ret = -ENOMEM;
goto out_err;
}
- sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);
+ sprintf(rbd_dev->header_name, "%s%s",
+ rbd_dev->spec->image_name, RBD_SUFFIX);
/* Populate rbd image metadata */
@@ -3038,8 +3056,8 @@ static int rbd_dev_v1_probe(struct rbd_device
*rbd_dev)
out_err:
kfree(rbd_dev->header_name);
rbd_dev->header_name = NULL;
- kfree(rbd_dev->image_id);
- rbd_dev->image_id = NULL;
+ kfree(rbd_dev->spec->image_id);
+ rbd_dev->spec->image_id = NULL;
return ret;
}
@@ -3054,12 +3072,12 @@ static int rbd_dev_v2_probe(struct rbd_device
*rbd_dev)
* Image id was filled in by the caller. Record the header
* object name for this rbd image.
*/
- size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->image_id_len;
+ size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->spec->image_id_len;
rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
if (!rbd_dev->header_name)
return -ENOMEM;
sprintf(rbd_dev->header_name, "%s%s",
- RBD_HEADER_PREFIX, rbd_dev->image_id);
+ RBD_HEADER_PREFIX, rbd_dev->spec->image_id);
/* Get the size and object order for the image */
@@ -3147,6 +3165,9 @@ static ssize_t rbd_add(struct bus_type *bus,
rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
if (!rbd_dev)
return -ENOMEM;
+ rbd_dev->spec = kzalloc(sizeof (*rbd_dev->spec), GFP_KERNEL);
+ if (!rbd_dev->spec)
+ goto err_out_mem;
/* static rbd_device initialization */
spin_lock_init(&rbd_dev->lock);
@@ -3167,10 +3188,10 @@ static ssize_t rbd_add(struct bus_type *bus,
/* pick the pool */
osdc = &rbd_dev->rbd_client->client->osdc;
- rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->pool_name);
+ rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->spec->pool_name);
if (rc < 0)
goto err_out_client;
- rbd_dev->pool_id = (u64) rc;
+ rbd_dev->spec->pool_id = (u64) rc;
rc = rbd_dev_probe(rbd_dev);
if (rc < 0)
@@ -3257,15 +3278,16 @@ err_out_probe:
err_out_client:
kfree(rbd_dev->header_name);
rbd_put_client(rbd_dev);
- kfree(rbd_dev->image_id);
+ kfree(rbd_dev->spec->image_id);
err_out_args:
if (ceph_opts)
ceph_destroy_options(ceph_opts);
- kfree(rbd_dev->snap_name);
- kfree(rbd_dev->image_name);
- kfree(rbd_dev->pool_name);
+ kfree(rbd_dev->spec->snap_name);
+ kfree(rbd_dev->spec->image_name);
+ kfree(rbd_dev->spec->pool_name);
kfree(rbd_opts);
err_out_mem:
+ kfree(rbd_dev->spec);
kfree(rbd_dev);
dout("Error adding device %s\n", buf);
@@ -3314,11 +3336,11 @@ static void rbd_dev_release(struct device *dev)
rbd_header_free(&rbd_dev->header);
/* done with the id, and with the rbd_dev */
- kfree(rbd_dev->snap_name);
- kfree(rbd_dev->image_id);
+ kfree(rbd_dev->spec->snap_name);
+ kfree(rbd_dev->spec->image_id);
kfree(rbd_dev->header_name);
- kfree(rbd_dev->pool_name);
- kfree(rbd_dev->image_name);
+ kfree(rbd_dev->spec->pool_name);
+ kfree(rbd_dev->spec->image_name);
rbd_dev_id_put(rbd_dev);
kfree(rbd_dev);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 6/8] rbd: define image specification structure
2012-10-26 23:03 ` [PATCH 6/8] rbd: define image specification structure Alex Elder
@ 2012-10-29 22:13 ` Josh Durgin
2012-10-30 12:40 ` Alex Elder
0 siblings, 1 reply; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 22:13 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
A couple notes below, but looks good.
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
On 10/26/2012 04:03 PM, Alex Elder wrote:
> Group the fields that uniquely specify an rbd image into a new
> reference-counted rbd_spec structure. This structure will be used
> to describe the desired image when mapping an image, and when
> probing parent images in layered rbd devices. Replace the set of
> fields in the rbd device structure with a pointer to a dynamically
> allocated rbd_spec.
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 158
> +++++++++++++++++++++++++++++----------------------
> 1 file changed, 90 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 388dd47..c39e238 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -112,6 +112,27 @@ struct rbd_image_header {
> u64 obj_version;
> };
>
> +/*
> + * An rbd image specification.
> + *
> + * The tuple (pool_id, image_id, snap_id) is sufficient to uniquely
> + * identify an image.
> + */
This looks like it's meant to be immutable. If so, it'd be nice
to have that in the comment.
> +struct rbd_spec {
> + u64 pool_id;
> + char *pool_name;
> +
> + char *image_id;
> + size_t image_id_len;
> + char *image_name;
> + size_t image_name_len;
I realize you're just rearranging things in this patch, but it's a bit
odd that only image_id and image_name have corresponding lengths stored.
Those fields don't seem necessary.
> +
> + u64 snap_id;
> + char *snap_name;
> +
> + struct kref kref;
> +};
> +
> struct rbd_options {
> bool read_only;
> };
> @@ -189,16 +210,9 @@ struct rbd_device {
>
> struct rbd_image_header header;
> bool exists;
> - char *image_id;
> - size_t image_id_len;
> - char *image_name;
> - size_t image_name_len;
> - char *header_name;
> - char *pool_name;
> - u64 pool_id;
> + struct rbd_spec *spec;
>
> - char *snap_name;
> - u64 snap_id;
> + char *header_name;
Are you planning to split out more stuff into a common
struct rbd_image, like header_name, exists, etc?
There's a bunch of stuff that's not specific to a particular rbd_device
in here.
>
> struct ceph_osd_event *watch_event;
> struct ceph_osd_request *watch_request;
> @@ -654,7 +668,7 @@ static int snap_by_name(struct rbd_device *rbd_dev,
> const char *snap_name)
>
> list_for_each_entry(snap, &rbd_dev->snaps, node) {
> if (!strcmp(snap_name, snap->name)) {
> - rbd_dev->snap_id = snap->id;
> + rbd_dev->spec->snap_id = snap->id;
> rbd_dev->mapping.size = snap->size;
> rbd_dev->mapping.features = snap->features;
>
> @@ -669,14 +683,14 @@ static int rbd_dev_set_mapping(struct rbd_device
> *rbd_dev)
> {
> int ret;
>
> - if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
> + if (!memcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME,
> sizeof (RBD_SNAP_HEAD_NAME))) {
> - rbd_dev->snap_id = CEPH_NOSNAP;
> + rbd_dev->spec->snap_id = CEPH_NOSNAP;
> rbd_dev->mapping.size = rbd_dev->header.image_size;
> rbd_dev->mapping.features = rbd_dev->header.features;
> ret = 0;
> } else {
> - ret = snap_by_name(rbd_dev, rbd_dev->snap_name);
> + ret = snap_by_name(rbd_dev, rbd_dev->spec->snap_name);
> if (ret < 0)
> goto done;
> rbd_dev->mapping.read_only = true;
> @@ -1096,7 +1110,7 @@ static int rbd_do_request(struct request *rq,
> layout->fl_stripe_unit = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
> layout->fl_stripe_count = cpu_to_le32(1);
> layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
> - layout->fl_pg_pool = cpu_to_le32((int) rbd_dev->pool_id);
> + layout->fl_pg_pool = cpu_to_le32((int) rbd_dev->spec->pool_id);
> ret = ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
> req, ops);
> rbd_assert(ret == 0);
> @@ -1261,7 +1275,7 @@ static int rbd_do_op(struct request *rq,
> opcode = CEPH_OSD_OP_READ;
> flags = CEPH_OSD_FLAG_READ;
> snapc = NULL;
> - snapid = rbd_dev->snap_id;
> + snapid = rbd_dev->spec->snap_id;
> payload_len = 0;
> }
>
> @@ -1545,7 +1559,7 @@ static void rbd_rq_fn(struct request_queue *q)
> down_read(&rbd_dev->header_rwsem);
>
> if (!rbd_dev->exists) {
> - rbd_assert(rbd_dev->snap_id != CEPH_NOSNAP);
> + rbd_assert(rbd_dev->spec->snap_id != CEPH_NOSNAP);
> up_read(&rbd_dev->header_rwsem);
> dout("request for non-existent snapshot");
> spin_lock_irq(q->queue_lock);
> @@ -1726,13 +1740,13 @@ rbd_dev_v1_header_read(struct rbd_device
> *rbd_dev, u64 *version)
> ret = -ENXIO;
> pr_warning("short header read for image %s"
> " (want %zd got %d)\n",
> - rbd_dev->image_name, size, ret);
> + rbd_dev->spec->image_name, size, ret);
> goto out_err;
> }
> if (!rbd_dev_ondisk_valid(ondisk)) {
> ret = -ENXIO;
> pr_warning("invalid header for image %s\n",
> - rbd_dev->image_name);
> + rbd_dev->spec->image_name);
> goto out_err;
> }
>
> @@ -1783,7 +1797,7 @@ static void rbd_update_mapping_size(struct
> rbd_device *rbd_dev)
> {
> sector_t size;
>
> - if (rbd_dev->snap_id != CEPH_NOSNAP)
> + if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
> return;
>
> size = (sector_t) rbd_dev->header.image_size / SECTOR_SIZE;
> @@ -1957,7 +1971,7 @@ static ssize_t rbd_pool_show(struct device *dev,
> {
> struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
>
> - return sprintf(buf, "%s\n", rbd_dev->pool_name);
> + return sprintf(buf, "%s\n", rbd_dev->spec->pool_name);
> }
>
> static ssize_t rbd_pool_id_show(struct device *dev,
> @@ -1965,7 +1979,8 @@ static ssize_t rbd_pool_id_show(struct device *dev,
> {
> struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
>
> - return sprintf(buf, "%llu\n", (unsigned long long) rbd_dev->pool_id);
> + return sprintf(buf, "%llu\n",
> + (unsigned long long) rbd_dev->spec->pool_id);
> }
>
> static ssize_t rbd_name_show(struct device *dev,
> @@ -1973,7 +1988,7 @@ static ssize_t rbd_name_show(struct device *dev,
> {
> struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
>
> - return sprintf(buf, "%s\n", rbd_dev->image_name);
> + return sprintf(buf, "%s\n", rbd_dev->spec->image_name);
> }
>
> static ssize_t rbd_image_id_show(struct device *dev,
> @@ -1981,7 +1996,7 @@ static ssize_t rbd_image_id_show(struct device *dev,
> {
> struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
>
> - return sprintf(buf, "%s\n", rbd_dev->image_id);
> + return sprintf(buf, "%s\n", rbd_dev->spec->image_id);
> }
>
> /*
> @@ -1994,7 +2009,7 @@ static ssize_t rbd_snap_show(struct device *dev,
> {
> struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
>
> - return sprintf(buf, "%s\n", rbd_dev->snap_name);
> + return sprintf(buf, "%s\n", rbd_dev->spec->snap_name);
> }
>
> static ssize_t rbd_image_refresh(struct device *dev,
> @@ -2547,11 +2562,12 @@ static int rbd_dev_snaps_update(struct
> rbd_device *rbd_dev)
>
> /* Existing snapshot not in the new snap context */
>
> - if (rbd_dev->snap_id == snap->id)
> + if (rbd_dev->spec->snap_id == snap->id)
> rbd_dev->exists = false;
> __rbd_remove_snap_dev(snap);
> dout("%ssnap id %llu has been removed\n",
> - rbd_dev->snap_id == snap->id ? "mapped " : "",
> + rbd_dev->spec->snap_id == snap->id ?
> + "mapped " : "",
> (unsigned long long) snap->id);
>
> /* Done with this list entry; advance */
> @@ -2869,16 +2885,17 @@ static int rbd_add_parse_args(struct rbd_device
> *rbd_dev,
> if (!*options)
> goto out_err; /* Missing options */
>
> - rbd_dev->pool_name = dup_token(&buf, NULL);
> - if (!rbd_dev->pool_name)
> + rbd_dev->spec->pool_name = dup_token(&buf, NULL);
> + if (!rbd_dev->spec->pool_name)
> goto out_mem;
> - if (!*rbd_dev->pool_name)
> + if (!*rbd_dev->spec->pool_name)
> goto out_err; /* Missing pool name */
>
> - rbd_dev->image_name = dup_token(&buf, &rbd_dev->image_name_len);
> - if (!rbd_dev->image_name)
> + rbd_dev->spec->image_name =
> + dup_token(&buf, &rbd_dev->spec->image_name_len);
> + if (!rbd_dev->spec->image_name)
> goto out_mem;
> - if (!*rbd_dev->image_name)
> + if (!*rbd_dev->spec->image_name)
> goto out_err; /* Missing image name */
>
> /*
> @@ -2893,11 +2910,11 @@ static int rbd_add_parse_args(struct rbd_device
> *rbd_dev,
> ret = -ENAMETOOLONG;
> goto out_err;
> }
> - rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL);
> - if (!rbd_dev->snap_name)
> + rbd_dev->spec->snap_name = kmalloc(len + 1, GFP_KERNEL);
> + if (!rbd_dev->spec->snap_name)
> goto out_mem;
> - memcpy(rbd_dev->snap_name, buf, len);
> - *(rbd_dev->snap_name + len) = '\0';
> + memcpy(rbd_dev->spec->snap_name, buf, len);
> + *(rbd_dev->spec->snap_name + len) = '\0';
>
> /* Initialize all rbd options to the defaults */
>
> @@ -2921,11 +2938,11 @@ static int rbd_add_parse_args(struct rbd_device
> *rbd_dev,
> out_mem:
> ret = -ENOMEM;
> out_err:
> - kfree(rbd_dev->image_name);
> - rbd_dev->image_name = NULL;
> - rbd_dev->image_name_len = 0;
> - kfree(rbd_dev->pool_name);
> - rbd_dev->pool_name = NULL;
> + kfree(rbd_dev->spec->image_name);
> + rbd_dev->spec->image_name = NULL;
> + rbd_dev->spec->image_name_len = 0;
> + kfree(rbd_dev->spec->pool_name);
> + rbd_dev->spec->pool_name = NULL;
> kfree(options);
>
> return ret;
> @@ -2957,11 +2974,11 @@ static int rbd_dev_image_id(struct rbd_device
> *rbd_dev)
> * First, see if the format 2 image id file exists, and if
> * so, get the image's persistent id from it.
> */
> - size = sizeof (RBD_ID_PREFIX) + rbd_dev->image_name_len;
> + size = sizeof (RBD_ID_PREFIX) + rbd_dev->spec->image_name_len;
> object_name = kmalloc(size, GFP_NOIO);
> if (!object_name)
> return -ENOMEM;
> - sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->image_name);
> + sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->spec->image_name);
> dout("rbd id object name is %s\n", object_name);
>
> /* Response will be an encoded string, which includes a length */
> @@ -2984,15 +3001,15 @@ static int rbd_dev_image_id(struct rbd_device
> *rbd_dev)
> ret = 0; /* rbd_req_sync_exec() can return positive */
>
> p = response;
> - rbd_dev->image_id = ceph_extract_encoded_string(&p,
> + rbd_dev->spec->image_id = ceph_extract_encoded_string(&p,
> p + RBD_IMAGE_ID_LEN_MAX,
> - &rbd_dev->image_id_len,
> + &rbd_dev->spec->image_id_len,
> GFP_NOIO);
> - if (IS_ERR(rbd_dev->image_id)) {
> - ret = PTR_ERR(rbd_dev->image_id);
> - rbd_dev->image_id = NULL;
> + if (IS_ERR(rbd_dev->spec->image_id)) {
> + ret = PTR_ERR(rbd_dev->spec->image_id);
> + rbd_dev->spec->image_id = NULL;
> } else {
> - dout("image_id is %s\n", rbd_dev->image_id);
> + dout("image_id is %s\n", rbd_dev->spec->image_id);
> }
> out:
> kfree(response);
> @@ -3008,20 +3025,21 @@ static int rbd_dev_v1_probe(struct rbd_device
> *rbd_dev)
>
> /* Version 1 images have no id; empty string is used */
>
> - rbd_dev->image_id = kstrdup("", GFP_KERNEL);
> - if (!rbd_dev->image_id)
> + rbd_dev->spec->image_id = kstrdup("", GFP_KERNEL);
> + if (!rbd_dev->spec->image_id)
> return -ENOMEM;
> - rbd_dev->image_id_len = 0;
> + rbd_dev->spec->image_id_len = 0;
>
> /* Record the header object name for this rbd image. */
>
> - size = rbd_dev->image_name_len + sizeof (RBD_SUFFIX);
> + size = rbd_dev->spec->image_name_len + sizeof (RBD_SUFFIX);
> rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
> if (!rbd_dev->header_name) {
> ret = -ENOMEM;
> goto out_err;
> }
> - sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);
> + sprintf(rbd_dev->header_name, "%s%s",
> + rbd_dev->spec->image_name, RBD_SUFFIX);
>
> /* Populate rbd image metadata */
>
> @@ -3038,8 +3056,8 @@ static int rbd_dev_v1_probe(struct rbd_device
> *rbd_dev)
> out_err:
> kfree(rbd_dev->header_name);
> rbd_dev->header_name = NULL;
> - kfree(rbd_dev->image_id);
> - rbd_dev->image_id = NULL;
> + kfree(rbd_dev->spec->image_id);
> + rbd_dev->spec->image_id = NULL;
>
> return ret;
> }
> @@ -3054,12 +3072,12 @@ static int rbd_dev_v2_probe(struct rbd_device
> *rbd_dev)
> * Image id was filled in by the caller. Record the header
> * object name for this rbd image.
> */
> - size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->image_id_len;
> + size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->spec->image_id_len;
> rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
> if (!rbd_dev->header_name)
> return -ENOMEM;
> sprintf(rbd_dev->header_name, "%s%s",
> - RBD_HEADER_PREFIX, rbd_dev->image_id);
> + RBD_HEADER_PREFIX, rbd_dev->spec->image_id);
>
> /* Get the size and object order for the image */
>
> @@ -3147,6 +3165,9 @@ static ssize_t rbd_add(struct bus_type *bus,
> rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
> if (!rbd_dev)
> return -ENOMEM;
> + rbd_dev->spec = kzalloc(sizeof (*rbd_dev->spec), GFP_KERNEL);
> + if (!rbd_dev->spec)
> + goto err_out_mem;
>
> /* static rbd_device initialization */
> spin_lock_init(&rbd_dev->lock);
> @@ -3167,10 +3188,10 @@ static ssize_t rbd_add(struct bus_type *bus,
>
> /* pick the pool */
> osdc = &rbd_dev->rbd_client->client->osdc;
> - rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->pool_name);
> + rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->spec->pool_name);
> if (rc < 0)
> goto err_out_client;
> - rbd_dev->pool_id = (u64) rc;
> + rbd_dev->spec->pool_id = (u64) rc;
>
> rc = rbd_dev_probe(rbd_dev);
> if (rc < 0)
> @@ -3257,15 +3278,16 @@ err_out_probe:
> err_out_client:
> kfree(rbd_dev->header_name);
> rbd_put_client(rbd_dev);
> - kfree(rbd_dev->image_id);
> + kfree(rbd_dev->spec->image_id);
> err_out_args:
> if (ceph_opts)
> ceph_destroy_options(ceph_opts);
> - kfree(rbd_dev->snap_name);
> - kfree(rbd_dev->image_name);
> - kfree(rbd_dev->pool_name);
> + kfree(rbd_dev->spec->snap_name);
> + kfree(rbd_dev->spec->image_name);
> + kfree(rbd_dev->spec->pool_name);
> kfree(rbd_opts);
> err_out_mem:
> + kfree(rbd_dev->spec);
> kfree(rbd_dev);
>
> dout("Error adding device %s\n", buf);
> @@ -3314,11 +3336,11 @@ static void rbd_dev_release(struct device *dev)
> rbd_header_free(&rbd_dev->header);
>
> /* done with the id, and with the rbd_dev */
> - kfree(rbd_dev->snap_name);
> - kfree(rbd_dev->image_id);
> + kfree(rbd_dev->spec->snap_name);
> + kfree(rbd_dev->spec->image_id);
> kfree(rbd_dev->header_name);
> - kfree(rbd_dev->pool_name);
> - kfree(rbd_dev->image_name);
> + kfree(rbd_dev->spec->pool_name);
> + kfree(rbd_dev->spec->image_name);
> rbd_dev_id_put(rbd_dev);
> kfree(rbd_dev);
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 6/8] rbd: define image specification structure
2012-10-29 22:13 ` Josh Durgin
@ 2012-10-30 12:40 ` Alex Elder
2012-10-30 20:13 ` Josh Durgin
0 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-30 12:40 UTC (permalink / raw)
To: Josh Durgin; +Cc: ceph-devel
On 10/29/2012 05:13 PM, Josh Durgin wrote:
> A couple notes below, but looks good.
I responded to all of your notes below. And I will update
the code/comments as appropriate after we have a chance
to talk about it but for the time being I'm going to
commit what I posted as-is.
-Alex
> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
>
> On 10/26/2012 04:03 PM, Alex Elder wrote:
>> Group the fields that uniquely specify an rbd image into a new
>> reference-counted rbd_spec structure. This structure will be used
>> to describe the desired image when mapping an image, and when
>> probing parent images in layered rbd devices. Replace the set of
>> fields in the rbd device structure with a pointer to a dynamically
>> allocated rbd_spec.
>>
>> Signed-off-by: Alex Elder <elder@inktank.com>
>> ---
>> drivers/block/rbd.c | 158
>> +++++++++++++++++++++++++++++----------------------
>> 1 file changed, 90 insertions(+), 68 deletions(-)
>>
>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>> index 388dd47..c39e238 100644
>> --- a/drivers/block/rbd.c
>> +++ b/drivers/block/rbd.c
>> @@ -112,6 +112,27 @@ struct rbd_image_header {
>> u64 obj_version;
>> };
>>
>> +/*
>> + * An rbd image specification.
>> + *
>> + * The tuple (pool_id, image_id, snap_id) is sufficient to uniquely
>> + * identify an image.
>> + */
>
> This looks like it's meant to be immutable. If so, it'd be nice
> to have that in the comment.
I want to be sure we agree on what that term means before saying
either way.
My aim in encapsulating this was to have a single thing represent
the identity of an image. I started with just the pool, image,
and snapshot id's, but after a bit decided the names really
belonged there too. I think the name<->id association can in
some cases change.
Also, for a given image, the id never changes, but a parent
will be specified using this, and that can change.
>> +struct rbd_spec {
>> + u64 pool_id;
>> + char *pool_name;
>> +
>> + char *image_id;
>> + size_t image_id_len;
>> + char *image_name;
>> + size_t image_name_len;
>
> I realize you're just rearranging things in this patch, but it's a bit
> odd that only image_id and image_name have corresponding lengths stored.
> Those fields don't seem necessary.
That's somewhat of an artifact, carrying along what was
already there, and grouping them like this makes it more
obvious those two were different.
Both the image id and image name lengths are now used one
place and it's basically one time only--in the probe routine.
So it is not valuable to keep them around. I will remove
them in a future patch.
>> +
>> + u64 snap_id;
>> + char *snap_name;
>> +
>> + struct kref kref;
>> +};
>> +
>> struct rbd_options {
>> bool read_only;
>> };
>> @@ -189,16 +210,9 @@ struct rbd_device {
>>
>> struct rbd_image_header header;
>> bool exists;
>> - char *image_id;
>> - size_t image_id_len;
>> - char *image_name;
>> - size_t image_name_len;
>> - char *header_name;
>> - char *pool_name;
>> - u64 pool_id;
>> + struct rbd_spec *spec;
>>
>> - char *snap_name;
>> - u64 snap_id;
>> + char *header_name;
>
> Are you planning to split out more stuff into a common
> struct rbd_image, like header_name, exists, etc?
> There's a bunch of stuff that's not specific to a particular rbd_device
> in here.
Possibly. Do you mean to distinguish the Linux device side
from the rados storage side? Let's talk about this today.
>>
>> struct ceph_osd_event *watch_event;
>> struct ceph_osd_request *watch_request;
>> @@ -654,7 +668,7 @@ static int snap_by_name(struct rbd_device *rbd_dev,
>> const char *snap_name)
>>
>> list_for_each_entry(snap, &rbd_dev->snaps, node) {
>> if (!strcmp(snap_name, snap->name)) {
>> - rbd_dev->snap_id = snap->id;
>> + rbd_dev->spec->snap_id = snap->id;
>> rbd_dev->mapping.size = snap->size;
>> rbd_dev->mapping.features = snap->features;
>>
. . .
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 6/8] rbd: define image specification structure
2012-10-30 12:40 ` Alex Elder
@ 2012-10-30 20:13 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-30 20:13 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
On 10/30/2012 05:40 AM, Alex Elder wrote:
> On 10/29/2012 05:13 PM, Josh Durgin wrote:
>> A couple notes below, but looks good.
>
> I responded to all of your notes below. And I will update
> the code/comments as appropriate after we have a chance
> to talk about it but for the time being I'm going to
> commit what I posted as-is.
>
> -Alex
>
>> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
>>
>> On 10/26/2012 04:03 PM, Alex Elder wrote:
>>> Group the fields that uniquely specify an rbd image into a new
>>> reference-counted rbd_spec structure. This structure will be used
>>> to describe the desired image when mapping an image, and when
>>> probing parent images in layered rbd devices. Replace the set of
>>> fields in the rbd device structure with a pointer to a dynamically
>>> allocated rbd_spec.
>>>
>>> Signed-off-by: Alex Elder <elder@inktank.com>
>>> ---
>>> drivers/block/rbd.c | 158
>>> +++++++++++++++++++++++++++++----------------------
>>> 1 file changed, 90 insertions(+), 68 deletions(-)
>>>
>>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>>> index 388dd47..c39e238 100644
>>> --- a/drivers/block/rbd.c
>>> +++ b/drivers/block/rbd.c
>>> @@ -112,6 +112,27 @@ struct rbd_image_header {
>>> u64 obj_version;
>>> };
>>>
>>> +/*
>>> + * An rbd image specification.
>>> + *
>>> + * The tuple (pool_id, image_id, snap_id) is sufficient to uniquely
>>> + * identify an image.
>>> + */
>>
>> This looks like it's meant to be immutable. If so, it'd be nice
>> to have that in the comment.
>
> I want to be sure we agree on what that term means before saying
> either way.
>
> My aim in encapsulating this was to have a single thing represent
> the identity of an image. I started with just the pool, image,
> and snapshot id's, but after a bit decided the names really
> belonged there too. I think the name<->id association can in
> some cases change.
>
> Also, for a given image, the id never changes, but a parent
> will be specified using this, and that can change.
When I was asking about immutability, I was wondering whether access to
the fields inside an rbd_spec would need to be synchronized. If those
fields won't change, it'd be good to document that fact. Otherwise
document how they'll be accessed.
>>> +struct rbd_spec {
>>> + u64 pool_id;
>>> + char *pool_name;
>>> +
>>> + char *image_id;
>>> + size_t image_id_len;
>>> + char *image_name;
>>> + size_t image_name_len;
>>
>> I realize you're just rearranging things in this patch, but it's a bit
>> odd that only image_id and image_name have corresponding lengths stored.
>> Those fields don't seem necessary.
>
> That's somewhat of an artifact, carrying along what was
> already there, and grouping them like this makes it more
> obvious those two were different.
>
> Both the image id and image name lengths are now used one
> place and it's basically one time only--in the probe routine.
> So it is not valuable to keep them around. I will remove
> them in a future patch.
Sounds good.
>>> +
>>> + u64 snap_id;
>>> + char *snap_name;
>>> +
>>> + struct kref kref;
>>> +};
>>> +
>>> struct rbd_options {
>>> bool read_only;
>>> };
>>> @@ -189,16 +210,9 @@ struct rbd_device {
>>>
>>> struct rbd_image_header header;
>>> bool exists;
>>> - char *image_id;
>>> - size_t image_id_len;
>>> - char *image_name;
>>> - size_t image_name_len;
>>> - char *header_name;
>>> - char *pool_name;
>>> - u64 pool_id;
>>> + struct rbd_spec *spec;
>>>
>>> - char *snap_name;
>>> - u64 snap_id;
>>> + char *header_name;
>>
>> Are you planning to split out more stuff into a common
>> struct rbd_image, like header_name, exists, etc?
>> There's a bunch of stuff that's not specific to a particular rbd_device
>> in here.
>
> Possibly. Do you mean to distinguish the Linux device side
> from the rados storage side? Let's talk about this today.
Yes that's what I meant. We talked about this, and decided
this separation isn't needed yet, and may not be needed to
implement layering.
>>>
>>> struct ceph_osd_event *watch_event;
>>> struct ceph_osd_request *watch_request;
>>> @@ -654,7 +668,7 @@ static int snap_by_name(struct rbd_device *rbd_dev,
>>> const char *snap_name)
>>>
>>> list_for_each_entry(snap, &rbd_dev->snaps, node) {
>>> if (!strcmp(snap_name, snap->name)) {
>>> - rbd_dev->snap_id = snap->id;
>>> + rbd_dev->spec->snap_id = snap->id;
>>> rbd_dev->mapping.size = snap->size;
>>> rbd_dev->mapping.features = snap->features;
>>>
>
> . . .
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 7/8] rbd: add reference counting to rbd_spec
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
` (5 preceding siblings ...)
2012-10-26 23:03 ` [PATCH 6/8] rbd: define image specification structure Alex Elder
@ 2012-10-26 23:03 ` Alex Elder
2012-10-29 22:20 ` Josh Durgin
2012-10-26 23:03 ` [PATCH 8/8] rbd: fill rbd_spec in rbd_add_parse_args() Alex Elder
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:03 UTC (permalink / raw)
To: ceph-devel
With layered images we'll share rbd_spec structures, so add a
reference count to it. It neatens up some code also.
A silly get/put pair is added to the alloc routine just to avoid
"defined but not used" warnings. It will go away soon.
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 52
+++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 42 insertions(+), 10 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index c39e238..19c7c6b 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2134,6 +2134,45 @@ static struct device_type rbd_snap_device_type = {
.release = rbd_snap_dev_release,
};
+static struct rbd_spec *rbd_spec_get(struct rbd_spec *spec)
+{
+ kref_get(&spec->kref);
+
+ return spec;
+}
+
+static void rbd_spec_free(struct kref *kref);
+static void rbd_spec_put(struct rbd_spec *spec)
+{
+ if (spec)
+ kref_put(&spec->kref, rbd_spec_free);
+}
+
+static struct rbd_spec *rbd_spec_alloc(void)
+{
+ struct rbd_spec *spec;
+
+ spec = kzalloc(sizeof (*spec), GFP_KERNEL);
+ if (!spec)
+ return NULL;
+ kref_init(&spec->kref);
+
+ rbd_spec_put(rbd_spec_get(spec)); /* TEMPORARY */
+
+ return spec;
+}
+
+static void rbd_spec_free(struct kref *kref)
+{
+ struct rbd_spec *spec = container_of(kref, struct rbd_spec, kref);
+
+ kfree(spec->pool_name);
+ kfree(spec->image_id);
+ kfree(spec->image_name);
+ kfree(spec->snap_name);
+ kfree(spec);
+}
+
static bool rbd_snap_registered(struct rbd_snap *snap)
{
bool ret = snap->dev.type == &rbd_snap_device_type;
@@ -3165,7 +3204,7 @@ static ssize_t rbd_add(struct bus_type *bus,
rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
if (!rbd_dev)
return -ENOMEM;
- rbd_dev->spec = kzalloc(sizeof (*rbd_dev->spec), GFP_KERNEL);
+ rbd_dev->spec = rbd_spec_alloc();
if (!rbd_dev->spec)
goto err_out_mem;
@@ -3278,16 +3317,12 @@ err_out_probe:
err_out_client:
kfree(rbd_dev->header_name);
rbd_put_client(rbd_dev);
- kfree(rbd_dev->spec->image_id);
err_out_args:
if (ceph_opts)
ceph_destroy_options(ceph_opts);
- kfree(rbd_dev->spec->snap_name);
- kfree(rbd_dev->spec->image_name);
- kfree(rbd_dev->spec->pool_name);
kfree(rbd_opts);
err_out_mem:
- kfree(rbd_dev->spec);
+ rbd_spec_put(rbd_dev->spec);
kfree(rbd_dev);
dout("Error adding device %s\n", buf);
@@ -3336,12 +3371,9 @@ static void rbd_dev_release(struct device *dev)
rbd_header_free(&rbd_dev->header);
/* done with the id, and with the rbd_dev */
- kfree(rbd_dev->spec->snap_name);
- kfree(rbd_dev->spec->image_id);
kfree(rbd_dev->header_name);
- kfree(rbd_dev->spec->pool_name);
- kfree(rbd_dev->spec->image_name);
rbd_dev_id_put(rbd_dev);
+ rbd_spec_put(rbd_dev->spec);
kfree(rbd_dev);
/* release module ref */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 7/8] rbd: add reference counting to rbd_spec
2012-10-26 23:03 ` [PATCH 7/8] rbd: add reference counting to rbd_spec Alex Elder
@ 2012-10-29 22:20 ` Josh Durgin
2012-10-30 12:59 ` Alex Elder
0 siblings, 1 reply; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 22:20 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
On 10/26/2012 04:03 PM, Alex Elder wrote:
> With layered images we'll share rbd_spec structures, so add a
> reference count to it. It neatens up some code also.
Could you explain your plan for these data structures? What
will the structs and their relationships look like with
clones mapped?
> A silly get/put pair is added to the alloc routine just to avoid
> "defined but not used" warnings. It will go away soon.
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 52
> +++++++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 42 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index c39e238..19c7c6b 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -2134,6 +2134,45 @@ static struct device_type rbd_snap_device_type = {
> .release = rbd_snap_dev_release,
> };
>
> +static struct rbd_spec *rbd_spec_get(struct rbd_spec *spec)
> +{
> + kref_get(&spec->kref);
> +
> + return spec;
> +}
> +
> +static void rbd_spec_free(struct kref *kref);
> +static void rbd_spec_put(struct rbd_spec *spec)
> +{
> + if (spec)
> + kref_put(&spec->kref, rbd_spec_free);
> +}
> +
> +static struct rbd_spec *rbd_spec_alloc(void)
> +{
> + struct rbd_spec *spec;
> +
> + spec = kzalloc(sizeof (*spec), GFP_KERNEL);
> + if (!spec)
> + return NULL;
> + kref_init(&spec->kref);
> +
> + rbd_spec_put(rbd_spec_get(spec)); /* TEMPORARY */
> +
> + return spec;
> +}
> +
> +static void rbd_spec_free(struct kref *kref)
> +{
> + struct rbd_spec *spec = container_of(kref, struct rbd_spec, kref);
> +
> + kfree(spec->pool_name);
> + kfree(spec->image_id);
> + kfree(spec->image_name);
> + kfree(spec->snap_name);
> + kfree(spec);
> +}
> +
> static bool rbd_snap_registered(struct rbd_snap *snap)
> {
> bool ret = snap->dev.type == &rbd_snap_device_type;
> @@ -3165,7 +3204,7 @@ static ssize_t rbd_add(struct bus_type *bus,
> rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
> if (!rbd_dev)
> return -ENOMEM;
> - rbd_dev->spec = kzalloc(sizeof (*rbd_dev->spec), GFP_KERNEL);
> + rbd_dev->spec = rbd_spec_alloc();
> if (!rbd_dev->spec)
> goto err_out_mem;
>
> @@ -3278,16 +3317,12 @@ err_out_probe:
> err_out_client:
> kfree(rbd_dev->header_name);
> rbd_put_client(rbd_dev);
> - kfree(rbd_dev->spec->image_id);
> err_out_args:
> if (ceph_opts)
> ceph_destroy_options(ceph_opts);
> - kfree(rbd_dev->spec->snap_name);
> - kfree(rbd_dev->spec->image_name);
> - kfree(rbd_dev->spec->pool_name);
> kfree(rbd_opts);
> err_out_mem:
> - kfree(rbd_dev->spec);
> + rbd_spec_put(rbd_dev->spec);
> kfree(rbd_dev);
>
> dout("Error adding device %s\n", buf);
> @@ -3336,12 +3371,9 @@ static void rbd_dev_release(struct device *dev)
> rbd_header_free(&rbd_dev->header);
>
> /* done with the id, and with the rbd_dev */
> - kfree(rbd_dev->spec->snap_name);
> - kfree(rbd_dev->spec->image_id);
> kfree(rbd_dev->header_name);
> - kfree(rbd_dev->spec->pool_name);
> - kfree(rbd_dev->spec->image_name);
> rbd_dev_id_put(rbd_dev);
> + rbd_spec_put(rbd_dev->spec);
> kfree(rbd_dev);
>
> /* release module ref */
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 7/8] rbd: add reference counting to rbd_spec
2012-10-29 22:20 ` Josh Durgin
@ 2012-10-30 12:59 ` Alex Elder
2012-10-30 20:17 ` Josh Durgin
0 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-30 12:59 UTC (permalink / raw)
To: Josh Durgin; +Cc: ceph-devel
On 10/29/2012 05:20 PM, Josh Durgin wrote:
> On 10/26/2012 04:03 PM, Alex Elder wrote:
>> With layered images we'll share rbd_spec structures, so add a
>> reference count to it. It neatens up some code also.
>
> Could you explain your plan for these data structures? What
> will the structs and their relationships look like with
> clones mapped?
Like I mentioned in the previous message, this structure
encapsulates the information that identifies an rbd image.
In the next patch, the information defining the image to
be mapped is extracted from "command line" arguments to
populate the content of one of these in the argument
parsing routine.
In an upcoming patch, some create/destroy helper routines
will be defined for an rbd_device structure. To create an
rbd device, you provide an initialized (activated?)
rbd_client (which includes a ceph client) and the identity
of an image you want that rbd_device to map using that client.
So in response to a map request via /sys/bus/rbd/add, a
new rbd_client will be created in that way. Later, a
mapped rbd image (v2) will continue its probing activity
by probing its parent, and if it has one, an rbd_device
structure will be created for that purpose, using the
same client as the original/child image and the image
specification fetched from the child for the parent.
I suppose it's not obvious at this point why reference
counting is needed. It's one of those things that is
needed later on (in work that's well underway but which
I have not posted yet), and this turns out to be a
good time to put that in place so it's there when it's
needed, shortly.
In any case, the reference counting here arises because
the image spec for a parent will be created and filled in
while probing the child. But I want to provide that image
spec for creating the parent rbd_device structure, and
keeping track of who owned what got a little confusing
so I decided that just sharing a reference counted
structure was the best way to go.
-Alex
>> A silly get/put pair is added to the alloc routine just to avoid
>> "defined but not used" warnings. It will go away soon.
>>
>> Signed-off-by: Alex Elder <elder@inktank.com>
>> ---
>> drivers/block/rbd.c | 52
>> +++++++++++++++++++++++++++++++++++++++++----------
>> 1 file changed, 42 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>> index c39e238..19c7c6b 100644
>> --- a/drivers/block/rbd.c
>> +++ b/drivers/block/rbd.c
>> @@ -2134,6 +2134,45 @@ static struct device_type rbd_snap_device_type = {
>> .release = rbd_snap_dev_release,
>> };
>>
>> +static struct rbd_spec *rbd_spec_get(struct rbd_spec *spec)
>> +{
>> + kref_get(&spec->kref);
>> +
>> + return spec;
>> +}
>> +
>> +static void rbd_spec_free(struct kref *kref);
>> +static void rbd_spec_put(struct rbd_spec *spec)
>> +{
>> + if (spec)
>> + kref_put(&spec->kref, rbd_spec_free);
>> +}
>> +
>> +static struct rbd_spec *rbd_spec_alloc(void)
>> +{
>> + struct rbd_spec *spec;
>> +
>> + spec = kzalloc(sizeof (*spec), GFP_KERNEL);
>> + if (!spec)
>> + return NULL;
>> + kref_init(&spec->kref);
>> +
>> + rbd_spec_put(rbd_spec_get(spec)); /* TEMPORARY */
>> +
>> + return spec;
>> +}
>> +
>> +static void rbd_spec_free(struct kref *kref)
>> +{
>> + struct rbd_spec *spec = container_of(kref, struct rbd_spec, kref);
>> +
>> + kfree(spec->pool_name);
>> + kfree(spec->image_id);
>> + kfree(spec->image_name);
>> + kfree(spec->snap_name);
>> + kfree(spec);
>> +}
>> +
>> static bool rbd_snap_registered(struct rbd_snap *snap)
>> {
>> bool ret = snap->dev.type == &rbd_snap_device_type;
>> @@ -3165,7 +3204,7 @@ static ssize_t rbd_add(struct bus_type *bus,
>> rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
>> if (!rbd_dev)
>> return -ENOMEM;
>> - rbd_dev->spec = kzalloc(sizeof (*rbd_dev->spec), GFP_KERNEL);
>> + rbd_dev->spec = rbd_spec_alloc();
>> if (!rbd_dev->spec)
>> goto err_out_mem;
>>
>> @@ -3278,16 +3317,12 @@ err_out_probe:
>> err_out_client:
>> kfree(rbd_dev->header_name);
>> rbd_put_client(rbd_dev);
>> - kfree(rbd_dev->spec->image_id);
>> err_out_args:
>> if (ceph_opts)
>> ceph_destroy_options(ceph_opts);
>> - kfree(rbd_dev->spec->snap_name);
>> - kfree(rbd_dev->spec->image_name);
>> - kfree(rbd_dev->spec->pool_name);
>> kfree(rbd_opts);
>> err_out_mem:
>> - kfree(rbd_dev->spec);
>> + rbd_spec_put(rbd_dev->spec);
>> kfree(rbd_dev);
>>
>> dout("Error adding device %s\n", buf);
>> @@ -3336,12 +3371,9 @@ static void rbd_dev_release(struct device *dev)
>> rbd_header_free(&rbd_dev->header);
>>
>> /* done with the id, and with the rbd_dev */
>> - kfree(rbd_dev->spec->snap_name);
>> - kfree(rbd_dev->spec->image_id);
>> kfree(rbd_dev->header_name);
>> - kfree(rbd_dev->spec->pool_name);
>> - kfree(rbd_dev->spec->image_name);
>> rbd_dev_id_put(rbd_dev);
>> + rbd_spec_put(rbd_dev->spec);
>> kfree(rbd_dev);
>>
>> /* release module ref */
>>
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 7/8] rbd: add reference counting to rbd_spec
2012-10-30 12:59 ` Alex Elder
@ 2012-10-30 20:17 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-30 20:17 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
On 10/30/2012 05:59 AM, Alex Elder wrote:
> On 10/29/2012 05:20 PM, Josh Durgin wrote:
>> On 10/26/2012 04:03 PM, Alex Elder wrote:
>>> With layered images we'll share rbd_spec structures, so add a
>>> reference count to it. It neatens up some code also.
>>
>> Could you explain your plan for these data structures? What
>> will the structs and their relationships look like with
>> clones mapped?
>
> Like I mentioned in the previous message, this structure
> encapsulates the information that identifies an rbd image.
>
> In the next patch, the information defining the image to
> be mapped is extracted from "command line" arguments to
> populate the content of one of these in the argument
> parsing routine.
>
> In an upcoming patch, some create/destroy helper routines
> will be defined for an rbd_device structure. To create an
> rbd device, you provide an initialized (activated?)
> rbd_client (which includes a ceph client) and the identity
> of an image you want that rbd_device to map using that client.
>
> So in response to a map request via /sys/bus/rbd/add, a
> new rbd_client will be created in that way. Later, a
> mapped rbd image (v2) will continue its probing activity
> by probing its parent, and if it has one, an rbd_device
> structure will be created for that purpose, using the
> same client as the original/child image and the image
> specification fetched from the child for the parent.
>
> I suppose it's not obvious at this point why reference
> counting is needed. It's one of those things that is
> needed later on (in work that's well underway but which
> I have not posted yet), and this turns out to be a
> good time to put that in place so it's there when it's
> needed, shortly.
>
> In any case, the reference counting here arises because
> the image spec for a parent will be created and filled in
> while probing the child. But I want to provide that image
> spec for creating the parent rbd_device structure, and
> keeping track of who owned what got a little confusing
> so I decided that just sharing a reference counted
> structure was the best way to go.
This makes sense now, thanks.
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
> -Alex
>
>>> A silly get/put pair is added to the alloc routine just to avoid
>>> "defined but not used" warnings. It will go away soon.
>>>
>>> Signed-off-by: Alex Elder <elder@inktank.com>
>>> ---
>>> drivers/block/rbd.c | 52
>>> +++++++++++++++++++++++++++++++++++++++++----------
>>> 1 file changed, 42 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>>> index c39e238..19c7c6b 100644
>>> --- a/drivers/block/rbd.c
>>> +++ b/drivers/block/rbd.c
>>> @@ -2134,6 +2134,45 @@ static struct device_type rbd_snap_device_type = {
>>> .release = rbd_snap_dev_release,
>>> };
>>>
>>> +static struct rbd_spec *rbd_spec_get(struct rbd_spec *spec)
>>> +{
>>> + kref_get(&spec->kref);
>>> +
>>> + return spec;
>>> +}
>>> +
>>> +static void rbd_spec_free(struct kref *kref);
>>> +static void rbd_spec_put(struct rbd_spec *spec)
>>> +{
>>> + if (spec)
>>> + kref_put(&spec->kref, rbd_spec_free);
>>> +}
>>> +
>>> +static struct rbd_spec *rbd_spec_alloc(void)
>>> +{
>>> + struct rbd_spec *spec;
>>> +
>>> + spec = kzalloc(sizeof (*spec), GFP_KERNEL);
>>> + if (!spec)
>>> + return NULL;
>>> + kref_init(&spec->kref);
>>> +
>>> + rbd_spec_put(rbd_spec_get(spec)); /* TEMPORARY */
>>> +
>>> + return spec;
>>> +}
>>> +
>>> +static void rbd_spec_free(struct kref *kref)
>>> +{
>>> + struct rbd_spec *spec = container_of(kref, struct rbd_spec, kref);
>>> +
>>> + kfree(spec->pool_name);
>>> + kfree(spec->image_id);
>>> + kfree(spec->image_name);
>>> + kfree(spec->snap_name);
>>> + kfree(spec);
>>> +}
>>> +
>>> static bool rbd_snap_registered(struct rbd_snap *snap)
>>> {
>>> bool ret = snap->dev.type == &rbd_snap_device_type;
>>> @@ -3165,7 +3204,7 @@ static ssize_t rbd_add(struct bus_type *bus,
>>> rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
>>> if (!rbd_dev)
>>> return -ENOMEM;
>>> - rbd_dev->spec = kzalloc(sizeof (*rbd_dev->spec), GFP_KERNEL);
>>> + rbd_dev->spec = rbd_spec_alloc();
>>> if (!rbd_dev->spec)
>>> goto err_out_mem;
>>>
>>> @@ -3278,16 +3317,12 @@ err_out_probe:
>>> err_out_client:
>>> kfree(rbd_dev->header_name);
>>> rbd_put_client(rbd_dev);
>>> - kfree(rbd_dev->spec->image_id);
>>> err_out_args:
>>> if (ceph_opts)
>>> ceph_destroy_options(ceph_opts);
>>> - kfree(rbd_dev->spec->snap_name);
>>> - kfree(rbd_dev->spec->image_name);
>>> - kfree(rbd_dev->spec->pool_name);
>>> kfree(rbd_opts);
>>> err_out_mem:
>>> - kfree(rbd_dev->spec);
>>> + rbd_spec_put(rbd_dev->spec);
>>> kfree(rbd_dev);
>>>
>>> dout("Error adding device %s\n", buf);
>>> @@ -3336,12 +3371,9 @@ static void rbd_dev_release(struct device *dev)
>>> rbd_header_free(&rbd_dev->header);
>>>
>>> /* done with the id, and with the rbd_dev */
>>> - kfree(rbd_dev->spec->snap_name);
>>> - kfree(rbd_dev->spec->image_id);
>>> kfree(rbd_dev->header_name);
>>> - kfree(rbd_dev->spec->pool_name);
>>> - kfree(rbd_dev->spec->image_name);
>>> rbd_dev_id_put(rbd_dev);
>>> + rbd_spec_put(rbd_dev->spec);
>>> kfree(rbd_dev);
>>>
>>> /* release module ref */
>>>
>>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 8/8] rbd: fill rbd_spec in rbd_add_parse_args()
2012-10-26 22:56 ` [PATCH 0/8] rbd: have rbd_add_parse_args() only parse args Alex Elder
` (6 preceding siblings ...)
2012-10-26 23:03 ` [PATCH 7/8] rbd: add reference counting to rbd_spec Alex Elder
@ 2012-10-26 23:03 ` Alex Elder
2012-10-29 22:30 ` Josh Durgin
7 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-26 23:03 UTC (permalink / raw)
To: ceph-devel
Pass the address of an rbd_spec structure to rbd_add_parse_args().
Use it to hold the information defining the rbd image to be mapped
in an rbd_add() call.
Use the result in the caller to initialize the rbd_dev->id field.
This means rbd_dev is no longer needed in rbd_add_parse_args(),
so get rid of it.
Now that this transformation of rbd_add_parse_args() is complete,
correct and expand on the its header documentation to reflect the
new reality.
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 104
++++++++++++++++++++++++++++++++++-----------------
1 file changed, 70 insertions(+), 34 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 19c7c6b..28abd31 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2887,21 +2887,53 @@ static inline char *dup_token(const char **buf,
size_t *lenp)
}
/*
- * This fills in the pool_name, image_name, image_name_len, rbd_dev,
- * rbd_md_name, and name fields of the given rbd_dev, based on the
- * list of monitor addresses and other options provided via
- * /sys/bus/rbd/add. Returns a pointer to a dynamically-allocated
- * copy of the snapshot name to map if successful, or a
- * pointer-coded error otherwise.
+ * Parse the options provided for an "rbd add" (i.e., rbd image
+ * mapping) request. These arrive via a write to /sys/bus/rbd/add,
+ * and the data written is passed here via a NUL-terminated buffer.
+ * Returns 0 if successful or an error code otherwise.
*
- * Note: rbd_dev is assumed to have been initially zero-filled.
+ * The information extracted from these options is recorded in
+ * the other parameters which return dynamically-allocated
+ * structures:
+ * ceph_opts
+ * The address of a pointer that will refer to a ceph options
+ * structure. Caller must release the returned pointer using
+ * ceph_destroy_options() when it is no longer needed.
+ * rbd_opts
+ * Address of an rbd options pointer. Fully initialized by
+ * this function; caller must release with kfree().
+ * spec
+ * Address of an rbd image specification pointer. Fully
+ * initialized by this function based on parsed options.
+ * Caller must release with kfree().
+ *
+ * The options passed take this form:
+ * <mon_addrs> <options> <pool_name> <image_name> [<snap_id>]
+ * where:
+ * <mon_addrs>
+ * A comma-separated list of one or more monitor addresses.
+ * A monitor address is an ip address, optionally followed
+ * by a port number (separated by a colon).
+ * I.e.: ip1[:port1][,ip2[:port2]...]
+ * <options>
+ * A comma-separated list of ceph and/or rbd options.
+ * <pool_name>
+ * The name of the rados pool containing the rbd image.
+ * <image_name>
+ * The name of the image in that pool to map.
+ * <snap_id>
+ * An optional snapshot id. If provided, the mapping will
+ * present data from the image at the time that snapshot was
+ * created. The image head is used if no snapshot id is
+ * provided. Snapshot mappings are always read-only.
*/
-static int rbd_add_parse_args(struct rbd_device *rbd_dev,
- const char *buf,
+static int rbd_add_parse_args(const char *buf,
struct ceph_options **ceph_opts,
- struct rbd_options **opts)
+ struct rbd_options **opts,
+ struct rbd_spec **rbd_spec)
{
size_t len;
+ struct rbd_spec *spec;
const char *mon_addrs;
size_t mon_addrs_size;
char *options;
@@ -2917,24 +2949,27 @@ static int rbd_add_parse_args(struct rbd_device
*rbd_dev,
mon_addrs_size = len + 1;
buf += len;
+ spec = rbd_spec_alloc();
+ if (!spec)
+ return -ENOMEM;
+
ret = -EINVAL;
options = dup_token(&buf, NULL);
if (!options)
- return -ENOMEM;
+ goto out_mem;
if (!*options)
goto out_err; /* Missing options */
- rbd_dev->spec->pool_name = dup_token(&buf, NULL);
- if (!rbd_dev->spec->pool_name)
+ spec->pool_name = dup_token(&buf, NULL);
+ if (!spec->pool_name)
goto out_mem;
- if (!*rbd_dev->spec->pool_name)
+ if (!*spec->pool_name)
goto out_err; /* Missing pool name */
- rbd_dev->spec->image_name =
- dup_token(&buf, &rbd_dev->spec->image_name_len);
- if (!rbd_dev->spec->image_name)
+ spec->image_name = dup_token(&buf, &spec->image_name_len);
+ if (!spec->image_name)
goto out_mem;
- if (!*rbd_dev->spec->image_name)
+ if (!*spec->image_name)
goto out_err; /* Missing image name */
/*
@@ -2949,11 +2984,11 @@ static int rbd_add_parse_args(struct rbd_device
*rbd_dev,
ret = -ENAMETOOLONG;
goto out_err;
}
- rbd_dev->spec->snap_name = kmalloc(len + 1, GFP_KERNEL);
- if (!rbd_dev->spec->snap_name)
+ spec->snap_name = kmalloc(len + 1, GFP_KERNEL);
+ if (!spec->snap_name)
goto out_mem;
- memcpy(rbd_dev->spec->snap_name, buf, len);
- *(rbd_dev->spec->snap_name + len) = '\0';
+ memcpy(spec->snap_name, buf, len);
+ *(spec->snap_name + len) = '\0';
/* Initialize all rbd options to the defaults */
@@ -2973,15 +3008,15 @@ static int rbd_add_parse_args(struct rbd_device
*rbd_dev,
}
*opts = rbd_opts;
+ *rbd_spec = spec;
+
return 0;
out_mem:
ret = -ENOMEM;
+ kfree(spec->image_name);
+ kfree(spec->pool_name);
+ kfree(spec);
out_err:
- kfree(rbd_dev->spec->image_name);
- rbd_dev->spec->image_name = NULL;
- rbd_dev->spec->image_name_len = 0;
- kfree(rbd_dev->spec->pool_name);
- rbd_dev->spec->pool_name = NULL;
kfree(options);
return ret;
@@ -3195,6 +3230,7 @@ static ssize_t rbd_add(struct bus_type *bus,
struct rbd_device *rbd_dev = NULL;
struct ceph_options *ceph_opts = NULL;
struct rbd_options *rbd_opts = NULL;
+ struct rbd_spec *spec = NULL;
struct ceph_osd_client *osdc;
int rc = -ENOMEM;
@@ -3204,9 +3240,6 @@ static ssize_t rbd_add(struct bus_type *bus,
rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
if (!rbd_dev)
return -ENOMEM;
- rbd_dev->spec = rbd_spec_alloc();
- if (!rbd_dev->spec)
- goto err_out_mem;
/* static rbd_device initialization */
spin_lock_init(&rbd_dev->lock);
@@ -3215,9 +3248,10 @@ static ssize_t rbd_add(struct bus_type *bus,
init_rwsem(&rbd_dev->header_rwsem);
/* parse add command */
- rc = rbd_add_parse_args(rbd_dev, buf, &ceph_opts, &rbd_opts);
+ rc = rbd_add_parse_args(buf, &ceph_opts, &rbd_opts, &spec);
if (rc < 0)
goto err_out_mem;
+
rbd_dev->mapping.read_only = rbd_opts->read_only;
rc = rbd_get_client(rbd_dev, ceph_opts);
@@ -3227,10 +3261,12 @@ static ssize_t rbd_add(struct bus_type *bus,
/* pick the pool */
osdc = &rbd_dev->rbd_client->client->osdc;
- rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->spec->pool_name);
+ rc = ceph_pg_poolid_by_name(osdc->osdmap, spec->pool_name);
if (rc < 0)
goto err_out_client;
- rbd_dev->spec->pool_id = (u64) rc;
+ spec->pool_id = (u64) rc;
+
+ rbd_dev->spec = spec;
rc = rbd_dev_probe(rbd_dev);
if (rc < 0)
@@ -3321,8 +3357,8 @@ err_out_args:
if (ceph_opts)
ceph_destroy_options(ceph_opts);
kfree(rbd_opts);
+ rbd_spec_put(spec);
err_out_mem:
- rbd_spec_put(rbd_dev->spec);
kfree(rbd_dev);
dout("Error adding device %s\n", buf);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 8/8] rbd: fill rbd_spec in rbd_add_parse_args()
2012-10-26 23:03 ` [PATCH 8/8] rbd: fill rbd_spec in rbd_add_parse_args() Alex Elder
@ 2012-10-29 22:30 ` Josh Durgin
2012-10-30 13:09 ` Alex Elder
0 siblings, 1 reply; 41+ messages in thread
From: Josh Durgin @ 2012-10-29 22:30 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
On 10/26/2012 04:03 PM, Alex Elder wrote:
> Pass the address of an rbd_spec structure to rbd_add_parse_args().
> Use it to hold the information defining the rbd image to be mapped
> in an rbd_add() call.
>
> Use the result in the caller to initialize the rbd_dev->id field.
>
> This means rbd_dev is no longer needed in rbd_add_parse_args(),
> so get rid of it.
>
> Now that this transformation of rbd_add_parse_args() is complete,
> correct and expand on the its header documentation to reflect the
> new reality.
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> drivers/block/rbd.c | 104
> ++++++++++++++++++++++++++++++++++-----------------
> 1 file changed, 70 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 19c7c6b..28abd31 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -2887,21 +2887,53 @@ static inline char *dup_token(const char **buf,
> size_t *lenp)
> }
>
> /*
> - * This fills in the pool_name, image_name, image_name_len, rbd_dev,
> - * rbd_md_name, and name fields of the given rbd_dev, based on the
> - * list of monitor addresses and other options provided via
> - * /sys/bus/rbd/add. Returns a pointer to a dynamically-allocated
> - * copy of the snapshot name to map if successful, or a
> - * pointer-coded error otherwise.
> + * Parse the options provided for an "rbd add" (i.e., rbd image
> + * mapping) request. These arrive via a write to /sys/bus/rbd/add,
> + * and the data written is passed here via a NUL-terminated buffer.
> + * Returns 0 if successful or an error code otherwise.
> *
> - * Note: rbd_dev is assumed to have been initially zero-filled.
> + * The information extracted from these options is recorded in
> + * the other parameters which return dynamically-allocated
> + * structures:
> + * ceph_opts
> + * The address of a pointer that will refer to a ceph options
> + * structure. Caller must release the returned pointer using
> + * ceph_destroy_options() when it is no longer needed.
> + * rbd_opts
> + * Address of an rbd options pointer. Fully initialized by
> + * this function; caller must release with kfree().
> + * spec
> + * Address of an rbd image specification pointer. Fully
> + * initialized by this function based on parsed options.
> + * Caller must release with kfree().
> + *
> + * The options passed take this form:
> + * <mon_addrs> <options> <pool_name> <image_name> [<snap_id>]
> + * where:
> + * <mon_addrs>
> + * A comma-separated list of one or more monitor addresses.
> + * A monitor address is an ip address, optionally followed
> + * by a port number (separated by a colon).
> + * I.e.: ip1[:port1][,ip2[:port2]...]
> + * <options>
> + * A comma-separated list of ceph and/or rbd options.
> + * <pool_name>
> + * The name of the rados pool containing the rbd image.
> + * <image_name>
> + * The name of the image in that pool to map.
> + * <snap_id>
> + * An optional snapshot id. If provided, the mapping will
> + * present data from the image at the time that snapshot was
> + * created. The image head is used if no snapshot id is
> + * provided. Snapshot mappings are always read-only.
> */
> -static int rbd_add_parse_args(struct rbd_device *rbd_dev,
> - const char *buf,
> +static int rbd_add_parse_args(const char *buf,
> struct ceph_options **ceph_opts,
> - struct rbd_options **opts)
> + struct rbd_options **opts,
> + struct rbd_spec **rbd_spec)
> {
> size_t len;
> + struct rbd_spec *spec;
> const char *mon_addrs;
> size_t mon_addrs_size;
> char *options;
> @@ -2917,24 +2949,27 @@ static int rbd_add_parse_args(struct rbd_device
> *rbd_dev,
> mon_addrs_size = len + 1;
> buf += len;
>
> + spec = rbd_spec_alloc();
> + if (!spec)
> + return -ENOMEM;
> +
> ret = -EINVAL;
> options = dup_token(&buf, NULL);
> if (!options)
> - return -ENOMEM;
> + goto out_mem;
> if (!*options)
> goto out_err; /* Missing options */
>
> - rbd_dev->spec->pool_name = dup_token(&buf, NULL);
> - if (!rbd_dev->spec->pool_name)
> + spec->pool_name = dup_token(&buf, NULL);
> + if (!spec->pool_name)
> goto out_mem;
> - if (!*rbd_dev->spec->pool_name)
> + if (!*spec->pool_name)
> goto out_err; /* Missing pool name */
>
> - rbd_dev->spec->image_name =
> - dup_token(&buf, &rbd_dev->spec->image_name_len);
> - if (!rbd_dev->spec->image_name)
> + spec->image_name = dup_token(&buf, &spec->image_name_len);
> + if (!spec->image_name)
> goto out_mem;
> - if (!*rbd_dev->spec->image_name)
> + if (!*spec->image_name)
> goto out_err; /* Missing image name */
>
> /*
> @@ -2949,11 +2984,11 @@ static int rbd_add_parse_args(struct rbd_device
> *rbd_dev,
> ret = -ENAMETOOLONG;
> goto out_err;
> }
> - rbd_dev->spec->snap_name = kmalloc(len + 1, GFP_KERNEL);
> - if (!rbd_dev->spec->snap_name)
> + spec->snap_name = kmalloc(len + 1, GFP_KERNEL);
> + if (!spec->snap_name)
> goto out_mem;
> - memcpy(rbd_dev->spec->snap_name, buf, len);
> - *(rbd_dev->spec->snap_name + len) = '\0';
> + memcpy(spec->snap_name, buf, len);
> + *(spec->snap_name + len) = '\0';
>
> /* Initialize all rbd options to the defaults */
>
> @@ -2973,15 +3008,15 @@ static int rbd_add_parse_args(struct rbd_device
> *rbd_dev,
> }
> *opts = rbd_opts;
>
> + *rbd_spec = spec;
> +
> return 0;
> out_mem:
> ret = -ENOMEM;
> + kfree(spec->image_name);
> + kfree(spec->pool_name);
> + kfree(spec);
This is missing spec->snap_name. Why not use rbd_spec_put()?
> out_err:
> - kfree(rbd_dev->spec->image_name);
> - rbd_dev->spec->image_name = NULL;
> - rbd_dev->spec->image_name_len = 0;
> - kfree(rbd_dev->spec->pool_name);
> - rbd_dev->spec->pool_name = NULL;
> kfree(options);
>
> return ret;
> @@ -3195,6 +3230,7 @@ static ssize_t rbd_add(struct bus_type *bus,
> struct rbd_device *rbd_dev = NULL;
> struct ceph_options *ceph_opts = NULL;
> struct rbd_options *rbd_opts = NULL;
> + struct rbd_spec *spec = NULL;
> struct ceph_osd_client *osdc;
> int rc = -ENOMEM;
>
> @@ -3204,9 +3240,6 @@ static ssize_t rbd_add(struct bus_type *bus,
> rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
> if (!rbd_dev)
> return -ENOMEM;
> - rbd_dev->spec = rbd_spec_alloc();
> - if (!rbd_dev->spec)
> - goto err_out_mem;
>
> /* static rbd_device initialization */
> spin_lock_init(&rbd_dev->lock);
> @@ -3215,9 +3248,10 @@ static ssize_t rbd_add(struct bus_type *bus,
> init_rwsem(&rbd_dev->header_rwsem);
>
> /* parse add command */
> - rc = rbd_add_parse_args(rbd_dev, buf, &ceph_opts, &rbd_opts);
> + rc = rbd_add_parse_args(buf, &ceph_opts, &rbd_opts, &spec);
> if (rc < 0)
> goto err_out_mem;
> +
> rbd_dev->mapping.read_only = rbd_opts->read_only;
>
> rc = rbd_get_client(rbd_dev, ceph_opts);
> @@ -3227,10 +3261,12 @@ static ssize_t rbd_add(struct bus_type *bus,
>
> /* pick the pool */
> osdc = &rbd_dev->rbd_client->client->osdc;
> - rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->spec->pool_name);
> + rc = ceph_pg_poolid_by_name(osdc->osdmap, spec->pool_name);
> if (rc < 0)
> goto err_out_client;
> - rbd_dev->spec->pool_id = (u64) rc;
> + spec->pool_id = (u64) rc;
> +
> + rbd_dev->spec = spec;
>
> rc = rbd_dev_probe(rbd_dev);
> if (rc < 0)
> @@ -3321,8 +3357,8 @@ err_out_args:
> if (ceph_opts)
> ceph_destroy_options(ceph_opts);
> kfree(rbd_opts);
> + rbd_spec_put(spec);
> err_out_mem:
> - rbd_spec_put(rbd_dev->spec);
> kfree(rbd_dev);
>
> dout("Error adding device %s\n", buf);
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 8/8] rbd: fill rbd_spec in rbd_add_parse_args()
2012-10-29 22:30 ` Josh Durgin
@ 2012-10-30 13:09 ` Alex Elder
2012-10-30 20:18 ` Josh Durgin
0 siblings, 1 reply; 41+ messages in thread
From: Alex Elder @ 2012-10-30 13:09 UTC (permalink / raw)
To: Josh Durgin; +Cc: ceph-devel
On 10/29/2012 05:30 PM, Josh Durgin wrote:
> On 10/26/2012 04:03 PM, Alex Elder wrote:
>> Pass the address of an rbd_spec structure to rbd_add_parse_args().
>> Use it to hold the information defining the rbd image to be mapped
>> in an rbd_add() call.
>>
>> Use the result in the caller to initialize the rbd_dev->id field.
>>
>> This means rbd_dev is no longer needed in rbd_add_parse_args(),
>> so get rid of it.
>>
>> Now that this transformation of rbd_add_parse_args() is complete,
>> correct and expand on the its header documentation to reflect the
>> new reality.
>>
>> Signed-off-by: Alex Elder <elder@inktank.com>
>> ---
>> drivers/block/rbd.c | 104
>> ++++++++++++++++++++++++++++++++++-----------------
>> 1 file changed, 70 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>> index 19c7c6b..28abd31 100644
>> --- a/drivers/block/rbd.c
>> +++ b/drivers/block/rbd.c
. . .
>> @@ -2973,15 +3008,15 @@ static int rbd_add_parse_args(struct rbd_device
>> *rbd_dev,
>> }
>> *opts = rbd_opts;
>>
>> + *rbd_spec = spec;
>> +
>> return 0;
>> out_mem:
>> ret = -ENOMEM;
>> + kfree(spec->image_name);
>> + kfree(spec->pool_name);
>> + kfree(spec);
>
> This is missing spec->snap_name. Why not use rbd_spec_put()?
You're right, and you're right. It was an oversight. I'll fix
that. Do you want me to repost?
In keeping with some of your previous comments I have also added
a note to include in a future patch messages about why a map
request failed in rbd_add() via a log message.
-Alex
>> out_err:
>> - kfree(rbd_dev->spec->image_name);
>> - rbd_dev->spec->image_name = NULL;
>> - rbd_dev->spec->image_name_len = 0;
>> - kfree(rbd_dev->spec->pool_name);
>> - rbd_dev->spec->pool_name = NULL;
>> kfree(options);
>>
. . .
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 8/8] rbd: fill rbd_spec in rbd_add_parse_args()
2012-10-30 13:09 ` Alex Elder
@ 2012-10-30 20:18 ` Josh Durgin
0 siblings, 0 replies; 41+ messages in thread
From: Josh Durgin @ 2012-10-30 20:18 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
On 10/30/2012 06:09 AM, Alex Elder wrote:
> On 10/29/2012 05:30 PM, Josh Durgin wrote:
>> On 10/26/2012 04:03 PM, Alex Elder wrote:
>>> Pass the address of an rbd_spec structure to rbd_add_parse_args().
>>> Use it to hold the information defining the rbd image to be mapped
>>> in an rbd_add() call.
>>>
>>> Use the result in the caller to initialize the rbd_dev->id field.
>>>
>>> This means rbd_dev is no longer needed in rbd_add_parse_args(),
>>> so get rid of it.
>>>
>>> Now that this transformation of rbd_add_parse_args() is complete,
>>> correct and expand on the its header documentation to reflect the
>>> new reality.
>>>
>>> Signed-off-by: Alex Elder <elder@inktank.com>
>>> ---
>>> drivers/block/rbd.c | 104
>>> ++++++++++++++++++++++++++++++++++-----------------
>>> 1 file changed, 70 insertions(+), 34 deletions(-)
>>>
>>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>>> index 19c7c6b..28abd31 100644
>>> --- a/drivers/block/rbd.c
>>> +++ b/drivers/block/rbd.c
>
> . . .
>
>>> @@ -2973,15 +3008,15 @@ static int rbd_add_parse_args(struct rbd_device
>>> *rbd_dev,
>>> }
>>> *opts = rbd_opts;
>>>
>>> + *rbd_spec = spec;
>>> +
>>> return 0;
>>> out_mem:
>>> ret = -ENOMEM;
>>> + kfree(spec->image_name);
>>> + kfree(spec->pool_name);
>>> + kfree(spec);
>>
>> This is missing spec->snap_name. Why not use rbd_spec_put()?
>
> You're right, and you're right. It was an oversight. I'll fix
> that. Do you want me to repost?
No, the change is trivial enough. You can add my reviewed-by with that.
> In keeping with some of your previous comments I have also added
> a note to include in a future patch messages about why a map
> request failed in rbd_add() via a log message.
Sounds good.
>
> -Alex
>
>>> out_err:
>>> - kfree(rbd_dev->spec->image_name);
>>> - rbd_dev->spec->image_name = NULL;
>>> - rbd_dev->spec->image_name_len = 0;
>>> - kfree(rbd_dev->spec->pool_name);
>>> - rbd_dev->spec->pool_name = NULL;
>>> kfree(options);
>>>
> . . .
^ permalink raw reply [flat|nested] 41+ messages in thread