You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
drbd: perpare for genetlink parallel_ops
Because all administrative requests via genetlink have been globally serialized via genl_lock(), we used to have one static struct drbd_config_context "admin context". Move this on-stack to the respective callback functions. This will allow us to selectively drop the genl_lock() (or use genl_family->parallel_ops) in the future. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
committed by
Jens Axboe
parent
88ea685d33
commit
a910b12352
@@ -814,6 +814,28 @@ struct drbd_device {
|
||||
struct submit_worker submit;
|
||||
};
|
||||
|
||||
struct drbd_config_context {
|
||||
/* assigned from drbd_genlmsghdr */
|
||||
unsigned int minor;
|
||||
/* assigned from request attributes, if present */
|
||||
unsigned int volume;
|
||||
#define VOLUME_UNSPECIFIED (-1U)
|
||||
/* pointer into the request skb,
|
||||
* limited lifetime! */
|
||||
char *resource_name;
|
||||
struct nlattr *my_addr;
|
||||
struct nlattr *peer_addr;
|
||||
|
||||
/* reply buffer */
|
||||
struct sk_buff *reply_skb;
|
||||
/* pointer into reply buffer */
|
||||
struct drbd_genlmsghdr *reply_dh;
|
||||
/* resolved from attributes, if possible */
|
||||
struct drbd_device *device;
|
||||
struct drbd_resource *resource;
|
||||
struct drbd_connection *connection;
|
||||
};
|
||||
|
||||
static inline struct drbd_device *minor_to_device(unsigned int minor)
|
||||
{
|
||||
return (struct drbd_device *)idr_find(&drbd_devices, minor);
|
||||
@@ -1229,9 +1251,9 @@ extern struct bio *bio_alloc_drbd(gfp_t gfp_mask);
|
||||
extern rwlock_t global_state_lock;
|
||||
|
||||
extern int conn_lowest_minor(struct drbd_connection *connection);
|
||||
enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr);
|
||||
extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor);
|
||||
extern void drbd_destroy_device(struct kref *kref);
|
||||
extern void drbd_delete_device(struct drbd_device *mdev);
|
||||
extern void drbd_delete_device(struct drbd_device *device);
|
||||
|
||||
extern struct drbd_resource *drbd_create_resource(const char *name);
|
||||
extern void drbd_free_resource(struct drbd_resource *resource);
|
||||
@@ -1257,7 +1279,7 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t);
|
||||
|
||||
|
||||
/* drbd_nl.c */
|
||||
extern int drbd_msg_put_info(const char *info);
|
||||
extern int drbd_msg_put_info(struct sk_buff *skb, const char *info);
|
||||
extern void drbd_suspend_io(struct drbd_device *device);
|
||||
extern void drbd_resume_io(struct drbd_device *device);
|
||||
extern char *ppsize(char *buf, unsigned long long size);
|
||||
|
||||
@@ -2687,14 +2687,16 @@ static int init_submitter(struct drbd_device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr)
|
||||
enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor)
|
||||
{
|
||||
struct drbd_resource *resource = adm_ctx->resource;
|
||||
struct drbd_connection *connection;
|
||||
struct drbd_device *device;
|
||||
struct drbd_peer_device *peer_device, *tmp_peer_device;
|
||||
struct gendisk *disk;
|
||||
struct request_queue *q;
|
||||
int id;
|
||||
int vnr = adm_ctx->volume;
|
||||
enum drbd_ret_code err = ERR_NOMEM;
|
||||
|
||||
device = minor_to_device(minor);
|
||||
@@ -2763,7 +2765,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
|
||||
if (id < 0) {
|
||||
if (id == -ENOSPC) {
|
||||
err = ERR_MINOR_EXISTS;
|
||||
drbd_msg_put_info("requested minor exists already");
|
||||
drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already");
|
||||
}
|
||||
goto out_no_minor_idr;
|
||||
}
|
||||
@@ -2773,7 +2775,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
|
||||
if (id < 0) {
|
||||
if (id == -ENOSPC) {
|
||||
err = ERR_MINOR_EXISTS;
|
||||
drbd_msg_put_info("requested minor exists already");
|
||||
drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already");
|
||||
}
|
||||
goto out_idr_remove_minor;
|
||||
}
|
||||
@@ -2794,7 +2796,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
|
||||
if (id < 0) {
|
||||
if (id == -ENOSPC) {
|
||||
err = ERR_INVALID_REQUEST;
|
||||
drbd_msg_put_info("requested volume exists already");
|
||||
drbd_msg_put_info(adm_ctx->reply_skb, "requested volume exists already");
|
||||
}
|
||||
goto out_idr_remove_from_resource;
|
||||
}
|
||||
@@ -2803,7 +2805,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned i
|
||||
|
||||
if (init_submitter(device)) {
|
||||
err = ERR_NOMEM;
|
||||
drbd_msg_put_info("unable to create submit workqueue");
|
||||
drbd_msg_put_info(adm_ctx->reply_skb, "unable to create submit workqueue");
|
||||
goto out_idr_remove_vol;
|
||||
}
|
||||
|
||||
|
||||
+166
-167
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user