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()

Changed files
+12 -6
fs
+3 -1
fs/nfs/file.c
··· 617 617 if (result) 618 618 goto out; 619 619 } 620 + if (iocb->ki_pos > i_size_read(inode)) 621 + nfs_revalidate_mapping(inode, file->f_mapping); 620 622 621 623 nfs_start_io_write(inode); 622 624 result = generic_write_checks(iocb, from); ··· 752 750 */ 753 751 nfs_sync_mapping(filp->f_mapping); 754 752 if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) 755 - nfs_zap_mapping(inode, filp->f_mapping); 753 + nfs_zap_caches(inode); 756 754 out: 757 755 return status; 758 756 }
+9 -5
fs/nfs/nfs4proc.c
··· 2236 2236 int openflags) 2237 2237 { 2238 2238 struct nfs_access_entry cache; 2239 - u32 mask; 2239 + u32 mask, flags; 2240 2240 2241 2241 /* access call failed or for some reason the server doesn't 2242 2242 * support any access modes -- defer access call until later */ ··· 2250 2250 */ 2251 2251 if (openflags & __FMODE_EXEC) { 2252 2252 /* ONLY check for exec rights */ 2253 - mask = MAY_EXEC; 2253 + if (S_ISDIR(state->inode->i_mode)) 2254 + mask = NFS4_ACCESS_LOOKUP; 2255 + else 2256 + mask = NFS4_ACCESS_EXECUTE; 2254 2257 } else if ((fmode & FMODE_READ) && !opendata->file_created) 2255 - mask = MAY_READ; 2258 + mask = NFS4_ACCESS_READ; 2256 2259 2257 2260 cache.cred = cred; 2258 2261 cache.jiffies = jiffies; 2259 2262 nfs_access_set_mask(&cache, opendata->o_res.access_result); 2260 2263 nfs_access_add_cache(state->inode, &cache); 2261 2264 2262 - if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0) 2265 + flags = NFS4_ACCESS_READ | NFS4_ACCESS_EXECUTE | NFS4_ACCESS_LOOKUP; 2266 + if ((mask & ~cache.mask & flags) == 0) 2263 2267 return 0; 2264 2268 2265 2269 return -EACCES; ··· 6496 6492 set_current_state(TASK_INTERRUPTIBLE); 6497 6493 spin_unlock_irqrestore(&q->lock, flags); 6498 6494 6499 - freezable_schedule_timeout_interruptible(NFS4_LOCK_MAXTIMEOUT); 6495 + freezable_schedule_timeout(NFS4_LOCK_MAXTIMEOUT); 6500 6496 } 6501 6497 6502 6498 finish_wait(q, &wait);