Skip to content

Commit

Permalink
Merge branch 'for-3.18/drivers' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull block layer driver update from Jens Axboe:
 "This is the block driver pull request for 3.18.  Not a lot in there
  this round, and nothing earth shattering.

   - A round of drbd fixes from the linbit team, and an improvement in
     asender performance.

   - Removal of deprecated (and unused) IRQF_DISABLED flag in rsxx and
     hd from Michael Opdenacker.

   - Disable entropy collection from flash devices by default, from Mike
     Snitzer.

   - A small collection of xen blkfront/back fixes from Roger Pau Monné
     and Vitaly Kuznetsov"

* 'for-3.18/drivers' of git://git.kernel.dk/linux-block:
  block: disable entropy contributions for nonrot devices
  xen, blkfront: factor out flush-related checks from do_blkif_request()
  xen-blkback: fix leak on grant map error path
  xen/blkback: unmap all persistent grants when frontend gets disconnected
  rsxx: Remove deprecated IRQF_DISABLED
  block: hd: remove deprecated IRQF_DISABLED
  drbd: use RB_DECLARE_CALLBACKS() to define augment callbacks
  drbd: compute the end before rb_insert_augmented()
  drbd: Add missing newline in resync progress display in /proc/drbd
  drbd: reduce lock contention in drbd_worker
  drbd: Improve asender performance
  drbd: Get rid of the WORK_PENDING macro
  drbd: Get rid of the __no_warn and __cond_lock macros
  drbd: Avoid inconsistent locking warning
  drbd: Remove superfluous newline from "resync_extents" debugfs entry.
  drbd: Use consistent names for all the bi_end_io callbacks
  drbd: Use better variable names
  • Loading branch information
torvalds committed Oct 18, 2014
2 parents d3dc366 + b277da0 commit e75437f
Show file tree
Hide file tree
Showing 30 changed files with 132 additions and 147 deletions.
4 changes: 2 additions & 2 deletions drivers/block/drbd/drbd_actlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,14 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
if (bio_add_page(bio, device->md_io.page, size, 0) != size)
goto out;
bio->bi_private = device;
bio->bi_end_io = drbd_md_io_complete;
bio->bi_end_io = drbd_md_endio;
bio->bi_rw = rw;

if (!(rw & WRITE) && device->state.disk == D_DISKLESS && device->ldev == NULL)
/* special case, drbd_md_read() during drbd_adm_attach(): no get_ldev */
;
else if (!get_ldev_if_state(device, D_ATTACHING)) {
/* Corresponding put_ldev in drbd_md_io_complete() */
/* Corresponding put_ldev in drbd_md_endio() */
drbd_err(device, "ASSERT FAILED: get_ldev_if_state() == 1 in _drbd_md_sync_page_io()\n");
err = -ENODEV;
goto out;
Expand Down
6 changes: 3 additions & 3 deletions drivers/block/drbd/drbd_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ static void drbd_bm_aio_ctx_destroy(struct kref *kref)
}

/* bv_page may be a copy, or may be the original */
static void bm_async_io_complete(struct bio *bio, int error)
static void drbd_bm_endio(struct bio *bio, int error)
{
struct drbd_bm_aio_ctx *ctx = bio->bi_private;
struct drbd_device *device = ctx->device;
Expand Down Expand Up @@ -1027,7 +1027,7 @@ static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_ho
* according to api. Do we want to assert that? */
bio_add_page(bio, page, len, 0);
bio->bi_private = ctx;
bio->bi_end_io = bm_async_io_complete;
bio->bi_end_io = drbd_bm_endio;

if (drbd_insert_fault(device, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) {
bio->bi_rw |= rw;
Expand Down Expand Up @@ -1125,7 +1125,7 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned
}

/*
* We initialize ctx->in_flight to one to make sure bm_async_io_complete
* We initialize ctx->in_flight to one to make sure drbd_bm_endio
* will not set ctx->done early, and decrement / test it here. If there
* are still some bios in flight, we need to wait for them here.
* If all IO is done already (or nothing had been submitted), there is
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/drbd/drbd_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ static void resync_dump_detail(struct seq_file *m, struct lc_element *e)
{
struct bm_extent *bme = lc_entry(e, struct bm_extent, lce);

seq_printf(m, "%5d %s %s %s\n", bme->rs_left,
seq_printf(m, "%5d %s %s %s", bme->rs_left,
test_bit(BME_NO_WRITES, &bme->flags) ? "NO_WRITES" : "---------",
test_bit(BME_LOCKED, &bme->flags) ? "LOCKED" : "------",
test_bit(BME_PRIORITY, &bme->flags) ? "PRIORITY" : "--------"
Expand Down
19 changes: 10 additions & 9 deletions drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@
# define __must_hold(x)
#endif

#define __no_warn(lock, stmt) do { __acquire(lock); stmt; __release(lock); } while (0)

/* module parameter, defined in drbd_main.c */
extern unsigned int minor_count;
extern bool disable_sendpage;
Expand Down Expand Up @@ -1483,7 +1481,7 @@ extern int drbd_khelper(struct drbd_device *device, char *cmd);

/* drbd_worker.c */
/* bi_end_io handlers */
extern void drbd_md_io_complete(struct bio *bio, int error);
extern void drbd_md_endio(struct bio *bio, int error);
extern void drbd_peer_request_endio(struct bio *bio, int error);
extern void drbd_request_endio(struct bio *bio, int error);
extern int drbd_worker(struct drbd_thread *thi);
Expand Down Expand Up @@ -2100,16 +2098,19 @@ static inline bool is_sync_state(enum drbd_conns connection_state)

/**
* get_ldev() - Increase the ref count on device->ldev. Returns 0 if there is no ldev
* @M: DRBD device.
* @_device: DRBD device.
* @_min_state: Minimum device state required for success.
*
* You have to call put_ldev() when finished working with device->ldev.
*/
#define get_ldev(M) __cond_lock(local, _get_ldev_if_state(M,D_INCONSISTENT))
#define get_ldev_if_state(M,MINS) __cond_lock(local, _get_ldev_if_state(M,MINS))
#define get_ldev_if_state(_device, _min_state) \
(_get_ldev_if_state((_device), (_min_state)) ? \
({ __acquire(x); true; }) : false)
#define get_ldev(_device) get_ldev_if_state(_device, D_INCONSISTENT)

static inline void put_ldev(struct drbd_device *device)
{
enum drbd_disk_state ds = device->state.disk;
enum drbd_disk_state disk_state = device->state.disk;
/* We must check the state *before* the atomic_dec becomes visible,
* or we have a theoretical race where someone hitting zero,
* while state still D_FAILED, will then see D_DISKLESS in the
Expand All @@ -2122,10 +2123,10 @@ static inline void put_ldev(struct drbd_device *device)
__release(local);
D_ASSERT(device, i >= 0);
if (i == 0) {
if (ds == D_DISKLESS)
if (disk_state == D_DISKLESS)
/* even internal references gone, safe to destroy */
drbd_device_post_work(device, DESTROY_DISK);
if (ds == D_FAILED)
if (disk_state == D_FAILED)
/* all application IO references gone. */
if (!test_and_set_bit(GOING_DISKLESS, &device->flags))
drbd_device_post_work(device, GO_DISKLESS);
Expand Down
40 changes: 6 additions & 34 deletions drivers/block/drbd/drbd_interval.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,8 @@ compute_subtree_last(struct drbd_interval *node)
return max;
}

static void augment_propagate(struct rb_node *rb, struct rb_node *stop)
{
while (rb != stop) {
struct drbd_interval *node = rb_entry(rb, struct drbd_interval, rb);
sector_t subtree_last = compute_subtree_last(node);
if (node->end == subtree_last)
break;
node->end = subtree_last;
rb = rb_parent(&node->rb);
}
}

static void augment_copy(struct rb_node *rb_old, struct rb_node *rb_new)
{
struct drbd_interval *old = rb_entry(rb_old, struct drbd_interval, rb);
struct drbd_interval *new = rb_entry(rb_new, struct drbd_interval, rb);

new->end = old->end;
}

static void augment_rotate(struct rb_node *rb_old, struct rb_node *rb_new)
{
struct drbd_interval *old = rb_entry(rb_old, struct drbd_interval, rb);
struct drbd_interval *new = rb_entry(rb_new, struct drbd_interval, rb);

new->end = old->end;
old->end = compute_subtree_last(old);
}

static const struct rb_augment_callbacks augment_callbacks = {
augment_propagate,
augment_copy,
augment_rotate,
};
RB_DECLARE_CALLBACKS(static, augment_callbacks, struct drbd_interval, rb,
sector_t, end, compute_subtree_last);

/**
* drbd_insert_interval - insert a new interval into a tree
Expand All @@ -79,6 +47,7 @@ bool
drbd_insert_interval(struct rb_root *root, struct drbd_interval *this)
{
struct rb_node **new = &root->rb_node, *parent = NULL;
sector_t this_end = this->sector + (this->size >> 9);

BUG_ON(!IS_ALIGNED(this->size, 512));

Expand All @@ -87,6 +56,8 @@ drbd_insert_interval(struct rb_root *root, struct drbd_interval *this)
rb_entry(*new, struct drbd_interval, rb);

parent = *new;
if (here->end < this_end)
here->end = this_end;
if (this->sector < here->sector)
new = &(*new)->rb_left;
else if (this->sector > here->sector)
Expand All @@ -99,6 +70,7 @@ drbd_insert_interval(struct rb_root *root, struct drbd_interval *this)
return false;
}

this->end = this_end;
rb_link_node(&this->rb, parent, new);
rb_insert_augmented(&this->rb, root, &augment_callbacks);
return true;
Expand Down
28 changes: 14 additions & 14 deletions drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1622,13 +1622,13 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *
struct drbd_socket *sock;
struct p_data *p;
unsigned int dp_flags = 0;
int dgs;
int digest_size;
int err;

sock = &peer_device->connection->data;
p = drbd_prepare_command(peer_device, sock);
dgs = peer_device->connection->integrity_tfm ?
crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;
digest_size = peer_device->connection->integrity_tfm ?
crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;

if (!p)
return -EIO;
Expand Down Expand Up @@ -1659,9 +1659,9 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *

/* our digest is still only over the payload.
* TRIM does not carry any payload. */
if (dgs)
if (digest_size)
drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, p + 1);
err = __send_command(peer_device->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
err = __send_command(peer_device->connection, device->vnr, sock, P_DATA, sizeof(*p) + digest_size, NULL, req->i.size);
if (!err) {
/* For protocol A, we have to memcpy the payload into
* socket buffers, as we may complete right away
Expand All @@ -1674,23 +1674,23 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *
* out ok after sending on this side, but does not fit on the
* receiving side, we sure have detected corruption elsewhere.
*/
if (!(req->rq_state & (RQ_EXP_RECEIVE_ACK | RQ_EXP_WRITE_ACK)) || dgs)
if (!(req->rq_state & (RQ_EXP_RECEIVE_ACK | RQ_EXP_WRITE_ACK)) || digest_size)
err = _drbd_send_bio(peer_device, req->master_bio);
else
err = _drbd_send_zc_bio(peer_device, req->master_bio);

/* double check digest, sometimes buffers have been modified in flight. */
if (dgs > 0 && dgs <= 64) {
if (digest_size > 0 && digest_size <= 64) {
/* 64 byte, 512 bit, is the largest digest size
* currently supported in kernel crypto. */
unsigned char digest[64];
drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, digest);
if (memcmp(p + 1, digest, dgs)) {
if (memcmp(p + 1, digest, digest_size)) {
drbd_warn(device,
"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
(unsigned long long)req->i.sector, req->i.size);
}
} /* else if (dgs > 64) {
} /* else if (digest_size > 64) {
... Be noisy about digest too large ...
} */
}
Expand All @@ -1711,23 +1711,23 @@ int drbd_send_block(struct drbd_peer_device *peer_device, enum drbd_packet cmd,
struct drbd_socket *sock;
struct p_data *p;
int err;
int dgs;
int digest_size;

sock = &peer_device->connection->data;
p = drbd_prepare_command(peer_device, sock);

dgs = peer_device->connection->integrity_tfm ?
crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;
digest_size = peer_device->connection->integrity_tfm ?
crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0;

if (!p)
return -EIO;
p->sector = cpu_to_be64(peer_req->i.sector);
p->block_id = peer_req->block_id;
p->seq_num = 0; /* unused */
p->dp_flags = 0;
if (dgs)
if (digest_size)
drbd_csum_ee(peer_device->connection->integrity_tfm, peer_req, p + 1);
err = __send_command(peer_device->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
err = __send_command(peer_device->connection, device->vnr, sock, cmd, sizeof(*p) + digest_size, NULL, peer_req->i.size);
if (!err)
err = _drbd_send_zc_ee(peer_device, peer_req);
mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */
Expand Down
4 changes: 3 additions & 1 deletion drivers/block/drbd/drbd_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,12 @@ static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *se
(unsigned long) Bit2KB(rs_left >> 10),
(unsigned long) Bit2KB(rs_total >> 10));
else
seq_printf(seq, "(%lu/%lu)K\n\t",
seq_printf(seq, "(%lu/%lu)K",
(unsigned long) Bit2KB(rs_left),
(unsigned long) Bit2KB(rs_total));

seq_printf(seq, "\n\t");

/* see drivers/md/md.c
* We do not want to overflow, so the order of operands and
* the * 100 / 100 trick are important. We do a +1 to be
Expand Down
Loading

0 comments on commit e75437f

Please sign in to comment.