Skip to content

Commit 072e513

Browse files
committed
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()
2 parents d3cd67d + ed06fce commit 072e513

8 files changed

Lines changed: 24 additions & 16 deletions

File tree

fs/nfs/dir.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2382,7 +2382,8 @@ static void nfs_dentry_remove_handle_error(struct inode *dir,
23822382
{
23832383
switch (error) {
23842384
case -ENOENT:
2385-
d_delete(dentry);
2385+
if (d_really_is_positive(dentry))
2386+
d_delete(dentry);
23862387
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
23872388
break;
23882389
case 0:
@@ -2484,8 +2485,10 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
24842485
*/
24852486
error = -ETXTBSY;
24862487
if (WARN_ON(dentry->d_flags & DCACHE_NFSFS_RENAMED) ||
2487-
WARN_ON(dentry->d_fsdata == NFS_FSDATA_BLOCKED))
2488+
WARN_ON(dentry->d_fsdata == NFS_FSDATA_BLOCKED)) {
2489+
spin_unlock(&dentry->d_lock);
24882490
goto out;
2491+
}
24892492
if (dentry->d_fsdata)
24902493
/* old devname */
24912494
kfree(dentry->d_fsdata);

fs/nfs/file.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,10 @@ nfs_file_fsync_commit(struct file *file, int datasync)
221221
int
222222
nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
223223
{
224-
struct nfs_open_context *ctx = nfs_file_open_context(file);
225224
struct inode *inode = file_inode(file);
225+
struct nfs_inode *nfsi = NFS_I(inode);
226+
long save_nredirtied = atomic_long_read(&nfsi->redirtied_pages);
227+
long nredirtied;
226228
int ret;
227229

228230
trace_nfs_fsync_enter(inode);
@@ -237,15 +239,10 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
237239
ret = pnfs_sync_inode(inode, !!datasync);
238240
if (ret != 0)
239241
break;
240-
if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags))
242+
nredirtied = atomic_long_read(&nfsi->redirtied_pages);
243+
if (nredirtied == save_nredirtied)
241244
break;
242-
/*
243-
* If nfs_file_fsync_commit detected a server reboot, then
244-
* resend all dirty pages that might have been covered by
245-
* the NFS_CONTEXT_RESEND_WRITES flag
246-
*/
247-
start = 0;
248-
end = LLONG_MAX;
245+
save_nredirtied = nredirtied;
249246
}
250247

251248
trace_nfs_fsync_exit(inode, ret);

fs/nfs/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh)
426426
static void nfs_inode_init_regular(struct nfs_inode *nfsi)
427427
{
428428
atomic_long_set(&nfsi->nrequests, 0);
429+
atomic_long_set(&nfsi->redirtied_pages, 0);
429430
INIT_LIST_HEAD(&nfsi->commit_info.list);
430431
atomic_long_set(&nfsi->commit_info.ncommit, 0);
431432
atomic_set(&nfsi->commit_info.rpcs_out, 0);

fs/nfs/nfs4file.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
340340
goto out;
341341
}
342342

343+
if (!S_ISREG(fattr->mode)) {
344+
res = ERR_PTR(-EBADF);
345+
goto out;
346+
}
347+
343348
res = ERR_PTR(-ENOMEM);
344349
len = strlen(SSC_READ_NAME_BODY) + 16;
345350
read_name = kzalloc(len, GFP_KERNEL);
@@ -357,6 +362,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
357362
r_ino->i_fop);
358363
if (IS_ERR(filep)) {
359364
res = ERR_CAST(filep);
365+
iput(r_ino);
360366
goto out_free_name;
361367
}
362368

fs/nfs/pnfs.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2817,7 +2817,6 @@ int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *hdr)
28172817
/* Resend all requests through the MDS */
28182818
nfs_pageio_init_write(&pgio, hdr->inode, FLUSH_STABLE, true,
28192819
hdr->completion_ops);
2820-
set_bit(NFS_CONTEXT_RESEND_WRITES, &hdr->args.context->flags);
28212820
return nfs_pageio_resend(&pgio, hdr);
28222821
}
28232822
EXPORT_SYMBOL_GPL(pnfs_write_done_resend_to_mds);

fs/nfs/write.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,10 +1420,12 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr,
14201420
*/
14211421
static void nfs_redirty_request(struct nfs_page *req)
14221422
{
1423+
struct nfs_inode *nfsi = NFS_I(page_file_mapping(req->wb_page)->host);
1424+
14231425
/* Bump the transmission count */
14241426
req->wb_nio++;
14251427
nfs_mark_request_dirty(req);
1426-
set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags);
1428+
atomic_long_inc(&nfsi->redirtied_pages);
14271429
nfs_end_page_writeback(req);
14281430
nfs_release_request(req);
14291431
}
@@ -1904,7 +1906,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
19041906
/* We have a mismatch. Write the page again */
19051907
dprintk_cont(" mismatch\n");
19061908
nfs_mark_request_dirty(req);
1907-
set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags);
1909+
atomic_long_inc(&NFS_I(data->inode)->redirtied_pages);
19081910
next:
19091911
nfs_unlock_and_release_request(req);
19101912
/* Latency breaker */

include/linux/nfs_fs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ struct nfs_open_context {
8383
fmode_t mode;
8484

8585
unsigned long flags;
86-
#define NFS_CONTEXT_RESEND_WRITES (1)
8786
#define NFS_CONTEXT_BAD (2)
8887
#define NFS_CONTEXT_UNLOCK (3)
8988
#define NFS_CONTEXT_FILE_OPEN (4)
@@ -182,6 +181,7 @@ struct nfs_inode {
182181
/* Regular file */
183182
struct {
184183
atomic_long_t nrequests;
184+
atomic_long_t redirtied_pages;
185185
struct nfs_mds_commit_info commit_info;
186186
struct mutex commit_mutex;
187187
};

net/sunrpc/clnt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1902,7 +1902,7 @@ call_encode(struct rpc_task *task)
19021902
break;
19031903
case -EKEYEXPIRED:
19041904
if (!task->tk_cred_retry) {
1905-
rpc_exit(task, task->tk_status);
1905+
rpc_call_rpcerror(task, task->tk_status);
19061906
} else {
19071907
task->tk_action = call_refresh;
19081908
task->tk_cred_retry--;

0 commit comments

Comments
 (0)