Commit d5e66348 authored by Trond Myklebust's avatar Trond Myklebust

NFS: Fix nfs_file_llseek()

After the BKL removal patches were applied to the rest of the NFS code, the
BKL protection in nfs_file_llseek() is no longer sufficient to ensure that
inode->i_size is read safely in generic_file_llseek_unlocked().

In order to fix the situation, we either have to replace the naked read of
inode->i_size in generic_file_llseek_unlocked() with i_size_read(), or the
whole thing needs to be executed under the inode->i_lock;
In order to avoid disrupting other filesystems, avoid touching
generic_file_llseek_unlocked() for now...
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 4330ed8e
...@@ -188,13 +188,16 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) ...@@ -188,13 +188,16 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
/* origin == SEEK_END => we must revalidate the cached file length */ /* origin == SEEK_END => we must revalidate the cached file length */
if (origin == SEEK_END) { if (origin == SEEK_END) {
struct inode *inode = filp->f_mapping->host; struct inode *inode = filp->f_mapping->host;
int retval = nfs_revalidate_file_size(inode, filp); int retval = nfs_revalidate_file_size(inode, filp);
if (retval < 0) if (retval < 0)
return (loff_t)retval; return (loff_t)retval;
}
lock_kernel(); /* BKL needed? */ spin_lock(&inode->i_lock);
loff = generic_file_llseek_unlocked(filp, offset, origin); loff = generic_file_llseek_unlocked(filp, offset, origin);
unlock_kernel(); spin_unlock(&inode->i_lock);
} else
loff = generic_file_llseek_unlocked(filp, offset, origin);
return loff; return loff;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment