mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'nfs-for-5.20-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client fixes from Trond Myklebust:
"Stable fixes:
- NFS: Fix another fsync() issue after a server reboot
Bugfixes:
- NFS: unlink/rmdir shouldn't call d_delete() twice on ENOENT
- NFS: Fix missing unlock in nfs_unlink()
- Add sanity checking of the file type used by __nfs42_ssc_open
- Fix a case where we're failing to set task->tk_rpc_status
Cleanups:
- Remove the NFS_CONTEXT_RESEND_WRITES flag that got obsoleted by the
fsync() fix"
* tag 'nfs-for-5.20-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
SUNRPC: RPC level errors should set task->tk_rpc_status
NFSv4.2 fix problems with __nfs42_ssc_open
NFS: unlink/rmdir shouldn't call d_delete() twice on ENOENT
NFS: Cleanup to remove unused flag NFS_CONTEXT_RESEND_WRITES
NFS: Remove a bogus flag setting in pnfs_write_done_resend_to_mds
NFS: Fix another fsync() issue after a server reboot
NFS: Fix missing unlock in nfs_unlink()
This commit is contained in:
@@ -2382,7 +2382,8 @@ static void nfs_dentry_remove_handle_error(struct inode *dir,
|
||||
{
|
||||
switch (error) {
|
||||
case -ENOENT:
|
||||
d_delete(dentry);
|
||||
if (d_really_is_positive(dentry))
|
||||
d_delete(dentry);
|
||||
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
||||
break;
|
||||
case 0:
|
||||
@@ -2484,8 +2485,10 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
|
||||
*/
|
||||
error = -ETXTBSY;
|
||||
if (WARN_ON(dentry->d_flags & DCACHE_NFSFS_RENAMED) ||
|
||||
WARN_ON(dentry->d_fsdata == NFS_FSDATA_BLOCKED))
|
||||
WARN_ON(dentry->d_fsdata == NFS_FSDATA_BLOCKED)) {
|
||||
spin_unlock(&dentry->d_lock);
|
||||
goto out;
|
||||
}
|
||||
if (dentry->d_fsdata)
|
||||
/* old devname */
|
||||
kfree(dentry->d_fsdata);
|
||||
|
||||
@@ -221,8 +221,10 @@ nfs_file_fsync_commit(struct file *file, int datasync)
|
||||
int
|
||||
nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
{
|
||||
struct nfs_open_context *ctx = nfs_file_open_context(file);
|
||||
struct inode *inode = file_inode(file);
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
long save_nredirtied = atomic_long_read(&nfsi->redirtied_pages);
|
||||
long nredirtied;
|
||||
int ret;
|
||||
|
||||
trace_nfs_fsync_enter(inode);
|
||||
@@ -237,15 +239,10 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
ret = pnfs_sync_inode(inode, !!datasync);
|
||||
if (ret != 0)
|
||||
break;
|
||||
if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags))
|
||||
nredirtied = atomic_long_read(&nfsi->redirtied_pages);
|
||||
if (nredirtied == save_nredirtied)
|
||||
break;
|
||||
/*
|
||||
* If nfs_file_fsync_commit detected a server reboot, then
|
||||
* resend all dirty pages that might have been covered by
|
||||
* the NFS_CONTEXT_RESEND_WRITES flag
|
||||
*/
|
||||
start = 0;
|
||||
end = LLONG_MAX;
|
||||
save_nredirtied = nredirtied;
|
||||
}
|
||||
|
||||
trace_nfs_fsync_exit(inode, ret);
|
||||
|
||||
@@ -426,6 +426,7 @@ nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh)
|
||||
static void nfs_inode_init_regular(struct nfs_inode *nfsi)
|
||||
{
|
||||
atomic_long_set(&nfsi->nrequests, 0);
|
||||
atomic_long_set(&nfsi->redirtied_pages, 0);
|
||||
INIT_LIST_HEAD(&nfsi->commit_info.list);
|
||||
atomic_long_set(&nfsi->commit_info.ncommit, 0);
|
||||
atomic_set(&nfsi->commit_info.rpcs_out, 0);
|
||||
|
||||
@@ -340,6 +340,11 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!S_ISREG(fattr->mode)) {
|
||||
res = ERR_PTR(-EBADF);
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = ERR_PTR(-ENOMEM);
|
||||
len = strlen(SSC_READ_NAME_BODY) + 16;
|
||||
read_name = kzalloc(len, GFP_KERNEL);
|
||||
@@ -357,6 +362,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
|
||||
r_ino->i_fop);
|
||||
if (IS_ERR(filep)) {
|
||||
res = ERR_CAST(filep);
|
||||
iput(r_ino);
|
||||
goto out_free_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -2817,7 +2817,6 @@ int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *hdr)
|
||||
/* Resend all requests through the MDS */
|
||||
nfs_pageio_init_write(&pgio, hdr->inode, FLUSH_STABLE, true,
|
||||
hdr->completion_ops);
|
||||
set_bit(NFS_CONTEXT_RESEND_WRITES, &hdr->args.context->flags);
|
||||
return nfs_pageio_resend(&pgio, hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_write_done_resend_to_mds);
|
||||
|
||||
@@ -1420,10 +1420,12 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr,
|
||||
*/
|
||||
static void nfs_redirty_request(struct nfs_page *req)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(page_file_mapping(req->wb_page)->host);
|
||||
|
||||
/* Bump the transmission count */
|
||||
req->wb_nio++;
|
||||
nfs_mark_request_dirty(req);
|
||||
set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags);
|
||||
atomic_long_inc(&nfsi->redirtied_pages);
|
||||
nfs_end_page_writeback(req);
|
||||
nfs_release_request(req);
|
||||
}
|
||||
@@ -1904,7 +1906,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
|
||||
/* We have a mismatch. Write the page again */
|
||||
dprintk_cont(" mismatch\n");
|
||||
nfs_mark_request_dirty(req);
|
||||
set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags);
|
||||
atomic_long_inc(&NFS_I(data->inode)->redirtied_pages);
|
||||
next:
|
||||
nfs_unlock_and_release_request(req);
|
||||
/* Latency breaker */
|
||||
|
||||
@@ -83,7 +83,6 @@ struct nfs_open_context {
|
||||
fmode_t mode;
|
||||
|
||||
unsigned long flags;
|
||||
#define NFS_CONTEXT_RESEND_WRITES (1)
|
||||
#define NFS_CONTEXT_BAD (2)
|
||||
#define NFS_CONTEXT_UNLOCK (3)
|
||||
#define NFS_CONTEXT_FILE_OPEN (4)
|
||||
@@ -182,6 +181,7 @@ struct nfs_inode {
|
||||
/* Regular file */
|
||||
struct {
|
||||
atomic_long_t nrequests;
|
||||
atomic_long_t redirtied_pages;
|
||||
struct nfs_mds_commit_info commit_info;
|
||||
struct mutex commit_mutex;
|
||||
};
|
||||
|
||||
@@ -1902,7 +1902,7 @@ call_encode(struct rpc_task *task)
|
||||
break;
|
||||
case -EKEYEXPIRED:
|
||||
if (!task->tk_cred_retry) {
|
||||
rpc_exit(task, task->tk_status);
|
||||
rpc_call_rpcerror(task, task->tk_status);
|
||||
} else {
|
||||
task->tk_action = call_refresh;
|
||||
task->tk_cred_retry--;
|
||||
|
||||
Reference in New Issue
Block a user