提交 f6032f21 编写于 作者: T Trond Myklebust

NFS: Teach nfs_try_to_update_request() to deal with request page_groups

Simplify the code, and avoid some flushes to disk.
Signed-off-by: NTrond Myklebust <trond.myklebust@primarydata.com>
上级 b66aaa8d
...@@ -1107,39 +1107,19 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, ...@@ -1107,39 +1107,19 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
end = offset + bytes; end = offset + bytes;
for (;;) { req = nfs_lock_and_join_requests(page);
if (!(PagePrivate(page) || PageSwapCache(page))) if (IS_ERR_OR_NULL(req))
return NULL; return req;
spin_lock(&inode->i_lock);
req = nfs_page_find_head_request_locked(NFS_I(inode), page);
if (req == NULL)
goto out_unlock;
/* should be handled by nfs_flush_incompatible */
WARN_ON_ONCE(req->wb_head != req);
WARN_ON_ONCE(req->wb_this_page != req);
rqend = req->wb_offset + req->wb_bytes;
/*
* Tell the caller to flush out the request if
* the offsets are non-contiguous.
* Note: nfs_flush_incompatible() will already
* have flushed out requests having wrong owners.
*/
if (offset > rqend
|| end < req->wb_offset)
goto out_flushme;
if (nfs_lock_request(req))
break;
/* The request is locked, so wait and then retry */ rqend = req->wb_offset + req->wb_bytes;
spin_unlock(&inode->i_lock); /*
error = nfs_wait_on_request(req); * Tell the caller to flush out the request if
nfs_release_request(req); * the offsets are non-contiguous.
if (error != 0) * Note: nfs_flush_incompatible() will already
goto out_err; * have flushed out requests having wrong owners.
} */
if (offset > rqend || end < req->wb_offset)
goto out_flushme;
/* Okay, the request matches. Update the region */ /* Okay, the request matches. Update the region */
if (offset < req->wb_offset) { if (offset < req->wb_offset) {
...@@ -1150,17 +1130,17 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, ...@@ -1150,17 +1130,17 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
req->wb_bytes = end - req->wb_offset; req->wb_bytes = end - req->wb_offset;
else else
req->wb_bytes = rqend - req->wb_offset; req->wb_bytes = rqend - req->wb_offset;
out_unlock:
if (req)
nfs_clear_request_commit(req);
spin_unlock(&inode->i_lock);
return req; return req;
out_flushme: out_flushme:
spin_unlock(&inode->i_lock); /*
nfs_release_request(req); * Note: we mark the request dirty here because
* nfs_lock_and_join_requests() cannot preserve
* commit flags, so we have to replay the write.
*/
nfs_mark_request_dirty(req);
nfs_unlock_and_release_request(req);
error = nfs_wb_page(inode, page); error = nfs_wb_page(inode, page);
out_err: return (error < 0) ? ERR_PTR(error) : NULL;
return ERR_PTR(error);
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册