Commit 88b390ff authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner
Browse files

drbd: _drbd_send_page(): Return 0 upon success and an error code otherwise

parent b987427b
Loading
Loading
Loading
Loading
+23 −21
Original line number Diff line number Diff line
@@ -1421,9 +1421,10 @@ static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page,
static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
		    int offset, size_t size, unsigned msg_flags)
{
	struct socket *socket = mdev->tconn->data.socket;
	mm_segment_t oldfs = get_fs();
	int sent, ok;
	int len = size;
	int err = -EIO;

	/* e.g. XFS meta- & log-data is in slab pages, which have a
	 * page_count of 0 and/or have PageSlab() set.
@@ -1432,25 +1433,25 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
	 * __page_cache_release a page that would actually still be referenced
	 * by someone, leading to some obscure delayed Oops somewhere else. */
	if (disable_sendpage || (page_count(page) < 1) || PageSlab(page))
		return !_drbd_no_send_page(mdev, page, offset, size, msg_flags);
		return _drbd_no_send_page(mdev, page, offset, size, msg_flags);

	msg_flags |= MSG_NOSIGNAL;
	drbd_update_congested(mdev->tconn);
	set_fs(KERNEL_DS);
	do {
		sent = mdev->tconn->data.socket->ops->sendpage(mdev->tconn->data.socket, page,
							offset, len,
							msg_flags);
		int sent;

		sent = socket->ops->sendpage(socket, page, offset, len, msg_flags);
		if (sent <= 0) {
			if (sent == -EAGAIN) {
			if (we_should_drop_the_connection(mdev->tconn,
							  mdev->tconn->data.socket))
				if (we_should_drop_the_connection(mdev->tconn, socket))
					break;
			else
				continue;
			}
		if (sent <= 0) {
			dev_warn(DEV, "%s: size=%d len=%d sent=%d\n",
			     __func__, (int)size, len, sent);
			if (sent < 0)
				err = sent;
			break;
		}
		len    -= sent;
@@ -1459,10 +1460,11 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
	set_fs(oldfs);
	clear_bit(NET_CONGESTED, &mdev->tconn->flags);

	ok = (len == 0);
	if (likely(ok))
	if (len == 0) {
		err = 0;
		mdev->send_cnt += size >> 9;
	return ok;
	}
	return err;
}

static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
@@ -1485,7 +1487,7 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
	int i;
	/* hint all but last page with MSG_MORE */
	__bio_for_each_segment(bvec, bio, i, 0) {
		if (!_drbd_send_page(mdev, bvec->bv_page,
		if (_drbd_send_page(mdev, bvec->bv_page,
				    bvec->bv_offset, bvec->bv_len,
				    i == bio->bi_vcnt -1 ? 0 : MSG_MORE))
			return 0;
@@ -1502,7 +1504,7 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev,
	/* hint all but last page with MSG_MORE */
	page_chain_for_each(page) {
		unsigned l = min_t(unsigned, len, PAGE_SIZE);
		if (!_drbd_send_page(mdev, page, 0, l,
		if (_drbd_send_page(mdev, page, 0, l,
				    page_chain_next(page) ? MSG_MORE : 0))
			return 0;
		len -= l;