提交 f1b45d8c 编写于 作者: L Linus Torvalds

Merge tag 'block-5.18-2022-04-08' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
 "Nothing major in here, just a few small fixes:

   - Small series of neglected drbd patches (Christoph, Lv, Xiaomeng)

   - Remove dead variable in cdrom (Enze)"

* tag 'block-5.18-2022-04-08' of git://git.kernel.dk/linux-block:
  drbd: set QUEUE_FLAG_STABLE_WRITES
  drbd: fix an invalid memory access caused by incorrect use of list iterator
  drbd: Fix five use after free bugs in get_initial_state
  cdrom: remove unused variable
...@@ -1638,22 +1638,22 @@ struct sib_info { ...@@ -1638,22 +1638,22 @@ struct sib_info {
}; };
void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib); void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib);
extern void notify_resource_state(struct sk_buff *, extern int notify_resource_state(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_resource *, struct drbd_resource *,
struct resource_info *, struct resource_info *,
enum drbd_notification_type); enum drbd_notification_type);
extern void notify_device_state(struct sk_buff *, extern int notify_device_state(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_device *, struct drbd_device *,
struct device_info *, struct device_info *,
enum drbd_notification_type); enum drbd_notification_type);
extern void notify_connection_state(struct sk_buff *, extern int notify_connection_state(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_connection *, struct drbd_connection *,
struct connection_info *, struct connection_info *,
enum drbd_notification_type); enum drbd_notification_type);
extern void notify_peer_device_state(struct sk_buff *, extern int notify_peer_device_state(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_peer_device *, struct drbd_peer_device *,
struct peer_device_info *, struct peer_device_info *,
......
...@@ -2719,6 +2719,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig ...@@ -2719,6 +2719,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
sprintf(disk->disk_name, "drbd%d", minor); sprintf(disk->disk_name, "drbd%d", minor);
disk->private_data = device; disk->private_data = device;
blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, disk->queue);
blk_queue_write_cache(disk->queue, true, true); blk_queue_write_cache(disk->queue, true, true);
/* Setting the max_hw_sectors to an odd value of 8kibyte here /* Setting the max_hw_sectors to an odd value of 8kibyte here
This triggers a max_bio_size message upon first attach or connect */ This triggers a max_bio_size message upon first attach or connect */
...@@ -2773,12 +2774,12 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig ...@@ -2773,12 +2774,12 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
if (init_submitter(device)) { if (init_submitter(device)) {
err = ERR_NOMEM; err = ERR_NOMEM;
goto out_idr_remove_vol; goto out_idr_remove_from_resource;
} }
err = add_disk(disk); err = add_disk(disk);
if (err) if (err)
goto out_idr_remove_vol; goto out_idr_remove_from_resource;
/* inherit the connection state */ /* inherit the connection state */
device->state.conn = first_connection(resource)->cstate; device->state.conn = first_connection(resource)->cstate;
...@@ -2792,8 +2793,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig ...@@ -2792,8 +2793,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
drbd_debugfs_device_add(device); drbd_debugfs_device_add(device);
return NO_ERROR; return NO_ERROR;
out_idr_remove_vol:
idr_remove(&connection->peer_devices, vnr);
out_idr_remove_from_resource: out_idr_remove_from_resource:
for_each_connection(connection, resource) { for_each_connection(connection, resource) {
peer_device = idr_remove(&connection->peer_devices, vnr); peer_device = idr_remove(&connection->peer_devices, vnr);
......
...@@ -4549,7 +4549,7 @@ static int nla_put_notification_header(struct sk_buff *msg, ...@@ -4549,7 +4549,7 @@ static int nla_put_notification_header(struct sk_buff *msg,
return drbd_notification_header_to_skb(msg, &nh, true); return drbd_notification_header_to_skb(msg, &nh, true);
} }
void notify_resource_state(struct sk_buff *skb, int notify_resource_state(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_resource *resource, struct drbd_resource *resource,
struct resource_info *resource_info, struct resource_info *resource_info,
...@@ -4591,16 +4591,17 @@ void notify_resource_state(struct sk_buff *skb, ...@@ -4591,16 +4591,17 @@ void notify_resource_state(struct sk_buff *skb,
if (err && err != -ESRCH) if (err && err != -ESRCH)
goto failed; goto failed;
} }
return; return 0;
nla_put_failure: nla_put_failure:
nlmsg_free(skb); nlmsg_free(skb);
failed: failed:
drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n", drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n",
err, seq); err, seq);
return err;
} }
void notify_device_state(struct sk_buff *skb, int notify_device_state(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_device *device, struct drbd_device *device,
struct device_info *device_info, struct device_info *device_info,
...@@ -4640,16 +4641,17 @@ void notify_device_state(struct sk_buff *skb, ...@@ -4640,16 +4641,17 @@ void notify_device_state(struct sk_buff *skb,
if (err && err != -ESRCH) if (err && err != -ESRCH)
goto failed; goto failed;
} }
return; return 0;
nla_put_failure: nla_put_failure:
nlmsg_free(skb); nlmsg_free(skb);
failed: failed:
drbd_err(device, "Error %d while broadcasting event. Event seq:%u\n", drbd_err(device, "Error %d while broadcasting event. Event seq:%u\n",
err, seq); err, seq);
return err;
} }
void notify_connection_state(struct sk_buff *skb, int notify_connection_state(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_connection *connection, struct drbd_connection *connection,
struct connection_info *connection_info, struct connection_info *connection_info,
...@@ -4689,16 +4691,17 @@ void notify_connection_state(struct sk_buff *skb, ...@@ -4689,16 +4691,17 @@ void notify_connection_state(struct sk_buff *skb,
if (err && err != -ESRCH) if (err && err != -ESRCH)
goto failed; goto failed;
} }
return; return 0;
nla_put_failure: nla_put_failure:
nlmsg_free(skb); nlmsg_free(skb);
failed: failed:
drbd_err(connection, "Error %d while broadcasting event. Event seq:%u\n", drbd_err(connection, "Error %d while broadcasting event. Event seq:%u\n",
err, seq); err, seq);
return err;
} }
void notify_peer_device_state(struct sk_buff *skb, int notify_peer_device_state(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_peer_device *peer_device, struct drbd_peer_device *peer_device,
struct peer_device_info *peer_device_info, struct peer_device_info *peer_device_info,
...@@ -4739,13 +4742,14 @@ void notify_peer_device_state(struct sk_buff *skb, ...@@ -4739,13 +4742,14 @@ void notify_peer_device_state(struct sk_buff *skb,
if (err && err != -ESRCH) if (err && err != -ESRCH)
goto failed; goto failed;
} }
return; return 0;
nla_put_failure: nla_put_failure:
nlmsg_free(skb); nlmsg_free(skb);
failed: failed:
drbd_err(peer_device, "Error %d while broadcasting event. Event seq:%u\n", drbd_err(peer_device, "Error %d while broadcasting event. Event seq:%u\n",
err, seq); err, seq);
return err;
} }
void notify_helper(enum drbd_notification_type type, void notify_helper(enum drbd_notification_type type,
...@@ -4796,7 +4800,7 @@ void notify_helper(enum drbd_notification_type type, ...@@ -4796,7 +4800,7 @@ void notify_helper(enum drbd_notification_type type,
err, seq); err, seq);
} }
static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq) static int notify_initial_state_done(struct sk_buff *skb, unsigned int seq)
{ {
struct drbd_genlmsghdr *dh; struct drbd_genlmsghdr *dh;
int err; int err;
...@@ -4810,11 +4814,12 @@ static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq) ...@@ -4810,11 +4814,12 @@ static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq)
if (nla_put_notification_header(skb, NOTIFY_EXISTS)) if (nla_put_notification_header(skb, NOTIFY_EXISTS))
goto nla_put_failure; goto nla_put_failure;
genlmsg_end(skb, dh); genlmsg_end(skb, dh);
return; return 0;
nla_put_failure: nla_put_failure:
nlmsg_free(skb); nlmsg_free(skb);
pr_err("Error %d sending event. Event seq:%u\n", err, seq); pr_err("Error %d sending event. Event seq:%u\n", err, seq);
return err;
} }
static void free_state_changes(struct list_head *list) static void free_state_changes(struct list_head *list)
...@@ -4841,6 +4846,7 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -4841,6 +4846,7 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
unsigned int seq = cb->args[2]; unsigned int seq = cb->args[2];
unsigned int n; unsigned int n;
enum drbd_notification_type flags = 0; enum drbd_notification_type flags = 0;
int err = 0;
/* There is no need for taking notification_mutex here: it doesn't /* There is no need for taking notification_mutex here: it doesn't
matter if the initial state events mix with later state chage matter if the initial state events mix with later state chage
...@@ -4849,32 +4855,32 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -4849,32 +4855,32 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
cb->args[5]--; cb->args[5]--;
if (cb->args[5] == 1) { if (cb->args[5] == 1) {
notify_initial_state_done(skb, seq); err = notify_initial_state_done(skb, seq);
goto out; goto out;
} }
n = cb->args[4]++; n = cb->args[4]++;
if (cb->args[4] < cb->args[3]) if (cb->args[4] < cb->args[3])
flags |= NOTIFY_CONTINUES; flags |= NOTIFY_CONTINUES;
if (n < 1) { if (n < 1) {
notify_resource_state_change(skb, seq, state_change->resource, err = notify_resource_state_change(skb, seq, state_change->resource,
NOTIFY_EXISTS | flags); NOTIFY_EXISTS | flags);
goto next; goto next;
} }
n--; n--;
if (n < state_change->n_connections) { if (n < state_change->n_connections) {
notify_connection_state_change(skb, seq, &state_change->connections[n], err = notify_connection_state_change(skb, seq, &state_change->connections[n],
NOTIFY_EXISTS | flags); NOTIFY_EXISTS | flags);
goto next; goto next;
} }
n -= state_change->n_connections; n -= state_change->n_connections;
if (n < state_change->n_devices) { if (n < state_change->n_devices) {
notify_device_state_change(skb, seq, &state_change->devices[n], err = notify_device_state_change(skb, seq, &state_change->devices[n],
NOTIFY_EXISTS | flags); NOTIFY_EXISTS | flags);
goto next; goto next;
} }
n -= state_change->n_devices; n -= state_change->n_devices;
if (n < state_change->n_devices * state_change->n_connections) { if (n < state_change->n_devices * state_change->n_connections) {
notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], err = notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n],
NOTIFY_EXISTS | flags); NOTIFY_EXISTS | flags);
goto next; goto next;
} }
...@@ -4889,7 +4895,10 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -4889,7 +4895,10 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
cb->args[4] = 0; cb->args[4] = 0;
} }
out: out:
return skb->len; if (err)
return err;
else
return skb->len;
} }
int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
......
...@@ -1537,7 +1537,7 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device, ...@@ -1537,7 +1537,7 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device,
return rv; return rv;
} }
void notify_resource_state_change(struct sk_buff *skb, int notify_resource_state_change(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_resource_state_change *resource_state_change, struct drbd_resource_state_change *resource_state_change,
enum drbd_notification_type type) enum drbd_notification_type type)
...@@ -1550,10 +1550,10 @@ void notify_resource_state_change(struct sk_buff *skb, ...@@ -1550,10 +1550,10 @@ void notify_resource_state_change(struct sk_buff *skb,
.res_susp_fen = resource_state_change->susp_fen[NEW], .res_susp_fen = resource_state_change->susp_fen[NEW],
}; };
notify_resource_state(skb, seq, resource, &resource_info, type); return notify_resource_state(skb, seq, resource, &resource_info, type);
} }
void notify_connection_state_change(struct sk_buff *skb, int notify_connection_state_change(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_connection_state_change *connection_state_change, struct drbd_connection_state_change *connection_state_change,
enum drbd_notification_type type) enum drbd_notification_type type)
...@@ -1564,10 +1564,10 @@ void notify_connection_state_change(struct sk_buff *skb, ...@@ -1564,10 +1564,10 @@ void notify_connection_state_change(struct sk_buff *skb,
.conn_role = connection_state_change->peer_role[NEW], .conn_role = connection_state_change->peer_role[NEW],
}; };
notify_connection_state(skb, seq, connection, &connection_info, type); return notify_connection_state(skb, seq, connection, &connection_info, type);
} }
void notify_device_state_change(struct sk_buff *skb, int notify_device_state_change(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_device_state_change *device_state_change, struct drbd_device_state_change *device_state_change,
enum drbd_notification_type type) enum drbd_notification_type type)
...@@ -1577,10 +1577,10 @@ void notify_device_state_change(struct sk_buff *skb, ...@@ -1577,10 +1577,10 @@ void notify_device_state_change(struct sk_buff *skb,
.dev_disk_state = device_state_change->disk_state[NEW], .dev_disk_state = device_state_change->disk_state[NEW],
}; };
notify_device_state(skb, seq, device, &device_info, type); return notify_device_state(skb, seq, device, &device_info, type);
} }
void notify_peer_device_state_change(struct sk_buff *skb, int notify_peer_device_state_change(struct sk_buff *skb,
unsigned int seq, unsigned int seq,
struct drbd_peer_device_state_change *p, struct drbd_peer_device_state_change *p,
enum drbd_notification_type type) enum drbd_notification_type type)
...@@ -1594,7 +1594,7 @@ void notify_peer_device_state_change(struct sk_buff *skb, ...@@ -1594,7 +1594,7 @@ void notify_peer_device_state_change(struct sk_buff *skb,
.peer_resync_susp_dependency = p->resync_susp_dependency[NEW], .peer_resync_susp_dependency = p->resync_susp_dependency[NEW],
}; };
notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type); return notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type);
} }
static void broadcast_state_change(struct drbd_state_change *state_change) static void broadcast_state_change(struct drbd_state_change *state_change)
...@@ -1602,7 +1602,7 @@ static void broadcast_state_change(struct drbd_state_change *state_change) ...@@ -1602,7 +1602,7 @@ static void broadcast_state_change(struct drbd_state_change *state_change)
struct drbd_resource_state_change *resource_state_change = &state_change->resource[0]; struct drbd_resource_state_change *resource_state_change = &state_change->resource[0];
bool resource_state_has_changed; bool resource_state_has_changed;
unsigned int n_device, n_connection, n_peer_device, n_peer_devices; unsigned int n_device, n_connection, n_peer_device, n_peer_devices;
void (*last_func)(struct sk_buff *, unsigned int, void *, int (*last_func)(struct sk_buff *, unsigned int, void *,
enum drbd_notification_type) = NULL; enum drbd_notification_type) = NULL;
void *last_arg = NULL; void *last_arg = NULL;
......
...@@ -44,19 +44,19 @@ extern struct drbd_state_change *remember_old_state(struct drbd_resource *, gfp_ ...@@ -44,19 +44,19 @@ extern struct drbd_state_change *remember_old_state(struct drbd_resource *, gfp_
extern void copy_old_to_new_state_change(struct drbd_state_change *); extern void copy_old_to_new_state_change(struct drbd_state_change *);
extern void forget_state_change(struct drbd_state_change *); extern void forget_state_change(struct drbd_state_change *);
extern void notify_resource_state_change(struct sk_buff *, extern int notify_resource_state_change(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_resource_state_change *, struct drbd_resource_state_change *,
enum drbd_notification_type type); enum drbd_notification_type type);
extern void notify_connection_state_change(struct sk_buff *, extern int notify_connection_state_change(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_connection_state_change *, struct drbd_connection_state_change *,
enum drbd_notification_type type); enum drbd_notification_type type);
extern void notify_device_state_change(struct sk_buff *, extern int notify_device_state_change(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_device_state_change *, struct drbd_device_state_change *,
enum drbd_notification_type type); enum drbd_notification_type type);
extern void notify_peer_device_state_change(struct sk_buff *, extern int notify_peer_device_state_change(struct sk_buff *,
unsigned int, unsigned int,
struct drbd_peer_device_state_change *, struct drbd_peer_device_state_change *,
enum drbd_notification_type type); enum drbd_notification_type type);
......
...@@ -1365,7 +1365,6 @@ static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot) ...@@ -1365,7 +1365,6 @@ static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot)
*/ */
int cdrom_number_of_slots(struct cdrom_device_info *cdi) int cdrom_number_of_slots(struct cdrom_device_info *cdi)
{ {
int status;
int nslots = 1; int nslots = 1;
struct cdrom_changer_info *info; struct cdrom_changer_info *info;
...@@ -1377,7 +1376,7 @@ int cdrom_number_of_slots(struct cdrom_device_info *cdi) ...@@ -1377,7 +1376,7 @@ int cdrom_number_of_slots(struct cdrom_device_info *cdi)
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
if ((status = cdrom_read_mech_status(cdi, info)) == 0) if (cdrom_read_mech_status(cdi, info) == 0)
nslots = info->hdr.nslots; nslots = info->hdr.nslots;
kfree(info); kfree(info);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册