Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 286ba844 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfs-for-4.13-3' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client fixes from Anna Schumaker:
 "More NFS client bugfixes for 4.13.

  Most of these fix locking bugs that Ben and Neil noticed, but I also
  have a patch to fix one more access bug that was reported after last
  week.

  Stable fixes:
   - Fix a race where CB_NOTIFY_LOCK fails to wake a waiter
   - Invalidate file size when taking a lock to prevent corruption

  Other fixes:
   - Don't excessively generate tiny writes with fallocate
   - Use the raw NFS access mask in nfs4_opendata_access()"

* tag 'nfs-for-4.13-3' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  NFSv4.1: Fix a race where CB_NOTIFY_LOCK fails to wake a waiter
  NFS: Optimize fallocate by refreshing mapping when needed.
  NFS: invalidate file size when taking a lock.
  NFS: Use raw NFS access mask in nfs4_opendata_access()
parents 19993e73 b7dbcc0e
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -617,6 +617,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
		if (result)
			goto out;
	}
	if (iocb->ki_pos > i_size_read(inode))
		nfs_revalidate_mapping(inode, file->f_mapping);

	nfs_start_io_write(inode);
	result = generic_write_checks(iocb, from);
@@ -750,7 +752,7 @@ do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
	 */
	nfs_sync_mapping(filp->f_mapping);
	if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
		nfs_zap_mapping(inode, filp->f_mapping);
		nfs_zap_caches(inode);
out:
	return status;
}
+9 −5
Original line number Diff line number Diff line
@@ -2236,7 +2236,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
				int openflags)
{
	struct nfs_access_entry cache;
	u32 mask;
	u32 mask, flags;

	/* access call failed or for some reason the server doesn't
	 * support any access modes -- defer access call until later */
@@ -2250,16 +2250,20 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
	 */
	if (openflags & __FMODE_EXEC) {
		/* ONLY check for exec rights */
		mask = MAY_EXEC;
		if (S_ISDIR(state->inode->i_mode))
			mask = NFS4_ACCESS_LOOKUP;
		else
			mask = NFS4_ACCESS_EXECUTE;
	} else if ((fmode & FMODE_READ) && !opendata->file_created)
		mask = MAY_READ;
		mask = NFS4_ACCESS_READ;

	cache.cred = cred;
	cache.jiffies = jiffies;
	nfs_access_set_mask(&cache, opendata->o_res.access_result);
	nfs_access_add_cache(state->inode, &cache);

	if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0)
	flags = NFS4_ACCESS_READ | NFS4_ACCESS_EXECUTE | NFS4_ACCESS_LOOKUP;
	if ((mask & ~cache.mask & flags) == 0)
		return 0;

	return -EACCES;
@@ -6492,7 +6496,7 @@ nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
		set_current_state(TASK_INTERRUPTIBLE);
		spin_unlock_irqrestore(&q->lock, flags);

		freezable_schedule_timeout_interruptible(NFS4_LOCK_MAXTIMEOUT);
		freezable_schedule_timeout(NFS4_LOCK_MAXTIMEOUT);
	}

	finish_wait(q, &wait);