Skip to content

Commit

Permalink
drbd: Preparing the connector interface to operator on connections
Browse files Browse the repository at this point in the history
Up to now it only operated on minor numbers. Now it can work also
on named connections.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
  • Loading branch information
Philipp Reisner committed Oct 14, 2011
1 parent 2f5cdd0 commit 1aba4d7
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 37 deletions.
1 change: 1 addition & 0 deletions drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,7 @@ extern void drbd_free_mdev(struct drbd_conf *mdev);

struct drbd_tconn *drbd_new_tconn(char *name);
extern void drbd_free_tconn(struct drbd_tconn *tconn);
struct drbd_tconn *conn_by_name(const char *name);

extern int proc_details;

Expand Down
15 changes: 15 additions & 0 deletions drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2196,6 +2196,21 @@ static void drbd_init_workqueue(struct drbd_work_queue* wq)
INIT_LIST_HEAD(&wq->q);
}

struct drbd_tconn *conn_by_name(const char *name)
{
struct drbd_tconn *tconn;

write_lock_irq(&global_state_lock);
list_for_each_entry(tconn, &drbd_tconns, all_tconn) {
if (!strcmp(tconn->name, name))
goto found;
}
tconn = NULL;
found:
write_unlock_irq(&global_state_lock);
return tconn;
}

struct drbd_tconn *drbd_new_tconn(char *name)
{
struct drbd_tconn *tconn;
Expand Down
96 changes: 63 additions & 33 deletions drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2184,42 +2184,57 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
return 0;
}

enum cn_handler_type {
CHT_MINOR,
CHT_CONN,
CHT_CTOR,
/* CHT_RES, later */
};

struct cn_handler_struct {
int (*function)(struct drbd_conf *,
struct drbd_nl_cfg_req *,
struct drbd_nl_cfg_reply *);
enum cn_handler_type type;
union {
int (*minor_based)(struct drbd_conf *,
struct drbd_nl_cfg_req *,
struct drbd_nl_cfg_reply *);
int (*conn_based)(struct drbd_tconn *,
struct drbd_nl_cfg_req *,
struct drbd_nl_cfg_reply *);
int (*constructor)(struct drbd_nl_cfg_req *,
struct drbd_nl_cfg_reply *);
};
int reply_body_size;
};

static struct cn_handler_struct cnd_table[] = {
[ P_primary ] = { &drbd_nl_primary, 0 },
[ P_secondary ] = { &drbd_nl_secondary, 0 },
[ P_disk_conf ] = { &drbd_nl_disk_conf, 0 },
[ P_detach ] = { &drbd_nl_detach, 0 },
[ P_net_conf ] = { &drbd_nl_net_conf, 0 },
[ P_disconnect ] = { &drbd_nl_disconnect, 0 },
[ P_resize ] = { &drbd_nl_resize, 0 },
[ P_syncer_conf ] = { &drbd_nl_syncer_conf, 0 },
[ P_invalidate ] = { &drbd_nl_invalidate, 0 },
[ P_invalidate_peer ] = { &drbd_nl_invalidate_peer, 0 },
[ P_pause_sync ] = { &drbd_nl_pause_sync, 0 },
[ P_resume_sync ] = { &drbd_nl_resume_sync, 0 },
[ P_suspend_io ] = { &drbd_nl_suspend_io, 0 },
[ P_resume_io ] = { &drbd_nl_resume_io, 0 },
[ P_outdate ] = { &drbd_nl_outdate, 0 },
[ P_get_config ] = { &drbd_nl_get_config,
[ P_primary ] = { CHT_MINOR, { &drbd_nl_primary }, 0 },
[ P_secondary ] = { CHT_MINOR, { &drbd_nl_secondary }, 0 },
[ P_disk_conf ] = { CHT_MINOR, { &drbd_nl_disk_conf }, 0 },
[ P_detach ] = { CHT_MINOR, { &drbd_nl_detach }, 0 },
[ P_net_conf ] = { CHT_MINOR, { &drbd_nl_net_conf }, 0 },
[ P_disconnect ] = { CHT_MINOR, { &drbd_nl_disconnect }, 0 },
[ P_resize ] = { CHT_MINOR, { &drbd_nl_resize }, 0 },
[ P_syncer_conf ] = { CHT_MINOR, { &drbd_nl_syncer_conf },0 },
[ P_invalidate ] = { CHT_MINOR, { &drbd_nl_invalidate }, 0 },
[ P_invalidate_peer ] = { CHT_MINOR, { &drbd_nl_invalidate_peer },0 },
[ P_pause_sync ] = { CHT_MINOR, { &drbd_nl_pause_sync }, 0 },
[ P_resume_sync ] = { CHT_MINOR, { &drbd_nl_resume_sync },0 },
[ P_suspend_io ] = { CHT_MINOR, { &drbd_nl_suspend_io }, 0 },
[ P_resume_io ] = { CHT_MINOR, { &drbd_nl_resume_io }, 0 },
[ P_outdate ] = { CHT_MINOR, { &drbd_nl_outdate }, 0 },
[ P_get_config ] = { CHT_MINOR, { &drbd_nl_get_config },
sizeof(struct syncer_conf_tag_len_struct) +
sizeof(struct disk_conf_tag_len_struct) +
sizeof(struct net_conf_tag_len_struct) },
[ P_get_state ] = { &drbd_nl_get_state,
[ P_get_state ] = { CHT_MINOR, { &drbd_nl_get_state },
sizeof(struct get_state_tag_len_struct) +
sizeof(struct sync_progress_tag_len_struct) },
[ P_get_uuids ] = { &drbd_nl_get_uuids,
[ P_get_uuids ] = { CHT_MINOR, { &drbd_nl_get_uuids },
sizeof(struct get_uuids_tag_len_struct) },
[ P_get_timeout_flag ] = { &drbd_nl_get_timeout_flag,
[ P_get_timeout_flag ] = { CHT_MINOR, { &drbd_nl_get_timeout_flag },
sizeof(struct get_timeout_flag_tag_len_struct)},
[ P_start_ov ] = { &drbd_nl_start_ov, 0 },
[ P_new_c_uuid ] = { &drbd_nl_new_c_uuid, 0 },
[ P_start_ov ] = { CHT_MINOR, { &drbd_nl_start_ov }, 0 },
[ P_new_c_uuid ] = { CHT_MINOR, { &drbd_nl_new_c_uuid }, 0 },
};

static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms *nsp)
Expand All @@ -2229,6 +2244,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
struct cn_msg *cn_reply;
struct drbd_nl_cfg_reply *reply;
struct drbd_conf *mdev;
struct drbd_tconn *tconn;
int retcode, rr;
int reply_size = sizeof(struct cn_msg)
+ sizeof(struct drbd_nl_cfg_reply)
Expand All @@ -2244,13 +2260,6 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
goto fail;
}

mdev = ensure_mdev(nlp->drbd_minor,
(nlp->flags & DRBD_NL_CREATE_DEVICE));
if (!mdev) {
retcode = ERR_MINOR_INVALID;
goto fail;
}

if (nlp->packet_type >= P_nl_after_last_packet ||
nlp->packet_type == P_return_code_only) {
retcode = ERR_PACKET_NR;
Expand All @@ -2260,7 +2269,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
cm = cnd_table + nlp->packet_type;

/* This may happen if packet number is 0: */
if (cm->function == NULL) {
if (cm->minor_based == NULL) {
retcode = ERR_PACKET_NR;
goto fail;
}
Expand All @@ -2281,7 +2290,28 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
reply->ret_code = NO_ERROR; /* Might by modified by cm->function. */
/* reply->tag_list; might be modified by cm->function. */

rr = cm->function(mdev, nlp, reply);
retcode = ERR_MINOR_INVALID;
rr = 0;
switch (cm->type) {
case CHT_MINOR:
mdev = minor_to_mdev(nlp->drbd_minor);
if (!mdev)
goto fail;
rr = cm->minor_based(mdev, nlp, reply);
break;
case CHT_CONN:
tconn = conn_by_name(nlp->obj_name);
if (!tconn) {
retcode = ERR_CONN_NOT_KNOWN;
goto fail;
}
rr = cm->conn_based(tconn, nlp, reply);
break;
case CHT_CTOR:
rr = cm->constructor(nlp, reply);
break;
/* case CHT_RES: */
}

cn_reply->id = req->id;
cn_reply->seq = req->seq;
Expand Down
19 changes: 15 additions & 4 deletions include/linux/drbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ enum drbd_ret_code {
ERR_CONG_NOT_PROTO_A = 155,
ERR_PIC_AFTER_DEP = 156,
ERR_PIC_PEER_DEP = 157,
ERR_CONN_NOT_KNOWN = 158,

/* insert new ones above this line */
AFTER_LAST_ERR_CODE
Expand Down Expand Up @@ -347,17 +348,27 @@ enum drbd_timeout_flag {

/* Start of the new netlink/connector stuff */

#define DRBD_NL_CREATE_DEVICE 0x01
#define DRBD_NL_SET_DEFAULTS 0x02
enum drbd_ncr_flags {
DRBD_NL_CREATE_DEVICE = 0x01,
DRBD_NL_SET_DEFAULTS = 0x02,
};
#define DRBD_NL_OBJ_NAME_LEN 32


/* For searching a vacant cn_idx value */
#define CN_IDX_STEP 6977

struct drbd_nl_cfg_req {
int packet_type;
unsigned int drbd_minor;
int flags;
union {
struct {
unsigned int drbd_minor;
enum drbd_ncr_flags flags;
};
struct {
char obj_name[DRBD_NL_OBJ_NAME_LEN];
};
};
unsigned short tag_list[];
};

Expand Down

0 comments on commit 1aba4d7

Please sign in to comment.