summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 20:11:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 20:11:47 -0500
commit33caf82acf4dc420bf0f0136b886f7b27ecf90c5 (patch)
treeb24b0b5c8f257ae7db3b8df939821a0856869895 /fs/nfsd/vfs.c
parentca9706a282943899981e83604f2ed13e88ce4239 (diff)
parentbbddca8e8fac07ece3938e03526b5d00fa791a4c (diff)
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro: "All kinds of stuff. That probably should've been 5 or 6 separate branches, but by the time I'd realized how large and mixed that bag had become it had been too close to -final to play with rebasing. Some fs/namei.c cleanups there, memdup_user_nul() introduction and switching open-coded instances, burying long-dead code, whack-a-mole of various kinds, several new helpers for ->llseek(), assorted cleanups and fixes from various people, etc. One piece probably deserves special mention - Neil's lookup_one_len_unlocked(). Similar to lookup_one_len(), but gets called without ->i_mutex and tries to avoid ever taking it. That, of course, means that it's not useful for any directory modifications, but things like getting inode attributes in nfds readdirplus are fine with that. I really should've asked for moratorium on lookup-related changes this cycle, but since I hadn't done that early enough... I *am* asking for that for the coming cycle, though - I'm going to try and get conversion of i_mutex to rwsem with ->lookup() done under lock taken shared. There will be a patch closer to the end of the window, along the lines of the one Linus had posted last May - mechanical conversion of ->i_mutex accesses to inode_lock()/inode_unlock()/inode_trylock()/ inode_is_locked()/inode_lock_nested(). To quote Linus back then: ----- | This is an automated patch using | | sed 's/mutex_lock(&\(.*\)->i_mutex)/inode_lock(\1)/' | sed 's/mutex_unlock(&\(.*\)->i_mutex)/inode_unlock(\1)/' | sed 's/mutex_lock_nested(&\(.*\)->i_mutex,[ ]*I_MUTEX_\([A-Z0-9_]*\))/inode_lock_nested(\1, I_MUTEX_\2)/' | sed 's/mutex_is_locked(&\(.*\)->i_mutex)/inode_is_locked(\1)/' | sed 's/mutex_trylock(&\(.*\)->i_mutex)/inode_trylock(\1)/' | | with a very few manual fixups ----- I'm going to send that once the ->i_mutex-affecting stuff in -next gets mostly merged (or when Linus says he's about to stop taking merges)" * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits) nfsd: don't hold i_mutex over userspace upcalls fs:affs:Replace time_t with time64_t fs/9p: use fscache mutex rather than spinlock proc: add a reschedule point in proc_readfd_common() logfs: constify logfs_block_ops structures fcntl: allow to set O_DIRECT flag on pipe fs: __generic_file_splice_read retry lookup on AOP_TRUNCATED_PAGE fs: xattr: Use kvfree() [s390] page_to_phys() always returns a multiple of PAGE_SIZE nbd: use ->compat_ioctl() fs: use block_device name vsprintf helper lib/vsprintf: add %*pg format specifier fs: use gendisk->disk_name where possible poll: plug an unused argument to do_poll amdkfd: don't open-code memdup_user() cdrom: don't open-code memdup_user() rsxx: don't open-code memdup_user() mtip32xx: don't open-code memdup_user() [um] mconsole: don't open-code memdup_user_nul() [um] hostaudio: don't open-code memdup_user() ...
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 5411bf09b810..d41c149fae75 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -218,10 +218,16 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
218 host_err = PTR_ERR(dentry); 218 host_err = PTR_ERR(dentry);
219 if (IS_ERR(dentry)) 219 if (IS_ERR(dentry))
220 goto out_nfserr; 220 goto out_nfserr;
221 /*
222 * check if we have crossed a mount point ...
223 */
224 if (nfsd_mountpoint(dentry, exp)) { 221 if (nfsd_mountpoint(dentry, exp)) {
222 /*
223 * We don't need the i_mutex after all. It's
224 * still possible we could open this (regular
225 * files can be mountpoints too), but the
226 * i_mutex is just there to prevent renames of
227 * something that we might be about to delegate,
228 * and a mountpoint won't be renamed:
229 */
230 fh_unlock(fhp);
225 if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { 231 if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
226 dput(dentry); 232 dput(dentry);
227 goto out_nfserr; 233 goto out_nfserr;
@@ -1817,7 +1823,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
1817 offset = *offsetp; 1823 offset = *offsetp;
1818 1824
1819 while (1) { 1825 while (1) {
1820 struct inode *dir_inode = file_inode(file);
1821 unsigned int reclen; 1826 unsigned int reclen;
1822 1827
1823 cdp->err = nfserr_eof; /* will be cleared on successful read */ 1828 cdp->err = nfserr_eof; /* will be cleared on successful read */
@@ -1836,15 +1841,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
1836 if (!size) 1841 if (!size)
1837 break; 1842 break;
1838 1843
1839 /*
1840 * Various filldir functions may end up calling back into
1841 * lookup_one_len() and the file system's ->lookup() method.
1842 * These expect i_mutex to be held, as it would within readdir.
1843 */
1844 host_err = mutex_lock_killable(&dir_inode->i_mutex);
1845 if (host_err)
1846 break;
1847
1848 de = (struct buffered_dirent *)buf.dirent; 1844 de = (struct buffered_dirent *)buf.dirent;
1849 while (size > 0) { 1845 while (size > 0) {
1850 offset = de->offset; 1846 offset = de->offset;
@@ -1861,7 +1857,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
1861 size -= reclen; 1857 size -= reclen;
1862 de = (struct buffered_dirent *)((char *)de + reclen); 1858 de = (struct buffered_dirent *)((char *)de + reclen);
1863 } 1859 }
1864 mutex_unlock(&dir_inode->i_mutex);
1865 if (size > 0) /* We bailed out early */ 1860 if (size > 0) /* We bailed out early */
1866 break; 1861 break;
1867 1862