Skip to content

Commit

Permalink
rbd: don't allocate mon_addrs buffer in rbd_add()
Browse files Browse the repository at this point in the history
The mon_addrs buffer in rbd_add is used to hold a copy of the
monitor IP addresses supplied via /sys/bus/rbd/add.  That is
passed to rbd_get_client(), which never modifies it (nor do
any of the functions it gets passed to thereafter)--the mon_addr
parameter to rbd_get_client() is a pointer to constant data, so it
can't be modifed.  Furthermore, rbd_get_client() has the length of
the mon_addrs buffer and that is used to ensure nothing goes beyond
its end.

Based on all this, there is no reason that a buffer needs to
be used to hold a copy of the mon_addrs provided via
/sys/bus/rbd/add.   Instead, the location within that passed-in
buffer can be provided, along with the length of the "token"
therein which represents the monitor IP's.

A small change to rbd_add_parse_args() allows the address within the
buffer to be passed back, and the length is already returned.  This
now means that, at least from the perspective of this interface,
there is no such thing as a list of monitor addresses that is too
long.

Signed-off-by: Alex Elder <elder@dreamhost.com>
  • Loading branch information
Alex Elder committed Mar 22, 2012
1 parent 5214ecc commit 7ef3214
Showing 1 changed file with 9 additions and 12 deletions.
21 changes: 9 additions & 12 deletions drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2284,7 +2284,7 @@ static inline size_t copy_token(const char **buf,
*/
static int rbd_add_parse_args(struct rbd_device *rbd_dev,
const char *buf,
char *mon_addrs,
const char **mon_addrs,
size_t *mon_addrs_size,
char *options,
size_t options_size)
Expand All @@ -2293,10 +2293,13 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev,

/* The first four tokens are required */

len = copy_token(&buf, mon_addrs, *mon_addrs_size);
if (!len || len >= *mon_addrs_size)
len = next_token(&buf);
if (!len)
return -EINVAL;
*mon_addrs_size = len + 1;
*mon_addrs = buf;

buf += len;

len = copy_token(&buf, options, options_size);
if (!len || len >= options_size)
Expand Down Expand Up @@ -2337,8 +2340,8 @@ static ssize_t rbd_add(struct bus_type *bus,
size_t count)
{
struct rbd_device *rbd_dev;
char *mon_addrs = NULL;
size_t mon_addrs_size;
const char *mon_addrs = NULL;
size_t mon_addrs_size = 0;
char *options = NULL;
struct ceph_osd_client *osdc;
int rc = -ENOMEM;
Expand All @@ -2349,9 +2352,6 @@ static ssize_t rbd_add(struct bus_type *bus,
rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
if (!rbd_dev)
goto err_nomem;
mon_addrs = kmalloc(count, GFP_KERNEL);
if (!mon_addrs)
goto err_nomem;
options = kmalloc(count, GFP_KERNEL);
if (!options)
goto err_nomem;
Expand All @@ -2372,8 +2372,7 @@ static ssize_t rbd_add(struct bus_type *bus,
sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->id);

/* parse add command */
mon_addrs_size = count;
rc = rbd_add_parse_args(rbd_dev, buf, mon_addrs, &mon_addrs_size,
rc = rbd_add_parse_args(rbd_dev, buf, &mon_addrs, &mon_addrs_size,
options, count);
if (rc)
goto err_put_id;
Expand Down Expand Up @@ -2420,7 +2419,6 @@ static ssize_t rbd_add(struct bus_type *bus,

rbd_bus_del_dev(rbd_dev);
kfree(options);
kfree(mon_addrs);
return rc;

err_out_blkdev:
Expand All @@ -2431,7 +2429,6 @@ static ssize_t rbd_add(struct bus_type *bus,
rbd_id_put(rbd_dev);
err_nomem:
kfree(options);
kfree(mon_addrs);
kfree(rbd_dev);

dout("Error adding device %s\n", buf);
Expand Down

0 comments on commit 7ef3214

Please sign in to comment.