Commit 84b8c06b authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner

drbd: Create a dedicated struct drbd_device_work

drbd_device_work is a work item that has a reference to a device,
while drbd_work is a more generic work item that does not carry
a reference to a device.

All callbacks get a pointer to a drbd_work instance, those callbacks
that expect a drbd_device_work use the container_of macro to get it.
Signed-off-by: default avatarAndreas Gruenbacher <agruen@linbit.com>
Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
parent 8682eae9
...@@ -95,11 +95,13 @@ struct __packed al_transaction_on_disk { ...@@ -95,11 +95,13 @@ struct __packed al_transaction_on_disk {
struct update_odbm_work { struct update_odbm_work {
struct drbd_work w; struct drbd_work w;
struct drbd_device *device;
unsigned int enr; unsigned int enr;
}; };
struct update_al_work { struct update_al_work {
struct drbd_work w; struct drbd_work w;
struct drbd_device *device;
struct completion event; struct completion event;
int err; int err;
}; };
...@@ -594,7 +596,7 @@ _al_write_transaction(struct drbd_device *device) ...@@ -594,7 +596,7 @@ _al_write_transaction(struct drbd_device *device)
static int w_al_write_transaction(struct drbd_work *w, int unused) static int w_al_write_transaction(struct drbd_work *w, int unused)
{ {
struct update_al_work *aw = container_of(w, struct update_al_work, w); struct update_al_work *aw = container_of(w, struct update_al_work, w);
struct drbd_device *device = w->device; struct drbd_device *device = aw->device;
int err; int err;
err = _al_write_transaction(device); err = _al_write_transaction(device);
...@@ -613,8 +615,9 @@ static int al_write_transaction(struct drbd_device *device, bool delegate) ...@@ -613,8 +615,9 @@ static int al_write_transaction(struct drbd_device *device, bool delegate)
struct update_al_work al_work; struct update_al_work al_work;
init_completion(&al_work.event); init_completion(&al_work.event);
al_work.w.cb = w_al_write_transaction; al_work.w.cb = w_al_write_transaction;
al_work.w.device = device; al_work.device = device;
drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &al_work.w); drbd_queue_work_front(&first_peer_device(device)->connection->sender_work,
&al_work.w);
wait_for_completion(&al_work.event); wait_for_completion(&al_work.event);
return al_work.err; return al_work.err;
} else } else
...@@ -684,7 +687,7 @@ int drbd_initialize_al(struct drbd_device *device, void *buffer) ...@@ -684,7 +687,7 @@ int drbd_initialize_al(struct drbd_device *device, void *buffer)
static int w_update_odbm(struct drbd_work *w, int unused) static int w_update_odbm(struct drbd_work *w, int unused)
{ {
struct update_odbm_work *udw = container_of(w, struct update_odbm_work, w); struct update_odbm_work *udw = container_of(w, struct update_odbm_work, w);
struct drbd_device *device = w->device; struct drbd_device *device = udw->device;
struct sib_info sib = { .sib_reason = SIB_SYNC_PROGRESS, }; struct sib_info sib = { .sib_reason = SIB_SYNC_PROGRESS, };
if (!get_ldev(device)) { if (!get_ldev(device)) {
...@@ -795,8 +798,9 @@ static void drbd_try_clear_on_disk_bm(struct drbd_device *device, sector_t secto ...@@ -795,8 +798,9 @@ static void drbd_try_clear_on_disk_bm(struct drbd_device *device, sector_t secto
if (udw) { if (udw) {
udw->enr = ext->lce.lc_number; udw->enr = ext->lce.lc_number;
udw->w.cb = w_update_odbm; udw->w.cb = w_update_odbm;
udw->w.device = device; udw->device = device;
drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &udw->w); drbd_queue_work_front(&first_peer_device(device)->connection->sender_work,
&udw->w);
} else { } else {
drbd_warn(device, "Could not kmalloc an udw\n"); drbd_warn(device, "Could not kmalloc an udw\n");
} }
......
...@@ -281,10 +281,11 @@ static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi) ...@@ -281,10 +281,11 @@ static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
struct drbd_work { struct drbd_work {
struct list_head list; struct list_head list;
int (*cb)(struct drbd_work *, int cancel); int (*cb)(struct drbd_work *, int cancel);
union { };
struct drbd_device_work {
struct drbd_work w;
struct drbd_device *device; struct drbd_device *device;
struct drbd_connection *connection;
};
}; };
#include "drbd_interval.h" #include "drbd_interval.h"
...@@ -293,6 +294,7 @@ extern int drbd_wait_misc(struct drbd_device *, struct drbd_interval *); ...@@ -293,6 +294,7 @@ extern int drbd_wait_misc(struct drbd_device *, struct drbd_interval *);
struct drbd_request { struct drbd_request {
struct drbd_work w; struct drbd_work w;
struct drbd_device *device;
/* if local IO is not allowed, will be NULL. /* if local IO is not allowed, will be NULL.
* if local IO _is_ allowed, holds the locally submitted bio clone, * if local IO _is_ allowed, holds the locally submitted bio clone,
...@@ -360,7 +362,7 @@ struct digest_info { ...@@ -360,7 +362,7 @@ struct digest_info {
}; };
struct drbd_peer_request { struct drbd_peer_request {
struct drbd_work w; struct drbd_device_work dw;
struct drbd_epoch *epoch; /* for writes */ struct drbd_epoch *epoch; /* for writes */
struct page *pages; struct page *pages;
atomic_t pending_bios; atomic_t pending_bios;
...@@ -686,11 +688,11 @@ struct drbd_device { ...@@ -686,11 +688,11 @@ struct drbd_device {
struct gendisk *vdisk; struct gendisk *vdisk;
unsigned long last_reattach_jif; unsigned long last_reattach_jif;
struct drbd_work resync_work, struct drbd_work resync_work;
unplug_work, struct drbd_work unplug_work;
go_diskless, struct drbd_work go_diskless;
md_sync_work, struct drbd_work md_sync_work;
start_resync_work; struct drbd_work start_resync_work;
struct timer_list resync_timer; struct timer_list resync_timer;
struct timer_list md_sync_timer; struct timer_list md_sync_timer;
struct timer_list start_resync_timer; struct timer_list start_resync_timer;
...@@ -1865,7 +1867,8 @@ static inline void put_ldev(struct drbd_device *device) ...@@ -1865,7 +1867,8 @@ static inline void put_ldev(struct drbd_device *device)
if (device->state.disk == D_FAILED) { if (device->state.disk == D_FAILED) {
/* all application IO references gone. */ /* all application IO references gone. */
if (!test_and_set_bit(GO_DISKLESS, &device->flags)) if (!test_and_set_bit(GO_DISKLESS, &device->flags))
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->go_diskless); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&device->go_diskless);
} }
wake_up(&device->misc_wait); wake_up(&device->misc_wait);
} }
...@@ -2092,7 +2095,9 @@ static inline void dec_ap_bio(struct drbd_device *device) ...@@ -2092,7 +2095,9 @@ static inline void dec_ap_bio(struct drbd_device *device)
if (ap_bio == 0 && test_bit(BITMAP_IO, &device->flags)) { if (ap_bio == 0 && test_bit(BITMAP_IO, &device->flags)) {
if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags)) if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w); drbd_queue_work(&first_peer_device(device)->
connection->sender_work,
&device->bm_io_work.w);
} }
/* this currently does wake_up for every dec_ap_bio! /* this currently does wake_up for every dec_ap_bio!
......
...@@ -312,7 +312,7 @@ void tl_abort_disk_io(struct drbd_device *device) ...@@ -312,7 +312,7 @@ void tl_abort_disk_io(struct drbd_device *device)
list_for_each_entry_safe(req, r, &connection->transfer_log, tl_requests) { list_for_each_entry_safe(req, r, &connection->transfer_log, tl_requests) {
if (!(req->rq_state & RQ_LOCAL_PENDING)) if (!(req->rq_state & RQ_LOCAL_PENDING))
continue; continue;
if (req->w.device != device) if (req->device != device)
continue; continue;
_req_mod(req, ABORT_DISK_IO); _req_mod(req, ABORT_DISK_IO);
} }
...@@ -1917,13 +1917,6 @@ void drbd_init_set_defaults(struct drbd_device *device) ...@@ -1917,13 +1917,6 @@ void drbd_init_set_defaults(struct drbd_device *device)
device->bm_io_work.w.cb = w_bitmap_io; device->bm_io_work.w.cb = w_bitmap_io;
device->start_resync_work.cb = w_start_resync; device->start_resync_work.cb = w_start_resync;
device->resync_work.device = device;
device->unplug_work.device = device;
device->go_diskless.device = device;
device->md_sync_work.device = device;
device->bm_io_work.w.device = device;
device->start_resync_work.device = device;
init_timer(&device->resync_timer); init_timer(&device->resync_timer);
init_timer(&device->md_sync_timer); init_timer(&device->md_sync_timer);
init_timer(&device->start_resync_timer); init_timer(&device->start_resync_timer);
...@@ -2222,7 +2215,7 @@ static void do_retry(struct work_struct *ws) ...@@ -2222,7 +2215,7 @@ static void do_retry(struct work_struct *ws)
spin_unlock_irq(&retry->lock); spin_unlock_irq(&retry->lock);
list_for_each_entry_safe(req, tmp, &writes, tl_requests) { list_for_each_entry_safe(req, tmp, &writes, tl_requests) {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct bio *bio = req->master_bio; struct bio *bio = req->master_bio;
unsigned long start_time = req->start_time; unsigned long start_time = req->start_time;
bool expected; bool expected;
...@@ -2273,7 +2266,7 @@ void drbd_restart_request(struct drbd_request *req) ...@@ -2273,7 +2266,7 @@ void drbd_restart_request(struct drbd_request *req)
/* Drop the extra reference that would otherwise /* Drop the extra reference that would otherwise
* have been dropped by complete_master_bio. * have been dropped by complete_master_bio.
* do_retry() needs to grab a new one. */ * do_retry() needs to grab a new one. */
dec_ap_bio(req->w.device); dec_ap_bio(req->device);
queue_work(retry.wq, &retry.worker); queue_work(retry.wq, &retry.worker);
} }
...@@ -3468,8 +3461,9 @@ int drbd_bmio_clear_n_write(struct drbd_device *device) ...@@ -3468,8 +3461,9 @@ int drbd_bmio_clear_n_write(struct drbd_device *device)
static int w_bitmap_io(struct drbd_work *w, int unused) static int w_bitmap_io(struct drbd_work *w, int unused)
{ {
struct bm_io_work *work = container_of(w, struct bm_io_work, w); struct drbd_device *device =
struct drbd_device *device = w->device; container_of(w, struct drbd_device, bm_io_work.w);
struct bm_io_work *work = &device->bm_io_work;
int rv = -EIO; int rv = -EIO;
D_ASSERT(device, atomic_read(&device->ap_bio_cnt) == 0); D_ASSERT(device, atomic_read(&device->ap_bio_cnt) == 0);
...@@ -3509,7 +3503,8 @@ void drbd_ldev_destroy(struct drbd_device *device) ...@@ -3509,7 +3503,8 @@ void drbd_ldev_destroy(struct drbd_device *device)
static int w_go_diskless(struct drbd_work *w, int unused) static int w_go_diskless(struct drbd_work *w, int unused)
{ {
struct drbd_device *device = w->device; struct drbd_device *device =
container_of(w, struct drbd_device, go_diskless);
D_ASSERT(device, device->state.disk == D_FAILED); D_ASSERT(device, device->state.disk == D_FAILED);
/* we cannot assert local_cnt == 0 here, as get_ldev_if_state will /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
...@@ -3583,7 +3578,8 @@ void drbd_queue_bitmap_io(struct drbd_device *device, ...@@ -3583,7 +3578,8 @@ void drbd_queue_bitmap_io(struct drbd_device *device,
set_bit(BITMAP_IO, &device->flags); set_bit(BITMAP_IO, &device->flags);
if (atomic_read(&device->ap_bio_cnt) == 0) { if (atomic_read(&device->ap_bio_cnt) == 0) {
if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags)) if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&device->bm_io_work.w);
} }
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
} }
...@@ -3643,12 +3639,14 @@ static void md_sync_timer_fn(unsigned long data) ...@@ -3643,12 +3639,14 @@ static void md_sync_timer_fn(unsigned long data)
/* must not double-queue! */ /* must not double-queue! */
if (list_empty(&device->md_sync_work.list)) if (list_empty(&device->md_sync_work.list))
drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &device->md_sync_work); drbd_queue_work_front(&first_peer_device(device)->connection->sender_work,
&device->md_sync_work);
} }
static int w_md_sync(struct drbd_work *w, int unused) static int w_md_sync(struct drbd_work *w, int unused)
{ {
struct drbd_device *device = w->device; struct drbd_device *device =
container_of(w, struct drbd_device, md_sync_work);
drbd_warn(device, "md_sync_timer expired! Worker calls drbd_md_sync().\n"); drbd_warn(device, "md_sync_timer expired! Worker calls drbd_md_sync().\n");
#ifdef DEBUG #ifdef DEBUG
......
...@@ -209,7 +209,7 @@ static void reclaim_finished_net_peer_reqs(struct drbd_device *device, ...@@ -209,7 +209,7 @@ static void reclaim_finished_net_peer_reqs(struct drbd_device *device,
stop to examine the list... */ stop to examine the list... */
list_for_each_safe(le, tle, &device->net_ee) { list_for_each_safe(le, tle, &device->net_ee) {
peer_req = list_entry(le, struct drbd_peer_request, w.list); peer_req = list_entry(le, struct drbd_peer_request, dw.w.list);
if (drbd_peer_req_has_active_page(peer_req)) if (drbd_peer_req_has_active_page(peer_req))
break; break;
list_move(le, to_be_freed); list_move(le, to_be_freed);
...@@ -225,7 +225,7 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device) ...@@ -225,7 +225,7 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
reclaim_finished_net_peer_reqs(device, &reclaimed); reclaim_finished_net_peer_reqs(device, &reclaimed);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
list_for_each_entry_safe(peer_req, t, &reclaimed, w.list) list_for_each_entry_safe(peer_req, t, &reclaimed, dw.w.list)
drbd_free_net_peer_req(device, peer_req); drbd_free_net_peer_req(device, peer_req);
} }
...@@ -363,7 +363,7 @@ drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t secto ...@@ -363,7 +363,7 @@ drbd_alloc_peer_req(struct drbd_peer_device *peer_device, u64 id, sector_t secto
peer_req->i.waiting = false; peer_req->i.waiting = false;
peer_req->epoch = NULL; peer_req->epoch = NULL;
peer_req->w.device = device; peer_req->dw.device = device;
peer_req->pages = page; peer_req->pages = page;
atomic_set(&peer_req->pending_bios, 0); atomic_set(&peer_req->pending_bios, 0);
peer_req->flags = 0; peer_req->flags = 0;
...@@ -402,7 +402,7 @@ int drbd_free_peer_reqs(struct drbd_device *device, struct list_head *list) ...@@ -402,7 +402,7 @@ int drbd_free_peer_reqs(struct drbd_device *device, struct list_head *list)
list_splice_init(list, &work_list); list_splice_init(list, &work_list);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
list_for_each_entry_safe(peer_req, t, &work_list, w.list) { list_for_each_entry_safe(peer_req, t, &work_list, dw.w.list) {
__drbd_free_peer_req(device, peer_req, is_net); __drbd_free_peer_req(device, peer_req, is_net);
count++; count++;
} }
...@@ -424,18 +424,18 @@ static int drbd_finish_peer_reqs(struct drbd_device *device) ...@@ -424,18 +424,18 @@ static int drbd_finish_peer_reqs(struct drbd_device *device)
list_splice_init(&device->done_ee, &work_list); list_splice_init(&device->done_ee, &work_list);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
list_for_each_entry_safe(peer_req, t, &reclaimed, w.list) list_for_each_entry_safe(peer_req, t, &reclaimed, dw.w.list)
drbd_free_net_peer_req(device, peer_req); drbd_free_net_peer_req(device, peer_req);
/* possible callbacks here: /* possible callbacks here:
* e_end_block, and e_end_resync_block, e_send_superseded. * e_end_block, and e_end_resync_block, e_send_superseded.
* all ignore the last argument. * all ignore the last argument.
*/ */
list_for_each_entry_safe(peer_req, t, &work_list, w.list) { list_for_each_entry_safe(peer_req, t, &work_list, dw.w.list) {
int err2; int err2;
/* list_del not necessary, next/prev members not touched */ /* list_del not necessary, next/prev members not touched */
err2 = peer_req->w.cb(&peer_req->w, !!err); err2 = peer_req->dw.w.cb(&peer_req->dw.w, !!err);
if (!err) if (!err)
err = err2; err = err2;
drbd_free_peer_req(device, peer_req); drbd_free_peer_req(device, peer_req);
...@@ -1664,9 +1664,10 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req ...@@ -1664,9 +1664,10 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req
*/ */
static int e_end_resync_block(struct drbd_work *w, int unused) static int e_end_resync_block(struct drbd_work *w, int unused)
{ {
struct drbd_device_work *dw = device_work(w);
struct drbd_peer_request *peer_req = struct drbd_peer_request *peer_req =
container_of(w, struct drbd_peer_request, w); container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = w->device; struct drbd_device *device = dw->device;
sector_t sector = peer_req->i.sector; sector_t sector = peer_req->i.sector;
int err; int err;
...@@ -1702,10 +1703,10 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto ...@@ -1702,10 +1703,10 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
/* corresponding dec_unacked() in e_end_resync_block() /* corresponding dec_unacked() in e_end_resync_block()
* respective _drbd_clear_done_ee */ * respective _drbd_clear_done_ee */
peer_req->w.cb = e_end_resync_block; peer_req->dw.w.cb = e_end_resync_block;
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_add(&peer_req->w.list, &device->sync_ee); list_add(&peer_req->dw.w.list, &device->sync_ee);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
atomic_add(data_size >> 9, &device->rs_sect_ev); atomic_add(data_size >> 9, &device->rs_sect_ev);
...@@ -1715,7 +1716,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto ...@@ -1715,7 +1716,7 @@ static int recv_resync_read(struct drbd_peer_device *peer_device, sector_t secto
/* don't care for the reason here */ /* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n"); drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list); list_del(&peer_req->dw.w.list);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req); drbd_free_peer_req(device, peer_req);
...@@ -1835,9 +1836,10 @@ static void restart_conflicting_writes(struct drbd_device *device, ...@@ -1835,9 +1836,10 @@ static void restart_conflicting_writes(struct drbd_device *device,
*/ */
static int e_end_block(struct drbd_work *w, int cancel) static int e_end_block(struct drbd_work *w, int cancel)
{ {
struct drbd_device_work *dw = device_work(w);
struct drbd_peer_request *peer_req = struct drbd_peer_request *peer_req =
container_of(w, struct drbd_peer_request, w); container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = w->device; struct drbd_device *device = dw->device;
sector_t sector = peer_req->i.sector; sector_t sector = peer_req->i.sector;
int err = 0, pcmd; int err = 0, pcmd;
...@@ -1874,11 +1876,11 @@ static int e_end_block(struct drbd_work *w, int cancel) ...@@ -1874,11 +1876,11 @@ static int e_end_block(struct drbd_work *w, int cancel)
return err; return err;
} }
static int e_send_ack(struct drbd_work *w, enum drbd_packet ack) static int e_send_ack(struct drbd_device_work *dw, enum drbd_packet ack)
{ {
struct drbd_device *device = w->device; struct drbd_device *device = dw->device;
struct drbd_peer_request *peer_req = struct drbd_peer_request *peer_req =
container_of(w, struct drbd_peer_request, w); container_of(dw, struct drbd_peer_request, dw);
int err; int err;
err = drbd_send_ack(first_peer_device(device), ack, peer_req); err = drbd_send_ack(first_peer_device(device), ack, peer_req);
...@@ -1889,14 +1891,15 @@ static int e_send_ack(struct drbd_work *w, enum drbd_packet ack) ...@@ -1889,14 +1891,15 @@ static int e_send_ack(struct drbd_work *w, enum drbd_packet ack)
static int e_send_superseded(struct drbd_work *w, int unused) static int e_send_superseded(struct drbd_work *w, int unused)
{ {
return e_send_ack(w, P_SUPERSEDED); return e_send_ack(device_work(w), P_SUPERSEDED);
} }
static int e_send_retry_write(struct drbd_work *w, int unused) static int e_send_retry_write(struct drbd_work *w, int unused)
{ {
struct drbd_connection *connection = first_peer_device(w->device)->connection; struct drbd_device_work *dw = device_work(w);
struct drbd_connection *connection = first_peer_device(dw->device)->connection;
return e_send_ack(w, connection->agreed_pro_version >= 100 ? return e_send_ack(dw, connection->agreed_pro_version >= 100 ?
P_RETRY_WRITE : P_SUPERSEDED); P_RETRY_WRITE : P_SUPERSEDED);
} }
...@@ -1943,7 +1946,7 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee ...@@ -1943,7 +1946,7 @@ static bool overlapping_resync_write(struct drbd_device *device, struct drbd_pee
bool rv = 0; bool rv = 0;
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_for_each_entry(rs_req, &device->sync_ee, w.list) { list_for_each_entry(rs_req, &device->sync_ee, dw.w.list) {
if (overlaps(peer_req->i.sector, peer_req->i.size, if (overlaps(peer_req->i.sector, peer_req->i.size,
rs_req->i.sector, rs_req->i.size)) { rs_req->i.sector, rs_req->i.size)) {
rv = 1; rv = 1;
...@@ -2114,9 +2117,9 @@ static int handle_write_conflicts(struct drbd_device *device, ...@@ -2114,9 +2117,9 @@ static int handle_write_conflicts(struct drbd_device *device,
superseded ? "local" : "remote"); superseded ? "local" : "remote");
inc_unacked(device); inc_unacked(device);
peer_req->w.cb = superseded ? e_send_superseded : peer_req->dw.w.cb = superseded ? e_send_superseded :
e_send_retry_write; e_send_retry_write;
list_add_tail(&peer_req->w.list, &device->done_ee); list_add_tail(&peer_req->dw.w.list, &device->done_ee);
wake_asender(first_peer_device(device)->connection); wake_asender(first_peer_device(device)->connection);
err = -ENOENT; err = -ENOENT;
...@@ -2212,7 +2215,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2212,7 +2215,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
return -EIO; return -EIO;
} }
peer_req->w.cb = e_end_block; peer_req->dw.w.cb = e_end_block;
dp_flags = be32_to_cpu(p->dp_flags); dp_flags = be32_to_cpu(p->dp_flags);
rw |= wire_flags_to_bio(device, dp_flags); rw |= wire_flags_to_bio(device, dp_flags);
...@@ -2252,7 +2255,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2252,7 +2255,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
update_peer_seq(peer_device, peer_seq); update_peer_seq(peer_device, peer_seq);
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
} }
list_add(&peer_req->w.list, &device->active_ee); list_add(&peer_req->dw.w.list, &device->active_ee);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
if (device->state.conn == C_SYNC_TARGET) if (device->state.conn == C_SYNC_TARGET)
...@@ -2299,7 +2302,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info * ...@@ -2299,7 +2302,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
/* don't care for the reason here */ /* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n"); drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list); list_del(&peer_req->dw.w.list);
drbd_remove_epoch_entry_interval(device, peer_req); drbd_remove_epoch_entry_interval(device, peer_req);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
if (peer_req->flags & EE_CALL_AL_COMPLETE_IO) if (peer_req->flags & EE_CALL_AL_COMPLETE_IO)
...@@ -2454,13 +2457,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2454,13 +2457,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
switch (pi->cmd) { switch (pi->cmd) {
case P_DATA_REQUEST: case P_DATA_REQUEST:
peer_req->w.cb = w_e_end_data_req; peer_req->dw.w.cb = w_e_end_data_req;
fault_type = DRBD_FAULT_DT_RD; fault_type = DRBD_FAULT_DT_RD;
/* application IO, don't drbd_rs_begin_io */ /* application IO, don't drbd_rs_begin_io */
goto submit; goto submit;
case P_RS_DATA_REQUEST: case P_RS_DATA_REQUEST:
peer_req->w.cb = w_e_end_rsdata_req; peer_req->dw.w.cb = w_e_end_rsdata_req;
fault_type = DRBD_FAULT_RS_RD; fault_type = DRBD_FAULT_RS_RD;
/* used in the sector offset progress display */ /* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector); device->bm_resync_fo = BM_SECT_TO_BIT(sector);
...@@ -2484,13 +2487,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2484,13 +2487,13 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
if (pi->cmd == P_CSUM_RS_REQUEST) { if (pi->cmd == P_CSUM_RS_REQUEST) {
D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89); D_ASSERT(device, peer_device->connection->agreed_pro_version >= 89);
peer_req->w.cb = w_e_end_csum_rs_req; peer_req->dw.w.cb = w_e_end_csum_rs_req;
/* used in the sector offset progress display */ /* used in the sector offset progress display */
device->bm_resync_fo = BM_SECT_TO_BIT(sector); device->bm_resync_fo = BM_SECT_TO_BIT(sector);
} else if (pi->cmd == P_OV_REPLY) { } else if (pi->cmd == P_OV_REPLY) {
/* track progress, we may need to throttle */ /* track progress, we may need to throttle */
atomic_add(size >> 9, &device->rs_sect_in); atomic_add(size >> 9, &device->rs_sect_in);
peer_req->w.cb = w_e_end_ov_reply; peer_req->dw.w.cb = w_e_end_ov_reply;
dec_rs_pending(device); dec_rs_pending(device);
/* drbd_rs_begin_io done when we sent this request, /* drbd_rs_begin_io done when we sent this request,
* but accounting still needs to be done. */ * but accounting still needs to be done. */
...@@ -2514,7 +2517,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2514,7 +2517,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
drbd_info(device, "Online Verify start sector: %llu\n", drbd_info(device, "Online Verify start sector: %llu\n",
(unsigned long long)sector); (unsigned long long)sector);
} }
peer_req->w.cb = w_e_end_ov_req; peer_req->dw.w.cb = w_e_end_ov_req;
fault_type = DRBD_FAULT_RS_RD; fault_type = DRBD_FAULT_RS_RD;
break; break;
...@@ -2555,7 +2558,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2555,7 +2558,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
submit: submit:
inc_unacked(device); inc_unacked(device);
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_add_tail(&peer_req->w.list, &device->read_ee); list_add_tail(&peer_req->dw.w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
if (drbd_submit_peer_request(device, peer_req, READ, fault_type) == 0) if (drbd_submit_peer_request(device, peer_req, READ, fault_type) == 0)
...@@ -2564,7 +2567,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet ...@@ -2564,7 +2567,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
/* don't care for the reason here */ /* don't care for the reason here */
drbd_err(device, "submit failed, triggering re-connect\n"); drbd_err(device, "submit failed, triggering re-connect\n");
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list); list_del(&peer_req->dw.w.list);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
/* no drbd_rs_complete_io(), we are dropping the connection anyways */ /* no drbd_rs_complete_io(), we are dropping the connection anyways */
...@@ -4495,7 +4498,6 @@ void conn_flush_workqueue(struct drbd_connection *connection) ...@@ -4495,7 +4498,6 @@ void conn_flush_workqueue(struct drbd_connection *connection)
struct drbd_wq_barrier barr; struct drbd_wq_barrier barr;
barr.w.cb = w_complete; barr.w.cb = w_complete;
barr.w.connection = connection;
init_completion(&barr.done); init_completion(&barr.done);
drbd_queue_work(&connection->sender_work, &barr.w); drbd_queue_work(&connection->sender_work, &barr.w);
wait_for_completion(&barr.done); wait_for_completion(&barr.done);
...@@ -5218,7 +5220,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info * ...@@ -5218,7 +5220,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info *
struct drbd_peer_device *peer_device; struct drbd_peer_device *peer_device;
struct drbd_device *device; struct drbd_device *device;
struct p_block_ack *p = pi->data; struct p_block_ack *p = pi->data;
struct drbd_work *w; struct drbd_device_work *dw;
sector_t sector; sector_t sector;
int size; int size;
...@@ -5250,13 +5252,13 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info * ...@@ -5250,13 +5252,13 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info *
drbd_advance_rs_marks(device, device->ov_left); drbd_advance_rs_marks(device, device->ov_left);
if (device->ov_left == 0) { if (device->ov_left == 0) {
w = kmalloc(sizeof(*w), GFP_NOIO); dw = kmalloc(sizeof(*dw), GFP_NOIO);
if (w) { if (dw) {
w->cb = w_ov_finished; dw->w.cb = w_ov_finished;
w->device = device; dw->device = device;
drbd_queue_work(&peer_device->connection->sender_work, w); drbd_queue_work(&peer_device->connection->sender_work, &dw->w);
} else { } else {
drbd_err(device, "kmalloc(w) failed."); drbd_err(device, "kmalloc(dw) failed.");
ov_out_of_sync_print(device); ov_out_of_sync_print(device);
drbd_resync_finished(device); drbd_resync_finished(device);
} }
......
...@@ -72,7 +72,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, ...@@ -72,7 +72,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device,
drbd_req_make_private_bio(req, bio_src); drbd_req_make_private_bio(req, bio_src);
req->rq_state = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0; req->rq_state = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0;
req->w.device = device; req->device = device;
req->master_bio = bio_src; req->master_bio = bio_src;
req->epoch = 0; req->epoch = 0;
...@@ -95,7 +95,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, ...@@ -95,7 +95,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device,
void drbd_req_destroy(struct kref *kref) void drbd_req_destroy(struct kref *kref)
{ {
struct drbd_request *req = container_of(kref, struct drbd_request, kref); struct drbd_request *req = container_of(kref, struct drbd_request, kref);
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
const unsigned s = req->rq_state; const unsigned s = req->rq_state;
if ((req->master_bio && !(s & RQ_POSTPONED)) || if ((req->master_bio && !(s & RQ_POSTPONED)) ||
...@@ -191,7 +191,7 @@ void complete_master_bio(struct drbd_device *device, ...@@ -191,7 +191,7 @@ void complete_master_bio(struct drbd_device *device,
static void drbd_remove_request_interval(struct rb_root *root, static void drbd_remove_request_interval(struct rb_root *root,
struct drbd_request *req) struct drbd_request *req)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct drbd_interval *i = &req->i; struct drbd_interval *i = &req->i;
drbd_remove_interval(root, i); drbd_remove_interval(root, i);
...@@ -211,7 +211,7 @@ static ...@@ -211,7 +211,7 @@ static
void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m) void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
{ {
const unsigned s = req->rq_state; const unsigned s = req->rq_state;
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
int rw; int rw;
int error, ok; int error, ok;
...@@ -306,7 +306,7 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m) ...@@ -306,7 +306,7 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_error *m, int put) static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_error *m, int put)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
D_ASSERT(device, m || (req->rq_state & RQ_POSTPONED)); D_ASSERT(device, m || (req->rq_state & RQ_POSTPONED));
if (!atomic_sub_and_test(put, &req->completion_ref)) if (!atomic_sub_and_test(put, &req->completion_ref))
...@@ -329,7 +329,7 @@ static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_ ...@@ -329,7 +329,7 @@ static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_
static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m, static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m,
int clear, int set) int clear, int set)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
unsigned s = req->rq_state; unsigned s = req->rq_state;
int c_put = 0; int c_put = 0;
int k_put = 0; int k_put = 0;
...@@ -454,7 +454,7 @@ static void drbd_report_io_error(struct drbd_device *device, struct drbd_request ...@@ -454,7 +454,7 @@ static void drbd_report_io_error(struct drbd_device *device, struct drbd_request
int __req_mod(struct drbd_request *req, enum drbd_req_event what, int __req_mod(struct drbd_request *req, enum drbd_req_event what,
struct bio_and_error *m) struct bio_and_error *m)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct net_conf *nc; struct net_conf *nc;
int p, rv = 0; int p, rv = 0;
...@@ -542,7 +542,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, ...@@ -542,7 +542,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
D_ASSERT(device, (req->rq_state & RQ_LOCAL_MASK) == 0); D_ASSERT(device, (req->rq_state & RQ_LOCAL_MASK) == 0);
mod_rq_state(req, m, 0, RQ_NET_QUEUED); mod_rq_state(req, m, 0, RQ_NET_QUEUED);
req->w.cb = w_send_read_req; req->w.cb = w_send_read_req;
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&req->w);
break; break;
case QUEUE_FOR_NET_WRITE: case QUEUE_FOR_NET_WRITE:
...@@ -577,7 +578,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, ...@@ -577,7 +578,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
D_ASSERT(device, req->rq_state & RQ_NET_PENDING); D_ASSERT(device, req->rq_state & RQ_NET_PENDING);
mod_rq_state(req, m, 0, RQ_NET_QUEUED|RQ_EXP_BARR_ACK); mod_rq_state(req, m, 0, RQ_NET_QUEUED|RQ_EXP_BARR_ACK);
req->w.cb = w_send_dblock; req->w.cb = w_send_dblock;
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&req->w);
/* close the epoch, in case it outgrew the limit */ /* close the epoch, in case it outgrew the limit */
rcu_read_lock(); rcu_read_lock();
...@@ -592,7 +594,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, ...@@ -592,7 +594,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
case QUEUE_FOR_SEND_OOS: case QUEUE_FOR_SEND_OOS:
mod_rq_state(req, m, 0, RQ_NET_QUEUED); mod_rq_state(req, m, 0, RQ_NET_QUEUED);
req->w.cb = w_send_out_of_sync; req->w.cb = w_send_out_of_sync;
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&req->w);
break; break;
case READ_RETRY_REMOTE_CANCELED: case READ_RETRY_REMOTE_CANCELED:
...@@ -704,7 +707,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, ...@@ -704,7 +707,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
get_ldev(device); /* always succeeds in this call path */ get_ldev(device); /* always succeeds in this call path */
req->w.cb = w_restart_disk_io; req->w.cb = w_restart_disk_io;
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&req->w);
break; break;
case RESEND: case RESEND:
...@@ -720,12 +724,13 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, ...@@ -720,12 +724,13 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
Throwing them out of the TL here by pretending we got a BARRIER_ACK. Throwing them out of the TL here by pretending we got a BARRIER_ACK.
During connection handshake, we ensure that the peer was not rebooted. */ During connection handshake, we ensure that the peer was not rebooted. */
if (!(req->rq_state & RQ_NET_OK)) { if (!(req->rq_state & RQ_NET_OK)) {
/* FIXME could this possibly be a req->w.cb == w_send_out_of_sync? /* FIXME could this possibly be a req->dw.cb == w_send_out_of_sync?
* in that case we must not set RQ_NET_PENDING. */ * in that case we must not set RQ_NET_PENDING. */
mod_rq_state(req, m, RQ_COMPLETION_SUSP, RQ_NET_QUEUED|RQ_NET_PENDING); mod_rq_state(req, m, RQ_COMPLETION_SUSP, RQ_NET_QUEUED|RQ_NET_PENDING);
if (req->w.cb) { if (req->w.cb) {
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &req->w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&req->w);
rv = req->rq_state & RQ_WRITE ? MR_WRITE : MR_READ; rv = req->rq_state & RQ_WRITE ? MR_WRITE : MR_READ;
} /* else: FIXME can this happen? */ } /* else: FIXME can this happen? */
break; break;
...@@ -835,7 +840,7 @@ static bool remote_due_to_read_balancing(struct drbd_device *device, sector_t se ...@@ -835,7 +840,7 @@ static bool remote_due_to_read_balancing(struct drbd_device *device, sector_t se
static void complete_conflicting_writes(struct drbd_request *req) static void complete_conflicting_writes(struct drbd_request *req)
{ {
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct drbd_interval *i; struct drbd_interval *i;
sector_t sector = req->i.sector; sector_t sector = req->i.sector;
int size = req->i.size; int size = req->i.size;
...@@ -915,7 +920,7 @@ static void maybe_pull_ahead(struct drbd_device *device) ...@@ -915,7 +920,7 @@ static void maybe_pull_ahead(struct drbd_device *device)
*/ */
static bool do_remote_read(struct drbd_request *req) static bool do_remote_read(struct drbd_request *req)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
enum drbd_read_balancing rbm; enum drbd_read_balancing rbm;
if (req->private_bio) { if (req->private_bio) {
...@@ -960,7 +965,7 @@ static bool do_remote_read(struct drbd_request *req) ...@@ -960,7 +965,7 @@ static bool do_remote_read(struct drbd_request *req)
* which does NOT include those that we are L_AHEAD for. */ * which does NOT include those that we are L_AHEAD for. */
static int drbd_process_write_request(struct drbd_request *req) static int drbd_process_write_request(struct drbd_request *req)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
int remote, send_oos; int remote, send_oos;
remote = drbd_should_do_remote(device->state); remote = drbd_should_do_remote(device->state);
...@@ -997,7 +1002,7 @@ static int drbd_process_write_request(struct drbd_request *req) ...@@ -997,7 +1002,7 @@ static int drbd_process_write_request(struct drbd_request *req)
static void static void
drbd_submit_req_private_bio(struct drbd_request *req) drbd_submit_req_private_bio(struct drbd_request *req)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct bio *bio = req->private_bio; struct bio *bio = req->private_bio;
const int rw = bio_rw(bio); const int rw = bio_rw(bio);
...@@ -1390,7 +1395,7 @@ void request_timer_fn(unsigned long data) ...@@ -1390,7 +1395,7 @@ void request_timer_fn(unsigned long data)
drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n"); drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n");
_drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL); _drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL);
} }
if (dt && req->rq_state & RQ_LOCAL_PENDING && req->w.device == device && if (dt && req->rq_state & RQ_LOCAL_PENDING && req->device == device &&
time_after(now, req->start_time + dt) && time_after(now, req->start_time + dt) &&
!time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) { !time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) {
drbd_warn(device, "Local backing device failed to meet the disk-timeout\n"); drbd_warn(device, "Local backing device failed to meet the disk-timeout\n");
......
...@@ -294,7 +294,7 @@ extern void drbd_restart_request(struct drbd_request *req); ...@@ -294,7 +294,7 @@ extern void drbd_restart_request(struct drbd_request *req);
* outside the spinlock, e.g. when walking some list on cleanup. */ * outside the spinlock, e.g. when walking some list on cleanup. */
static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
{ {
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct bio_and_error m; struct bio_and_error m;
int rv; int rv;
...@@ -314,7 +314,7 @@ static inline int req_mod(struct drbd_request *req, ...@@ -314,7 +314,7 @@ static inline int req_mod(struct drbd_request *req,
enum drbd_req_event what) enum drbd_req_event what)
{ {
unsigned long flags; unsigned long flags;
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct bio_and_error m; struct bio_and_error m;
int rv; int rv;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
struct after_state_chg_work { struct after_state_chg_work {
struct drbd_work w; struct drbd_work w;
struct drbd_device *device;
union drbd_state os; union drbd_state os;
union drbd_state ns; union drbd_state ns;
enum chg_state_flags flags; enum chg_state_flags flags;
...@@ -1145,9 +1146,10 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, ...@@ -1145,9 +1146,10 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
ascw->ns = ns; ascw->ns = ns;
ascw->flags = flags; ascw->flags = flags;
ascw->w.cb = w_after_state_ch; ascw->w.cb = w_after_state_ch;
ascw->w.device = device; ascw->device = device;
ascw->done = done; ascw->done = done;
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &ascw->w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&ascw->w);
} else { } else {
drbd_err(device, "Could not kmalloc an ascw\n"); drbd_err(device, "Could not kmalloc an ascw\n");
} }
...@@ -1159,7 +1161,7 @@ static int w_after_state_ch(struct drbd_work *w, int unused) ...@@ -1159,7 +1161,7 @@ static int w_after_state_ch(struct drbd_work *w, int unused)
{ {
struct after_state_chg_work *ascw = struct after_state_chg_work *ascw =
container_of(w, struct after_state_chg_work, w); container_of(w, struct after_state_chg_work, w);
struct drbd_device *device = w->device; struct drbd_device *device = ascw->device;
after_state_ch(device, ascw->os, ascw->ns, ascw->flags); after_state_ch(device, ascw->os, ascw->ns, ascw->flags);
if (ascw->flags & CS_WAIT_COMPLETE) if (ascw->flags & CS_WAIT_COMPLETE)
...@@ -1528,18 +1530,19 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, ...@@ -1528,18 +1530,19 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
} }
struct after_conn_state_chg_work { struct after_conn_state_chg_work {
struct drbd_work w; struct drbd_device_work dw;
enum drbd_conns oc; enum drbd_conns oc;
union drbd_state ns_min; union drbd_state ns_min;
union drbd_state ns_max; /* new, max state, over all devices */ union drbd_state ns_max; /* new, max state, over all devices */
enum chg_state_flags flags; enum chg_state_flags flags;
struct drbd_connection *connection;
}; };
static int w_after_conn_state_ch(struct drbd_work *w, int unused) static int w_after_conn_state_ch(struct drbd_work *w, int unused)
{ {
struct after_conn_state_chg_work *acscw = struct after_conn_state_chg_work *acscw =
container_of(w, struct after_conn_state_chg_work, w); container_of(w, struct after_conn_state_chg_work, dw.w);
struct drbd_connection *connection = w->connection; struct drbd_connection *connection = acscw->connection;
enum drbd_conns oc = acscw->oc; enum drbd_conns oc = acscw->oc;
union drbd_state ns_max = acscw->ns_max; union drbd_state ns_max = acscw->ns_max;
struct drbd_peer_device *peer_device; struct drbd_peer_device *peer_device;
...@@ -1840,10 +1843,10 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u ...@@ -1840,10 +1843,10 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
acscw->ns_min = ns_min; acscw->ns_min = ns_min;
acscw->ns_max = ns_max; acscw->ns_max = ns_max;
acscw->flags = flags; acscw->flags = flags;
acscw->w.cb = w_after_conn_state_ch; acscw->dw.w.cb = w_after_conn_state_ch;
kref_get(&connection->kref); kref_get(&connection->kref);
acscw->w.connection = connection; acscw->connection = connection;
drbd_queue_work(&connection->sender_work, &acscw->w); drbd_queue_work(&connection->sender_work, &acscw->dw.w);
} else { } else {
drbd_err(connection, "Could not kmalloc an acscw\n"); drbd_err(connection, "Could not kmalloc an acscw\n");
} }
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
along with drbd; see the file COPYING. If not, write to along with drbd; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/drbd.h> #include <linux/drbd.h>
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "drbd_protocol.h" #include "drbd_protocol.h"
#include "drbd_req.h" #include "drbd_req.h"
static int w_make_ov_request(struct drbd_work *w, int cancel); static int w_make_ov_request(struct drbd_work *, int);
/* endio handlers: /* endio handlers:
...@@ -100,18 +100,19 @@ void drbd_md_io_complete(struct bio *bio, int error) ...@@ -100,18 +100,19 @@ void drbd_md_io_complete(struct bio *bio, int error)
static void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local) static void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{ {
unsigned long flags = 0; unsigned long flags = 0;
struct drbd_device *device = peer_req->w.device; struct drbd_device *device = peer_req->dw.device;
spin_lock_irqsave(&device->resource->req_lock, flags); spin_lock_irqsave(&device->resource->req_lock, flags);
device->read_cnt += peer_req->i.size >> 9; device->read_cnt += peer_req->i.size >> 9;
list_del(&peer_req->w.list); list_del(&peer_req->dw.w.list);
if (list_empty(&device->read_ee)) if (list_empty(&device->read_ee))
wake_up(&device->ee_wait); wake_up(&device->ee_wait);
if (test_bit(__EE_WAS_ERROR, &peer_req->flags)) if (test_bit(__EE_WAS_ERROR, &peer_req->flags))
__drbd_chk_io_error(device, DRBD_READ_ERROR); __drbd_chk_io_error(device, DRBD_READ_ERROR);
spin_unlock_irqrestore(&device->resource->req_lock, flags); spin_unlock_irqrestore(&device->resource->req_lock, flags);
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &peer_req->w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&peer_req->dw.w);
put_ldev(device); put_ldev(device);
} }
...@@ -120,7 +121,7 @@ static void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __rele ...@@ -120,7 +121,7 @@ static void drbd_endio_read_sec_final(struct drbd_peer_request *peer_req) __rele
static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local) static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(local)
{ {
unsigned long flags = 0; unsigned long flags = 0;
struct drbd_device *device = peer_req->w.device; struct drbd_device *device = peer_req->dw.device;
struct drbd_interval i; struct drbd_interval i;
int do_wake; int do_wake;
u64 block_id; u64 block_id;
...@@ -136,13 +137,13 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel ...@@ -136,13 +137,13 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
spin_lock_irqsave(&device->resource->req_lock, flags); spin_lock_irqsave(&device->resource->req_lock, flags);
device->writ_cnt += peer_req->i.size >> 9; device->writ_cnt += peer_req->i.size >> 9;
list_move_tail(&peer_req->w.list, &device->done_ee); list_move_tail(&peer_req->dw.w.list, &device->done_ee);
/* /*
* Do not remove from the write_requests tree here: we did not send the * Do not remove from the write_requests tree here: we did not send the
* Ack yet and did not wake possibly waiting conflicting requests. * Ack yet and did not wake possibly waiting conflicting requests.
* Removed from the tree from "drbd_process_done_ee" within the * Removed from the tree from "drbd_process_done_ee" within the
* appropriate w.cb (e_end_block/e_end_resync_block) or from * appropriate dw.cb (e_end_block/e_end_resync_block) or from
* _drbd_clear_done_ee. * _drbd_clear_done_ee.
*/ */
...@@ -171,7 +172,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel ...@@ -171,7 +172,7 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
void drbd_peer_request_endio(struct bio *bio, int error) void drbd_peer_request_endio(struct bio *bio, int error)
{ {
struct drbd_peer_request *peer_req = bio->bi_private; struct drbd_peer_request *peer_req = bio->bi_private;
struct drbd_device *device = peer_req->w.device; struct drbd_device *device = peer_req->dw.device;
int uptodate = bio_flagged(bio, BIO_UPTODATE); int uptodate = bio_flagged(bio, BIO_UPTODATE);
int is_write = bio_data_dir(bio) == WRITE; int is_write = bio_data_dir(bio) == WRITE;
...@@ -208,7 +209,7 @@ void drbd_request_endio(struct bio *bio, int error) ...@@ -208,7 +209,7 @@ void drbd_request_endio(struct bio *bio, int error)
{ {
unsigned long flags; unsigned long flags;
struct drbd_request *req = bio->bi_private; struct drbd_request *req = bio->bi_private;
struct drbd_device *device = req->w.device; struct drbd_device *device = req->device;
struct bio_and_error m; struct bio_and_error m;
enum drbd_req_event what; enum drbd_req_event what;
int uptodate = bio_flagged(bio, BIO_UPTODATE); int uptodate = bio_flagged(bio, BIO_UPTODATE);
...@@ -332,8 +333,9 @@ void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest) ...@@ -332,8 +333,9 @@ void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest)
/* MAYBE merge common code with w_e_end_ov_req */ /* MAYBE merge common code with w_e_end_ov_req */
static int w_e_send_csum(struct drbd_work *w, int cancel) static int w_e_send_csum(struct drbd_work *w, int cancel)
{ {
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w); struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = w->device; struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = dw->device;
int digest_size; int digest_size;
void *digest; void *digest;
int err = 0; int err = 0;
...@@ -396,9 +398,9 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, ...@@ -396,9 +398,9 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
if (!peer_req) if (!peer_req)
goto defer; goto defer;
peer_req->w.cb = w_e_send_csum; peer_req->dw.w.cb = w_e_send_csum;
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_add(&peer_req->w.list, &device->read_ee); list_add(&peer_req->dw.w.list, &device->read_ee);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
atomic_add(size >> 9, &device->rs_sect_ev); atomic_add(size >> 9, &device->rs_sect_ev);
...@@ -410,7 +412,7 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, ...@@ -410,7 +412,7 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
* retry may or may not help. * retry may or may not help.
* If it does not, you may need to force disconnect. */ * If it does not, you may need to force disconnect. */
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_del(&peer_req->w.list); list_del(&peer_req->dw.w.list);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
drbd_free_peer_req(device, peer_req); drbd_free_peer_req(device, peer_req);
...@@ -421,7 +423,9 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector, ...@@ -421,7 +423,9 @@ static int read_for_csum(struct drbd_peer_device *peer_device, sector_t sector,
int w_resync_timer(struct drbd_work *w, int cancel) int w_resync_timer(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = w->device; struct drbd_device *device =
container_of(w, struct drbd_device, resync_work);
switch (device->state.conn) { switch (device->state.conn) {
case C_VERIFY_S: case C_VERIFY_S:
w_make_ov_request(w, cancel); w_make_ov_request(w, cancel);
...@@ -439,7 +443,8 @@ void resync_timer_fn(unsigned long data) ...@@ -439,7 +443,8 @@ void resync_timer_fn(unsigned long data)
struct drbd_device *device = (struct drbd_device *) data; struct drbd_device *device = (struct drbd_device *) data;
if (list_empty(&device->resync_work.list)) if (list_empty(&device->resync_work.list))
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->resync_work); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&device->resync_work);
} }
static void fifo_set(struct fifo_buffer *fb, int value) static void fifo_set(struct fifo_buffer *fb, int value)
...@@ -563,7 +568,8 @@ static int drbd_rs_number_requests(struct drbd_device *device) ...@@ -563,7 +568,8 @@ static int drbd_rs_number_requests(struct drbd_device *device)
int w_make_resync_request(struct drbd_work *w, int cancel) int w_make_resync_request(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = w->device; struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = dw->device;
unsigned long bit; unsigned long bit;
sector_t sector; sector_t sector;
const sector_t capacity = drbd_get_capacity(device->this_bdev); const sector_t capacity = drbd_get_capacity(device->this_bdev);
...@@ -727,7 +733,7 @@ int w_make_resync_request(struct drbd_work *w, int cancel) ...@@ -727,7 +733,7 @@ int w_make_resync_request(struct drbd_work *w, int cancel)
static int w_make_ov_request(struct drbd_work *w, int cancel) static int w_make_ov_request(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = w->device; struct drbd_device *device = device_work(w)->device;
int number, i, size; int number, i, size;
sector_t sector; sector_t sector;
const sector_t capacity = drbd_get_capacity(device->this_bdev); const sector_t capacity = drbd_get_capacity(device->this_bdev);
...@@ -781,8 +787,10 @@ static int w_make_ov_request(struct drbd_work *w, int cancel) ...@@ -781,8 +787,10 @@ static int w_make_ov_request(struct drbd_work *w, int cancel)
int w_ov_finished(struct drbd_work *w, int cancel) int w_ov_finished(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = w->device; struct drbd_device_work *dw =
kfree(w); container_of(w, struct drbd_device_work, w);
struct drbd_device *device = dw->device;
kfree(dw);
ov_out_of_sync_print(device); ov_out_of_sync_print(device);
drbd_resync_finished(device); drbd_resync_finished(device);
...@@ -791,8 +799,10 @@ int w_ov_finished(struct drbd_work *w, int cancel) ...@@ -791,8 +799,10 @@ int w_ov_finished(struct drbd_work *w, int cancel)
static int w_resync_finished(struct drbd_work *w, int cancel) static int w_resync_finished(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = w->device; struct drbd_device_work *dw =
kfree(w); container_of(w, struct drbd_device_work, w);
struct drbd_device *device = dw->device;
kfree(dw);
drbd_resync_finished(device); drbd_resync_finished(device);
...@@ -814,7 +824,7 @@ int drbd_resync_finished(struct drbd_device *device) ...@@ -814,7 +824,7 @@ int drbd_resync_finished(struct drbd_device *device)
unsigned long db, dt, dbdt; unsigned long db, dt, dbdt;
unsigned long n_oos; unsigned long n_oos;
union drbd_state os, ns; union drbd_state os, ns;
struct drbd_work *w; struct drbd_device_work *dw;
char *khelper_cmd = NULL; char *khelper_cmd = NULL;
int verify_done = 0; int verify_done = 0;
...@@ -828,14 +838,15 @@ int drbd_resync_finished(struct drbd_device *device) ...@@ -828,14 +838,15 @@ int drbd_resync_finished(struct drbd_device *device)
* is not finished by now). Retry in 100ms. */ * is not finished by now). Retry in 100ms. */
schedule_timeout_interruptible(HZ / 10); schedule_timeout_interruptible(HZ / 10);
w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC); dw = kmalloc(sizeof(struct drbd_device_work), GFP_ATOMIC);
if (w) { if (dw) {
w->cb = w_resync_finished; dw->w.cb = w_resync_finished;
w->device = device; dw->device = device;
drbd_queue_work(&first_peer_device(device)->connection->sender_work, w); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&dw->w);
return 1; return 1;
} }
drbd_err(device, "Warn failed to drbd_rs_del_all() and to kmalloc(w).\n"); drbd_err(device, "Warn failed to drbd_rs_del_all() and to kmalloc(dw).\n");
} }
dt = (jiffies - device->rs_start - device->rs_paused) / HZ; dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
...@@ -972,7 +983,7 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_ ...@@ -972,7 +983,7 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_
atomic_add(i, &device->pp_in_use_by_net); atomic_add(i, &device->pp_in_use_by_net);
atomic_sub(i, &device->pp_in_use); atomic_sub(i, &device->pp_in_use);
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
list_add_tail(&peer_req->w.list, &device->net_ee); list_add_tail(&peer_req->dw.w.list, &device->net_ee);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
wake_up(&drbd_pp_wait); wake_up(&drbd_pp_wait);
} else } else
...@@ -987,8 +998,9 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_ ...@@ -987,8 +998,9 @@ static void move_to_net_ee_or_free(struct drbd_device *device, struct drbd_peer_
*/ */
int w_e_end_data_req(struct drbd_work *w, int cancel) int w_e_end_data_req(struct drbd_work *w, int cancel)
{ {
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w); struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = w->device; struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = dw->device;
int err; int err;
if (unlikely(cancel)) { if (unlikely(cancel)) {
...@@ -1018,14 +1030,14 @@ int w_e_end_data_req(struct drbd_work *w, int cancel) ...@@ -1018,14 +1030,14 @@ int w_e_end_data_req(struct drbd_work *w, int cancel)
/** /**
* w_e_end_rsdata_req() - Worker callback to send a P_RS_DATA_REPLY packet in response to a P_RS_DATA_REQUEST * w_e_end_rsdata_req() - Worker callback to send a P_RS_DATA_REPLY packet in response to a P_RS_DATA_REQUEST
* @device: DRBD device.
* @w: work object. * @w: work object.
* @cancel: The connection will be closed anyways * @cancel: The connection will be closed anyways
*/ */
int w_e_end_rsdata_req(struct drbd_work *w, int cancel) int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
{ {
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w); struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = w->device; struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = dw->device;
int err; int err;
if (unlikely(cancel)) { if (unlikely(cancel)) {
...@@ -1073,8 +1085,9 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel) ...@@ -1073,8 +1085,9 @@ int w_e_end_rsdata_req(struct drbd_work *w, int cancel)
int w_e_end_csum_rs_req(struct drbd_work *w, int cancel) int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
{ {
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w); struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = w->device; struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = dw->device;
struct digest_info *di; struct digest_info *di;
int digest_size; int digest_size;
void *digest = NULL; void *digest = NULL;
...@@ -1136,8 +1149,9 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel) ...@@ -1136,8 +1149,9 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
int w_e_end_ov_req(struct drbd_work *w, int cancel) int w_e_end_ov_req(struct drbd_work *w, int cancel)
{ {
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w); struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = w->device; struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = dw->device;
sector_t sector = peer_req->i.sector; sector_t sector = peer_req->i.sector;
unsigned int size = peer_req->i.size; unsigned int size = peer_req->i.size;
int digest_size; int digest_size;
...@@ -1192,8 +1206,9 @@ void drbd_ov_out_of_sync_found(struct drbd_device *device, sector_t sector, int ...@@ -1192,8 +1206,9 @@ void drbd_ov_out_of_sync_found(struct drbd_device *device, sector_t sector, int
int w_e_end_ov_reply(struct drbd_work *w, int cancel) int w_e_end_ov_reply(struct drbd_work *w, int cancel)
{ {
struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w); struct drbd_device_work *dw = device_work(w);
struct drbd_device *device = w->device; struct drbd_peer_request *peer_req = container_of(dw, struct drbd_peer_request, dw);
struct drbd_device *device = dw->device;
struct digest_info *di; struct digest_info *di;
void *digest; void *digest;
sector_t sector = peer_req->i.sector; sector_t sector = peer_req->i.sector;
...@@ -1285,7 +1300,8 @@ static int drbd_send_barrier(struct drbd_connection *connection) ...@@ -1285,7 +1300,8 @@ static int drbd_send_barrier(struct drbd_connection *connection)
int w_send_write_hint(struct drbd_work *w, int cancel) int w_send_write_hint(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = w->device; struct drbd_device *device =
container_of(w, struct drbd_device, unplug_work);
struct drbd_socket *sock; struct drbd_socket *sock;
if (cancel) if (cancel)
...@@ -1320,7 +1336,7 @@ static void maybe_send_barrier(struct drbd_connection *connection, unsigned int ...@@ -1320,7 +1336,7 @@ static void maybe_send_barrier(struct drbd_connection *connection, unsigned int
int w_send_out_of_sync(struct drbd_work *w, int cancel) int w_send_out_of_sync(struct drbd_work *w, int cancel)
{ {
struct drbd_request *req = container_of(w, struct drbd_request, w); struct drbd_request *req = container_of(w, struct drbd_request, w);
struct drbd_device *device = w->device; struct drbd_device *device = req->device;
struct drbd_connection *connection = first_peer_device(device)->connection; struct drbd_connection *connection = first_peer_device(device)->connection;
int err; int err;
...@@ -1343,14 +1359,13 @@ int w_send_out_of_sync(struct drbd_work *w, int cancel) ...@@ -1343,14 +1359,13 @@ int w_send_out_of_sync(struct drbd_work *w, int cancel)
/** /**
* w_send_dblock() - Worker callback to send a P_DATA packet in order to mirror a write request * w_send_dblock() - Worker callback to send a P_DATA packet in order to mirror a write request
* @device: DRBD device.
* @w: work object. * @w: work object.
* @cancel: The connection will be closed anyways * @cancel: The connection will be closed anyways
*/ */
int w_send_dblock(struct drbd_work *w, int cancel) int w_send_dblock(struct drbd_work *w, int cancel)
{ {
struct drbd_request *req = container_of(w, struct drbd_request, w); struct drbd_request *req = container_of(w, struct drbd_request, w);
struct drbd_device *device = w->device; struct drbd_device *device = req->device;
struct drbd_connection *connection = first_peer_device(device)->connection; struct drbd_connection *connection = first_peer_device(device)->connection;
int err; int err;
...@@ -1371,14 +1386,13 @@ int w_send_dblock(struct drbd_work *w, int cancel) ...@@ -1371,14 +1386,13 @@ int w_send_dblock(struct drbd_work *w, int cancel)
/** /**
* w_send_read_req() - Worker callback to send a read request (P_DATA_REQUEST) packet * w_send_read_req() - Worker callback to send a read request (P_DATA_REQUEST) packet
* @device: DRBD device.
* @w: work object. * @w: work object.
* @cancel: The connection will be closed anyways * @cancel: The connection will be closed anyways
*/ */
int w_send_read_req(struct drbd_work *w, int cancel) int w_send_read_req(struct drbd_work *w, int cancel)
{ {
struct drbd_request *req = container_of(w, struct drbd_request, w); struct drbd_request *req = container_of(w, struct drbd_request, w);
struct drbd_device *device = w->device; struct drbd_device *device = req->device;
struct drbd_connection *connection = first_peer_device(device)->connection; struct drbd_connection *connection = first_peer_device(device)->connection;
int err; int err;
...@@ -1402,7 +1416,7 @@ int w_send_read_req(struct drbd_work *w, int cancel) ...@@ -1402,7 +1416,7 @@ int w_send_read_req(struct drbd_work *w, int cancel)
int w_restart_disk_io(struct drbd_work *w, int cancel) int w_restart_disk_io(struct drbd_work *w, int cancel)
{ {
struct drbd_request *req = container_of(w, struct drbd_request, w); struct drbd_request *req = container_of(w, struct drbd_request, w);
struct drbd_device *device = w->device; struct drbd_device *device = req->device;
if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG) if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
drbd_al_begin_io(device, &req->i, false); drbd_al_begin_io(device, &req->i, false);
...@@ -1574,12 +1588,14 @@ void start_resync_timer_fn(unsigned long data) ...@@ -1574,12 +1588,14 @@ void start_resync_timer_fn(unsigned long data)
{ {
struct drbd_device *device = (struct drbd_device *) data; struct drbd_device *device = (struct drbd_device *) data;
drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->start_resync_work); drbd_queue_work(&first_peer_device(device)->connection->sender_work,
&device->start_resync_work);
} }
int w_start_resync(struct drbd_work *w, int cancel) int w_start_resync(struct drbd_work *w, int cancel)
{ {
struct drbd_device *device = w->device; struct drbd_device *device =
container_of(w, struct drbd_device, start_resync_work);
if (atomic_read(&device->unacked_cnt) || atomic_read(&device->rs_pending_cnt)) { if (atomic_read(&device->unacked_cnt) || atomic_read(&device->rs_pending_cnt)) {
drbd_warn(device, "w_start_resync later...\n"); drbd_warn(device, "w_start_resync later...\n");
...@@ -1881,7 +1897,7 @@ static void wait_for_work(struct drbd_connection *connection, struct list_head * ...@@ -1881,7 +1897,7 @@ static void wait_for_work(struct drbd_connection *connection, struct list_head *
int drbd_worker(struct drbd_thread *thi) int drbd_worker(struct drbd_thread *thi)
{ {
struct drbd_connection *connection = thi->connection; struct drbd_connection *connection = thi->connection;
struct drbd_work *w = NULL; struct drbd_device_work *dw = NULL;
struct drbd_peer_device *peer_device; struct drbd_peer_device *peer_device;
LIST_HEAD(work_list); LIST_HEAD(work_list);
int vnr; int vnr;
...@@ -1907,9 +1923,9 @@ int drbd_worker(struct drbd_thread *thi) ...@@ -1907,9 +1923,9 @@ int drbd_worker(struct drbd_thread *thi)
break; break;
while (!list_empty(&work_list)) { while (!list_empty(&work_list)) {
w = list_first_entry(&work_list, struct drbd_work, list); dw = list_first_entry(&work_list, struct drbd_device_work, w.list);
list_del_init(&w->list); list_del_init(&dw->w.list);
if (w->cb(w, connection->cstate < C_WF_REPORT_PARAMS) == 0) if (dw->w.cb(&dw->w, connection->cstate < C_WF_REPORT_PARAMS) == 0)
continue; continue;
if (connection->cstate >= C_WF_REPORT_PARAMS) if (connection->cstate >= C_WF_REPORT_PARAMS)
conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD); conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
...@@ -1918,9 +1934,9 @@ int drbd_worker(struct drbd_thread *thi) ...@@ -1918,9 +1934,9 @@ int drbd_worker(struct drbd_thread *thi)
do { do {
while (!list_empty(&work_list)) { while (!list_empty(&work_list)) {
w = list_first_entry(&work_list, struct drbd_work, list); dw = list_first_entry(&work_list, struct drbd_device_work, w.list);
list_del_init(&w->list); list_del_init(&dw->w.list);
w->cb(w, 1); dw->w.cb(&dw->w, 1);
} }
dequeue_work_batch(&connection->sender_work, &work_list); dequeue_work_batch(&connection->sender_work, &work_list);
} while (!list_empty(&work_list)); } while (!list_empty(&work_list));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment