Commit 072e5135 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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()
parents d3cd67d6 ed06fce0
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -2382,6 +2382,7 @@ static void nfs_dentry_remove_handle_error(struct inode *dir,
{
	switch (error) {
	case -ENOENT:
		if (d_really_is_positive(dentry))
			d_delete(dentry);
		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
		break;
@@ -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);
+6 −9
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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);
+6 −0
Original line number Diff line number Diff line
@@ -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;
	}

+0 −1
Original line number Diff line number Diff line
@@ -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);
Loading