Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7561e51 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

Merge branch 'writeback'

parents 55cfcd12 ce7c252a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
		goto out_iput;
	res->size = i_size_read(inode);
	res->change_attr = delegation->change_attr;
	if (nfsi->nrequests != 0)
	if (nfs_have_writebacks(inode))
		res->change_attr++;
	res->ctime = inode->i_ctime;
	res->mtime = inode->i_mtime;
+1 −1
Original line number Diff line number Diff line
@@ -1089,7 +1089,7 @@ bool nfs4_delegation_flush_on_close(const struct inode *inode)
	delegation = rcu_dereference(nfsi->delegation);
	if (delegation == NULL || !(delegation->type & FMODE_WRITE))
		goto out;
	if (nfsi->nrequests < delegation->pagemod_limit)
	if (atomic_long_read(&nfsi->nrequests) < delegation->pagemod_limit)
		ret = false;
out:
	rcu_read_unlock();
+2 −2
Original line number Diff line number Diff line
@@ -616,13 +616,13 @@ nfs_direct_write_scan_commit_list(struct inode *inode,
				  struct list_head *list,
				  struct nfs_commit_info *cinfo)
{
	spin_lock(&cinfo->inode->i_lock);
	mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
#ifdef CONFIG_NFS_V4_1
	if (cinfo->ds != NULL && cinfo->ds->nwritten != 0)
		NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
#endif
	nfs_scan_commit_list(&cinfo->mds->list, list, cinfo, 0);
	spin_unlock(&cinfo->inode->i_lock);
	mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
}

static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
+5 −5
Original line number Diff line number Diff line
@@ -1285,7 +1285,6 @@ static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi)

static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{
	struct nfs_inode *nfsi = NFS_I(inode);
	unsigned long ret = 0;

	if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
@@ -1315,7 +1314,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
	if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
			&& (fattr->valid & NFS_ATTR_FATTR_SIZE)
			&& i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
			&& nfsi->nrequests == 0) {
			&& !nfs_have_writebacks(inode)) {
		i_size_write(inode, nfs_size_to_loff_t(fattr->size));
		ret |= NFS_INO_INVALID_ATTR;
	}
@@ -1823,7 +1822,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
		if (new_isize != cur_isize) {
			/* Do we perhaps have any outstanding writes, or has
			 * the file grown beyond our last write? */
			if (nfsi->nrequests == 0 || new_isize > cur_isize) {
			if (!nfs_have_writebacks(inode) || new_isize > cur_isize) {
				i_size_write(inode, new_isize);
				if (!have_writers)
					invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
@@ -2012,10 +2011,11 @@ static void init_once(void *foo)
	INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
	INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
	INIT_LIST_HEAD(&nfsi->commit_info.list);
	nfsi->nrequests = 0;
	nfsi->commit_info.ncommit = 0;
	atomic_long_set(&nfsi->nrequests, 0);
	atomic_long_set(&nfsi->commit_info.ncommit, 0);
	atomic_set(&nfsi->commit_info.rpcs_out, 0);
	init_rwsem(&nfsi->rmdir_sem);
	mutex_init(&nfsi->commit_mutex);
	nfs4_init_once(nfsi);
}

+19 −48
Original line number Diff line number Diff line
@@ -134,19 +134,14 @@ EXPORT_SYMBOL_GPL(nfs_async_iocounter_wait);
/*
 * nfs_page_group_lock - lock the head of the page group
 * @req - request in group that is to be locked
 * @nonblock - if true don't block waiting for lock
 *
 * this lock must be held if modifying the page group list
 * this lock must be held when traversing or modifying the page
 * group list
 *
 * return 0 on success, < 0 on error: -EDELAY if nonblocking or the
 * result from wait_on_bit_lock
 *
 * NOTE: calling with nonblock=false should always have set the
 *       lock bit (see fs/buffer.c and other uses of wait_on_bit_lock
 *       with TASK_UNINTERRUPTIBLE), so there is no need to check the result.
 * return 0 on success, < 0 on error
 */
int
nfs_page_group_lock(struct nfs_page *req, bool nonblock)
nfs_page_group_lock(struct nfs_page *req)
{
	struct nfs_page *head = req->wb_head;

@@ -155,37 +150,12 @@ nfs_page_group_lock(struct nfs_page *req, bool nonblock)
	if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags))
		return 0;

	if (!nonblock) {
	set_bit(PG_CONTENDED1, &head->wb_flags);
	smp_mb__after_atomic();
	return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
				TASK_UNINTERRUPTIBLE);
}

	return -EAGAIN;
}

/*
 * nfs_page_group_lock_wait - wait for the lock to clear, but don't grab it
 * @req - a request in the group
 *
 * This is a blocking call to wait for the group lock to be cleared.
 */
void
nfs_page_group_lock_wait(struct nfs_page *req)
{
	struct nfs_page *head = req->wb_head;

	WARN_ON_ONCE(head != head->wb_head);

	if (!test_bit(PG_HEADLOCK, &head->wb_flags))
		return;
	set_bit(PG_CONTENDED1, &head->wb_flags);
	smp_mb__after_atomic();
	wait_on_bit(&head->wb_flags, PG_HEADLOCK,
		TASK_UNINTERRUPTIBLE);
}

/*
 * nfs_page_group_unlock - unlock the head of the page group
 * @req - request in group that is to be unlocked
@@ -246,7 +216,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit)
{
	bool ret;

	nfs_page_group_lock(req, false);
	nfs_page_group_lock(req);
	ret = nfs_page_group_sync_on_bit_locked(req, bit);
	nfs_page_group_unlock(req);

@@ -288,9 +258,7 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
			inode = page_file_mapping(req->wb_page)->host;
			set_bit(PG_INODE_REF, &req->wb_flags);
			kref_get(&req->wb_kref);
			spin_lock(&inode->i_lock);
			NFS_I(inode)->nrequests++;
			spin_unlock(&inode->i_lock);
			atomic_long_inc(&NFS_I(inode)->nrequests);
		}
	}
}
@@ -306,14 +274,11 @@ static void
nfs_page_group_destroy(struct kref *kref)
{
	struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
	struct nfs_page *head = req->wb_head;
	struct nfs_page *tmp, *next;

	/* subrequests must release the ref on the head request */
	if (req->wb_head != req)
		nfs_release_request(req->wb_head);

	if (!nfs_page_group_sync_on_bit(req, PG_TEARDOWN))
		return;
		goto out;

	tmp = req;
	do {
@@ -324,6 +289,10 @@ nfs_page_group_destroy(struct kref *kref)
		nfs_free_request(tmp);
		tmp = next;
	} while (tmp != req);
out:
	/* subrequests must release the ref on the head request */
	if (head != req)
		nfs_release_request(head);
}

/**
@@ -465,6 +434,7 @@ void nfs_release_request(struct nfs_page *req)
{
	kref_put(&req->wb_kref, nfs_page_group_destroy);
}
EXPORT_SYMBOL_GPL(nfs_release_request);

/**
 * nfs_wait_on_request - Wait for a request to complete.
@@ -483,6 +453,7 @@ nfs_wait_on_request(struct nfs_page *req)
	return wait_on_bit_io(&req->wb_flags, PG_BUSY,
			      TASK_UNINTERRUPTIBLE);
}
EXPORT_SYMBOL_GPL(nfs_wait_on_request);

/*
 * nfs_generic_pg_test - determine if requests can be coalesced
@@ -1036,7 +1007,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
	unsigned int bytes_left = 0;
	unsigned int offset, pgbase;

	nfs_page_group_lock(req, false);
	nfs_page_group_lock(req);

	subreq = req;
	bytes_left = subreq->wb_bytes;
@@ -1058,7 +1029,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
			if (mirror->pg_recoalesce)
				return 0;
			/* retry add_request for this subreq */
			nfs_page_group_lock(req, false);
			nfs_page_group_lock(req);
			continue;
		}

@@ -1155,7 +1126,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,

	for (midx = 0; midx < desc->pg_mirror_count; midx++) {
		if (midx) {
			nfs_page_group_lock(req, false);
			nfs_page_group_lock(req);

			/* find the last request */
			for (lastreq = req->wb_head;
Loading