aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Elder <elder@dreamhost.com>2012-02-02 09:13:30 -0500
committerAlex Elder <elder@dreamhost.com>2012-03-22 11:47:50 -0400
commit7ef3214af220515b8fe223ec92ec017d2e5607a7 (patch)
tree74911dc83a10f824d0e2cbd83896bb32b0fc566b /drivers
parent5214ecc45cf9b9f1365b189bcb63e441e3865334 (diff)
rbd: don't allocate mon_addrs buffer in rbd_add()
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/rbd.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 2f2d194ca3d4..641f09898e19 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2284,7 +2284,7 @@ static inline size_t copy_token(const char **buf,
2284 */ 2284 */
2285static int rbd_add_parse_args(struct rbd_device *rbd_dev, 2285static int rbd_add_parse_args(struct rbd_device *rbd_dev,
2286 const char *buf, 2286 const char *buf,
2287 char *mon_addrs, 2287 const char **mon_addrs,
2288 size_t *mon_addrs_size, 2288 size_t *mon_addrs_size,
2289 char *options, 2289 char *options,
2290 size_t options_size) 2290 size_t options_size)
@@ -2293,10 +2293,13 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev,
2293 2293
2294 /* The first four tokens are required */ 2294 /* The first four tokens are required */
2295 2295
2296 len = copy_token(&buf, mon_addrs, *mon_addrs_size); 2296 len = next_token(&buf);
2297 if (!len || len >= *mon_addrs_size) 2297 if (!len)
2298 return -EINVAL; 2298 return -EINVAL;
2299 *mon_addrs_size = len + 1; 2299 *mon_addrs_size = len + 1;
2300 *mon_addrs = buf;
2301
2302 buf += len;
2300 2303
2301 len = copy_token(&buf, options, options_size); 2304 len = copy_token(&buf, options, options_size);
2302 if (!len || len >= options_size) 2305 if (!len || len >= options_size)
@@ -2337,8 +2340,8 @@ static ssize_t rbd_add(struct bus_type *bus,
2337 size_t count) 2340 size_t count)
2338{ 2341{
2339 struct rbd_device *rbd_dev; 2342 struct rbd_device *rbd_dev;
2340 char *mon_addrs = NULL; 2343 const char *mon_addrs = NULL;
2341 size_t mon_addrs_size; 2344 size_t mon_addrs_size = 0;
2342 char *options = NULL; 2345 char *options = NULL;
2343 struct ceph_osd_client *osdc; 2346 struct ceph_osd_client *osdc;
2344 int rc = -ENOMEM; 2347 int rc = -ENOMEM;
@@ -2349,9 +2352,6 @@ static ssize_t rbd_add(struct bus_type *bus,
2349 rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); 2352 rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
2350 if (!rbd_dev) 2353 if (!rbd_dev)
2351 goto err_nomem; 2354 goto err_nomem;
2352 mon_addrs = kmalloc(count, GFP_KERNEL);
2353 if (!mon_addrs)
2354 goto err_nomem;
2355 options = kmalloc(count, GFP_KERNEL); 2355 options = kmalloc(count, GFP_KERNEL);
2356 if (!options) 2356 if (!options)
2357 goto err_nomem; 2357 goto err_nomem;
@@ -2372,8 +2372,7 @@ static ssize_t rbd_add(struct bus_type *bus,
2372 sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->id); 2372 sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->id);
2373 2373
2374 /* parse add command */ 2374 /* parse add command */
2375 mon_addrs_size = count; 2375 rc = rbd_add_parse_args(rbd_dev, buf, &mon_addrs, &mon_addrs_size,
2376 rc = rbd_add_parse_args(rbd_dev, buf, mon_addrs, &mon_addrs_size,
2377 options, count); 2376 options, count);
2378 if (rc) 2377 if (rc)
2379 goto err_put_id; 2378 goto err_put_id;
@@ -2420,7 +2419,6 @@ err_out_bus:
2420 2419
2421 rbd_bus_del_dev(rbd_dev); 2420 rbd_bus_del_dev(rbd_dev);
2422 kfree(options); 2421 kfree(options);
2423 kfree(mon_addrs);
2424 return rc; 2422 return rc;
2425 2423
2426err_out_blkdev: 2424err_out_blkdev:
@@ -2431,7 +2429,6 @@ err_put_id:
2431 rbd_id_put(rbd_dev); 2429 rbd_id_put(rbd_dev);
2432err_nomem: 2430err_nomem:
2433 kfree(options); 2431 kfree(options);
2434 kfree(mon_addrs);
2435 kfree(rbd_dev); 2432 kfree(rbd_dev);
2436 2433
2437 dout("Error adding device %s\n", buf); 2434 dout("Error adding device %s\n", buf);