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)
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)
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;
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;
}
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;