From afbbfa88bc506bc13b957c3811bce299de1d31d5 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 16 Jun 2011 17:58:02 +0200 Subject: [PATCH] drbd: Allow to pass resource options to the new-resource command This is equivalent to how the attach and connect commands work. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 4 +-- drivers/block/drbd/drbd_main.c | 46 ++++++++++++++++++++++++++++-- drivers/block/drbd/drbd_nl.c | 51 +++++++++++----------------------- 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 6d6d1056d824..ece2e4a991fb 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1379,7 +1379,8 @@ extern int conn_lowest_minor(struct drbd_tconn *tconn); enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr); extern void drbd_minor_destroy(struct kref *kref); -struct drbd_tconn *conn_create(const char *name); +extern int set_resource_options(struct drbd_tconn *tconn, struct res_opts *res_opts); +extern struct drbd_tconn *conn_create(const char *name, struct res_opts *res_opts); extern void conn_destroy(struct kref *kref); struct drbd_tconn *conn_get_by_name(const char *name); extern struct drbd_tconn *conn_get_by_addrs(void *my_addr, int my_addr_len, @@ -1397,7 +1398,6 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t); /* drbd_nl.c */ -extern void drbd_set_res_opts_defaults(struct res_opts *r); extern int drbd_msg_put_info(const char *info); extern void drbd_suspend_io(struct drbd_conf *mdev); extern void drbd_resume_io(struct drbd_conf *mdev); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 79f275dc43a4..933d4767c110 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2479,8 +2479,47 @@ void conn_free_crypto(struct drbd_tconn *tconn) tconn->int_dig_vv = NULL; } +int set_resource_options(struct drbd_tconn *tconn, struct res_opts *res_opts) +{ + cpumask_var_t new_cpu_mask; + int err; + + if (!zalloc_cpumask_var(&new_cpu_mask, GFP_KERNEL)) + return -ENOMEM; + /* + retcode = ERR_NOMEM; + drbd_msg_put_info("unable to allocate cpumask"); + */ + + /* silently ignore cpu mask on UP kernel */ + if (nr_cpu_ids > 1 && res_opts->cpu_mask[0] != 0) { + /* FIXME: Get rid of constant 32 here */ + err = __bitmap_parse(res_opts->cpu_mask, 32, 0, + cpumask_bits(new_cpu_mask), nr_cpu_ids); + if (err) { + conn_warn(tconn, "__bitmap_parse() failed with %d\n", err); + /* retcode = ERR_CPU_MASK_PARSE; */ + goto fail; + } + } + tconn->res_opts = *res_opts; + if (!cpumask_equal(tconn->cpu_mask, new_cpu_mask)) { + cpumask_copy(tconn->cpu_mask, new_cpu_mask); + drbd_calc_cpu_mask(tconn); + tconn->receiver.reset_cpu_mask = 1; + tconn->asender.reset_cpu_mask = 1; + tconn->worker.reset_cpu_mask = 1; + } + err = 0; + +fail: + free_cpumask_var(new_cpu_mask); + return err; + +} + /* caller must be under genl_lock() */ -struct drbd_tconn *conn_create(const char *name) +struct drbd_tconn *conn_create(const char *name, struct res_opts *res_opts) { struct drbd_tconn *tconn; @@ -2500,6 +2539,9 @@ struct drbd_tconn *conn_create(const char *name) if (!zalloc_cpumask_var(&tconn->cpu_mask, GFP_KERNEL)) goto fail; + if (set_resource_options(tconn, res_opts)) + goto fail; + if (!tl_init(tconn)) goto fail; @@ -2520,8 +2562,6 @@ struct drbd_tconn *conn_create(const char *name) drbd_thread_init(tconn, &tconn->worker, drbd_worker, "worker"); drbd_thread_init(tconn, &tconn->asender, drbd_asender, "asender"); - drbd_set_res_opts_defaults(&tconn->res_opts); - kref_init(&tconn->kref); list_add_tail_rcu(&tconn->all_tconn, &drbd_tconns); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index e7933e04e7b8..930af5dbfa76 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -2335,15 +2335,9 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) return 0; } -void drbd_set_res_opts_defaults(struct res_opts *r) -{ - return set_res_opts_defaults(r); -} - int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info) { enum drbd_ret_code retcode; - cpumask_var_t new_cpu_mask; struct drbd_tconn *tconn; struct res_opts res_opts; int err; @@ -2355,12 +2349,6 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info) goto fail; tconn = adm_ctx.tconn; - if (!zalloc_cpumask_var(&new_cpu_mask, GFP_KERNEL)) { - retcode = ERR_NOMEM; - drbd_msg_put_info("unable to allocate cpumask"); - goto fail; - } - res_opts = tconn->res_opts; if (should_set_defaults(info)) set_res_opts_defaults(&res_opts); @@ -2372,31 +2360,14 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info) goto fail; } - /* silently ignore cpu mask on UP kernel */ - if (nr_cpu_ids > 1 && res_opts.cpu_mask[0] != 0) { - err = __bitmap_parse(res_opts.cpu_mask, 32, 0, - cpumask_bits(new_cpu_mask), nr_cpu_ids); - if (err) { - conn_warn(tconn, "__bitmap_parse() failed with %d\n", err); - retcode = ERR_CPU_MASK_PARSE; - goto fail; - } - } - - - tconn->res_opts = res_opts; - - if (!cpumask_equal(tconn->cpu_mask, new_cpu_mask)) { - cpumask_copy(tconn->cpu_mask, new_cpu_mask); - drbd_calc_cpu_mask(tconn); - tconn->receiver.reset_cpu_mask = 1; - tconn->asender.reset_cpu_mask = 1; - tconn->worker.reset_cpu_mask = 1; + err = set_resource_options(tconn, &res_opts); + if (err) { + retcode = ERR_INVALID_REQUEST; + if (err == -ENOMEM) + retcode = ERR_NOMEM; } fail: - free_cpumask_var(new_cpu_mask); - drbd_adm_finish(info, retcode); return 0; } @@ -3012,6 +2983,8 @@ drbd_check_resource_name(const char *name) int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info) { enum drbd_ret_code retcode; + struct res_opts res_opts; + int err; retcode = drbd_adm_prepare(skb, info, 0); if (!adm_ctx.reply_skb) @@ -3019,6 +2992,14 @@ int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info) if (retcode != NO_ERROR) goto out; + set_res_opts_defaults(&res_opts); + err = res_opts_from_attrs(&res_opts, info); + if (err && err != -ENOMSG) { + retcode = ERR_MANDATORY_TAG; + drbd_msg_put_info(from_attrs_err_to_txt(err)); + goto out; + } + retcode = drbd_check_resource_name(adm_ctx.resource_name); if (retcode != NO_ERROR) goto out; @@ -3032,7 +3013,7 @@ int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info) goto out; } - if (!conn_create(adm_ctx.resource_name)) + if (!conn_create(adm_ctx.resource_name, &res_opts)) retcode = ERR_NOMEM; out: drbd_adm_finish(info, retcode); -- 2.20.1