mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-05 22:12:16 +00:00
Merge branch 'pnfs_generic'
* pnfs_generic: NFSv4.1/pNFS: Cleanup constify struct pnfs_layout_range arguments NFSv4.1/pnfs: Cleanup copying of pnfs_layout_range structures NFSv4.1/pNFS: Cleanup pnfs_mark_matching_lsegs_invalid() NFSv4.1/pNFS: Fix a race in initiate_file_draining() NFSv4.1/pNFS: pnfs_error_mark_layout_for_return() must always return layout NFSv4.1/pNFS: pnfs_mark_matching_lsegs_return() should set the iomode NFSv4.1/pNFS: Use nfs4_stateid_copy for copying stateids NFSv4.1/pNFS: Don't pass stateids by value to pnfs_send_layoutreturn() NFS: Relax requirements in nfs_flush_incompatible NFSv4.1/pNFS: Don't queue up a new commit if the layout segment is invalid NFS: Allow multiple commit requests in flight per file NFS/pNFS: Fix up pNFS write reschedule layering violations and bugs NFSv4: List stateid information in the callback tracepoints NFSv4.1/pNFS: Don't return NFS4ERR_DELAY unnecessarily in CB_LAYOUTRECALL NFSv4.1/pNFS: Ensure we enforce RFC5661 Section 12.5.5.2.1 pNFS: If we have to delay the layout callback, mark the layout for return NFSv4.1/pNFS: Add a helper to mark the layout as returned pNFS: Ensure nfs4_layoutget_prepare returns the correct error
This commit is contained in:
commit
942e3d72a6
15 changed files with 298 additions and 119 deletions
|
@ -21,6 +21,8 @@
|
|||
#include <linux/nfs_page.h>
|
||||
#include <linux/backing-dev.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
|
@ -1155,7 +1157,8 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
|
|||
if (req == NULL)
|
||||
return 0;
|
||||
l_ctx = req->wb_lock_context;
|
||||
do_flush = req->wb_page != page || req->wb_context != ctx;
|
||||
do_flush = req->wb_page != page ||
|
||||
!nfs_match_open_context(req->wb_context, ctx);
|
||||
/* for now, flush if more than 1 request in page_group */
|
||||
do_flush |= req->wb_this_page != req;
|
||||
if (l_ctx && flctx &&
|
||||
|
@ -1353,9 +1356,15 @@ static void nfs_async_write_error(struct list_head *head)
|
|||
}
|
||||
}
|
||||
|
||||
static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr)
|
||||
{
|
||||
nfs_async_write_error(&hdr->pages);
|
||||
}
|
||||
|
||||
static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = {
|
||||
.error_cleanup = nfs_async_write_error,
|
||||
.completion = nfs_write_completion,
|
||||
.reschedule_io = nfs_async_write_reschedule_io,
|
||||
};
|
||||
|
||||
void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
|
@ -1556,27 +1565,29 @@ static void nfs_writeback_result(struct rpc_task *task,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
|
||||
static int nfs_wait_atomic_killable(atomic_t *key)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!test_and_set_bit(NFS_INO_COMMIT, &nfsi->flags))
|
||||
return 1;
|
||||
if (!may_wait)
|
||||
return 0;
|
||||
ret = out_of_line_wait_on_bit_lock(&nfsi->flags,
|
||||
NFS_INO_COMMIT,
|
||||
nfs_wait_bit_killable,
|
||||
TASK_KILLABLE);
|
||||
return (ret < 0) ? ret : 1;
|
||||
if (fatal_signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
freezable_schedule_unsafe();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nfs_commit_clear_lock(struct nfs_inode *nfsi)
|
||||
static int wait_on_commit(struct nfs_mds_commit_info *cinfo)
|
||||
{
|
||||
clear_bit(NFS_INO_COMMIT, &nfsi->flags);
|
||||
smp_mb__after_atomic();
|
||||
wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
|
||||
return wait_on_atomic_t(&cinfo->rpcs_out,
|
||||
nfs_wait_atomic_killable, TASK_KILLABLE);
|
||||
}
|
||||
|
||||
static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
|
||||
{
|
||||
atomic_inc(&cinfo->rpcs_out);
|
||||
}
|
||||
|
||||
static void nfs_commit_end(struct nfs_mds_commit_info *cinfo)
|
||||
{
|
||||
if (atomic_dec_and_test(&cinfo->rpcs_out))
|
||||
wake_up_atomic_t(&cinfo->rpcs_out);
|
||||
}
|
||||
|
||||
void nfs_commitdata_release(struct nfs_commit_data *data)
|
||||
|
@ -1693,6 +1704,13 @@ void nfs_retry_commit(struct list_head *page_list,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_retry_commit);
|
||||
|
||||
static void
|
||||
nfs_commit_resched_write(struct nfs_commit_info *cinfo,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
__set_page_dirty_nobuffers(req->wb_page);
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit dirty pages
|
||||
*/
|
||||
|
@ -1714,7 +1732,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
|
|||
data->mds_ops, how, 0);
|
||||
out_bad:
|
||||
nfs_retry_commit(head, NULL, cinfo, 0);
|
||||
cinfo->completion_ops->error_cleanup(NFS_I(inode));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -1776,8 +1793,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
|
|||
clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
|
||||
|
||||
nfs_init_cinfo(&cinfo, data->inode, data->dreq);
|
||||
if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
|
||||
nfs_commit_clear_lock(NFS_I(data->inode));
|
||||
nfs_commit_end(cinfo.mds);
|
||||
}
|
||||
|
||||
static void nfs_commit_release(void *calldata)
|
||||
|
@ -1796,7 +1812,7 @@ static const struct rpc_call_ops nfs_commit_ops = {
|
|||
|
||||
static const struct nfs_commit_completion_ops nfs_commit_completion_ops = {
|
||||
.completion = nfs_commit_release_pages,
|
||||
.error_cleanup = nfs_commit_clear_lock,
|
||||
.resched_write = nfs_commit_resched_write,
|
||||
};
|
||||
|
||||
int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
|
||||
|
@ -1815,30 +1831,25 @@ int nfs_commit_inode(struct inode *inode, int how)
|
|||
LIST_HEAD(head);
|
||||
struct nfs_commit_info cinfo;
|
||||
int may_wait = how & FLUSH_SYNC;
|
||||
int error = 0;
|
||||
int res;
|
||||
|
||||
res = nfs_commit_set_lock(NFS_I(inode), may_wait);
|
||||
if (res <= 0)
|
||||
goto out_mark_dirty;
|
||||
nfs_init_cinfo_from_inode(&cinfo, inode);
|
||||
nfs_commit_begin(cinfo.mds);
|
||||
res = nfs_scan_commit(inode, &head, &cinfo);
|
||||
if (res) {
|
||||
int error;
|
||||
|
||||
if (res)
|
||||
error = nfs_generic_commit_list(inode, &head, how, &cinfo);
|
||||
if (error < 0)
|
||||
return error;
|
||||
if (!may_wait)
|
||||
goto out_mark_dirty;
|
||||
error = wait_on_bit_action(&NFS_I(inode)->flags,
|
||||
NFS_INO_COMMIT,
|
||||
nfs_wait_bit_killable,
|
||||
TASK_KILLABLE);
|
||||
if (error < 0)
|
||||
return error;
|
||||
} else
|
||||
nfs_commit_clear_lock(NFS_I(inode));
|
||||
nfs_commit_end(cinfo.mds);
|
||||
if (error < 0)
|
||||
goto out_error;
|
||||
if (!may_wait)
|
||||
goto out_mark_dirty;
|
||||
error = wait_on_commit(cinfo.mds);
|
||||
if (error < 0)
|
||||
return error;
|
||||
return res;
|
||||
out_error:
|
||||
res = error;
|
||||
/* Note: If we exit without ensuring that the commit is complete,
|
||||
* we must mark the inode as dirty. Otherwise, future calls to
|
||||
* sync_inode() with the WB_SYNC_ALL flag set will fail to ensure
|
||||
|
@ -1848,6 +1859,7 @@ out_mark_dirty:
|
|||
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_commit_inode);
|
||||
|
||||
int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue