mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
NFS client bugfixes for Linux 6.0
Highlights include: 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 flag NFS_CONTEXT_RESEND_WRITES that got obsoleted by the fsync() fix -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEESQctxSBg8JpV8KqEZwvnipYKAPIFAmMDk3wACgkQZwvnipYK APJLpw/+ONqG16L5W31/BzGJ80DlG9CERMad7Yt8+lk+ih574k/OrCotHThMyBm9 2TfY3S8zD9QoLnsPesDKeoc6AYyL3el0Wo2vKmWlGvrirvrzNt9nMc61CDMs2IHT kN7gjO2P1LCZln8GTE87C4tI3Pg0Cwr4UUlyHHjMSKdYuJckJugj1gDvblSjn5h4 bGKGEJ9G71G1REn013sVqmQ6huvQ3iif07X5NaN7T5e+TpNFet/0AlTmrA9zsUDI WPm+efP+ieTmihvhqOSYdV31uHN/ECx4p60ITzAlWwPYPyXr1M0r9acUGX10ENna eX1B9nyxbUAzO6rxxPgXi3LXgvmgRDVEmbSs5IL985XR2zsVR+AF3dgAwoJXqV9y 7mAtoiwyqe3idvaK+mHU4OWCSqdhZbauJJ+Jc0ZHZHy2vzHPS2CWcpvXHjVTw63R txOkUFL89SwnqJv03N6CZt4OyY1av97dDOEvPqHuRx4NyfT3v/QvF5W3V/UvLnt2 hTPNGIRUPZU1lpfqEgd7NXWO6LLtkWK2MciRGVnSFf2S5uKYqvlbPsVqWc6CviXc Mu4o2RoctkIwxexSfHY0p7UQrbu3OvYgTuIzgy6cIZ2GK70L29UpJYBe5YEh9Qru J/Pgn1ZSdGgDgwqzR8S92PTbbKq1caOqnGReFdyJDnCetb6LrrA= =tpKO -----END PGP SIGNATURE----- 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:
commit
072e51356c
@ -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--;
|
||||
|
Loading…
Reference in New Issue
Block a user