Commit 54df7662 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] bdev: use correct mapping's i_sem

From: viro@parcelfarce.linux.theplanet.co.uk <viro@parcelfarce.linux.theplanet.co.uk>

In a bunch of places we used file->f_dentry->d_inode->i_sem to protect
fdatasync et.al.  Replaced with corrent file->f_mapping->host->i_sem - the
object we are protecting is address_space, so we want an exclusion that would
work for redirected ->i_mapping.  For normal files (not coda, not bdev) it's
all the same, of course - there we have

 	file->f_mapping->host == file->f_dentry->d_inode

and change above is an equivalent transfromation.
parent 32d66678
...@@ -314,8 +314,7 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync) ...@@ -314,8 +314,7 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
asmlinkage long sys_fsync(unsigned int fd) asmlinkage long sys_fsync(unsigned int fd)
{ {
struct file * file; struct file * file;
struct dentry * dentry; struct address_space *mapping;
struct inode * inode;
int ret, err; int ret, err;
ret = -EBADF; ret = -EBADF;
...@@ -323,8 +322,7 @@ asmlinkage long sys_fsync(unsigned int fd) ...@@ -323,8 +322,7 @@ asmlinkage long sys_fsync(unsigned int fd)
if (!file) if (!file)
goto out; goto out;
dentry = file->f_dentry; mapping = file->f_mapping;
inode = dentry->d_inode;
ret = -EINVAL; ret = -EINVAL;
if (!file->f_op || !file->f_op->fsync) { if (!file->f_op || !file->f_op->fsync) {
...@@ -333,17 +331,17 @@ asmlinkage long sys_fsync(unsigned int fd) ...@@ -333,17 +331,17 @@ asmlinkage long sys_fsync(unsigned int fd)
} }
/* We need to protect against concurrent writers.. */ /* We need to protect against concurrent writers.. */
down(&inode->i_sem); down(&mapping->host->i_sem);
current->flags |= PF_SYNCWRITE; current->flags |= PF_SYNCWRITE;
ret = filemap_fdatawrite(inode->i_mapping); ret = filemap_fdatawrite(mapping);
err = file->f_op->fsync(file, dentry, 0); err = file->f_op->fsync(file, file->f_dentry, 0);
if (!ret) if (!ret)
ret = err; ret = err;
err = filemap_fdatawait(inode->i_mapping); err = filemap_fdatawait(mapping);
if (!ret) if (!ret)
ret = err; ret = err;
current->flags &= ~PF_SYNCWRITE; current->flags &= ~PF_SYNCWRITE;
up(&inode->i_sem); up(&mapping->host->i_sem);
out_putf: out_putf:
fput(file); fput(file);
...@@ -354,8 +352,7 @@ asmlinkage long sys_fsync(unsigned int fd) ...@@ -354,8 +352,7 @@ asmlinkage long sys_fsync(unsigned int fd)
asmlinkage long sys_fdatasync(unsigned int fd) asmlinkage long sys_fdatasync(unsigned int fd)
{ {
struct file * file; struct file * file;
struct dentry * dentry; struct address_space *mapping;
struct inode * inode;
int ret, err; int ret, err;
ret = -EBADF; ret = -EBADF;
...@@ -363,24 +360,23 @@ asmlinkage long sys_fdatasync(unsigned int fd) ...@@ -363,24 +360,23 @@ asmlinkage long sys_fdatasync(unsigned int fd)
if (!file) if (!file)
goto out; goto out;
dentry = file->f_dentry;
inode = dentry->d_inode;
ret = -EINVAL; ret = -EINVAL;
if (!file->f_op || !file->f_op->fsync) if (!file->f_op || !file->f_op->fsync)
goto out_putf; goto out_putf;
down(&inode->i_sem); mapping = file->f_mapping;
down(&mapping->host->i_sem);
current->flags |= PF_SYNCWRITE; current->flags |= PF_SYNCWRITE;
ret = filemap_fdatawrite(inode->i_mapping); ret = filemap_fdatawrite(mapping);
err = file->f_op->fsync(file, dentry, 1); err = file->f_op->fsync(file, file->f_dentry, 1);
if (!ret) if (!ret)
ret = err; ret = err;
err = filemap_fdatawait(inode->i_mapping); err = filemap_fdatawait(mapping);
if (!ret) if (!ret)
ret = err; ret = err;
current->flags &= ~PF_SYNCWRITE; current->flags &= ~PF_SYNCWRITE;
up(&inode->i_sem); up(&mapping->host->i_sem);
out_putf: out_putf:
fput(file); fput(file);
......
...@@ -266,7 +266,7 @@ nfs_file_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos) ...@@ -266,7 +266,7 @@ nfs_file_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos)
int int
nfs_lock(struct file *filp, int cmd, struct file_lock *fl) nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
{ {
struct inode * inode = filp->f_dentry->d_inode; struct inode * inode = filp->f_mapping->host;
int status = 0; int status = 0;
int status2; int status2;
...@@ -309,13 +309,13 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -309,13 +309,13 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
* Flush all pending writes before doing anything * Flush all pending writes before doing anything
* with locks.. * with locks..
*/ */
status = filemap_fdatawrite(inode->i_mapping); status = filemap_fdatawrite(filp->f_mapping);
down(&inode->i_sem); down(&inode->i_sem);
status2 = nfs_wb_all(inode); status2 = nfs_wb_all(inode);
if (!status) if (!status)
status = status2; status = status2;
up(&inode->i_sem); up(&inode->i_sem);
status2 = filemap_fdatawait(inode->i_mapping); status2 = filemap_fdatawait(filp->f_mapping);
if (!status) if (!status)
status = status2; status = status2;
if (status < 0) if (status < 0)
...@@ -335,11 +335,11 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -335,11 +335,11 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
*/ */
out_ok: out_ok:
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
filemap_fdatawrite(inode->i_mapping); filemap_fdatawrite(filp->f_mapping);
down(&inode->i_sem); down(&inode->i_sem);
nfs_wb_all(inode); /* we may have slept */ nfs_wb_all(inode); /* we may have slept */
up(&inode->i_sem); up(&inode->i_sem);
filemap_fdatawait(inode->i_mapping); filemap_fdatawait(filp->f_mapping);
nfs_zap_caches(inode); nfs_zap_caches(inode);
} }
return status; return status;
......
...@@ -1970,7 +1970,7 @@ EXPORT_SYMBOL(generic_file_readv); ...@@ -1970,7 +1970,7 @@ EXPORT_SYMBOL(generic_file_readv);
ssize_t generic_file_writev(struct file *file, const struct iovec *iov, ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
unsigned long nr_segs, loff_t * ppos) unsigned long nr_segs, loff_t * ppos)
{ {
struct inode *inode = file->f_dentry->d_inode; struct inode *inode = file->f_mapping->host;
ssize_t ret; ssize_t ret;
down(&inode->i_sem); down(&inode->i_sem);
......
...@@ -146,20 +146,20 @@ static int msync_interval(struct vm_area_struct * vma, ...@@ -146,20 +146,20 @@ static int msync_interval(struct vm_area_struct * vma,
ret = filemap_sync(vma, start, end-start, flags); ret = filemap_sync(vma, start, end-start, flags);
if (!ret && (flags & MS_SYNC)) { if (!ret && (flags & MS_SYNC)) {
struct inode *inode = file->f_dentry->d_inode; struct address_space *mapping = file->f_mapping;
int err; int err;
down(&inode->i_sem); down(&mapping->host->i_sem);
ret = filemap_fdatawrite(inode->i_mapping); ret = filemap_fdatawrite(mapping);
if (file->f_op && file->f_op->fsync) { if (file->f_op && file->f_op->fsync) {
err = file->f_op->fsync(file,file->f_dentry,1); err = file->f_op->fsync(file,file->f_dentry,1);
if (err && !ret) if (err && !ret)
ret = err; ret = err;
} }
err = filemap_fdatawait(inode->i_mapping); err = filemap_fdatawait(mapping);
if (!ret) if (!ret)
ret = err; ret = err;
up(&inode->i_sem); up(&mapping->host->i_sem);
} }
} }
return ret; return ret;
......
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