add a vfs_fsync helper
Fsync currently has a fdatawrite/fdatawait pair around the method call, and a mutex_lock/unlock of the inode mutex. All callers of fsync have to duplicate this, but we have a few and most of them don't quite get it right. This patch adds a new vfs_fsync that takes care of this. It's a little more complicated as usual as ->fsync might get a NULL file pointer and just a dentry from nfsd, but otherwise gets afile and we want to take the mapping and file operations from it when it is there. Notes on the fsync callers: - ecryptfs wasn't calling filemap_fdatawrite / filemap_fdatawait on the lower file - coda wasn't calling filemap_fdatawrite / filemap_fdatawait on the host file, and returning 0 when ->fsync was missing - shm wasn't calling either filemap_fdatawrite / filemap_fdatawait nor taking i_mutex. Now given that shared memory doesn't have disk backing not doing anything in fsync seems fine and I left it out of the vfs_fsync conversion for now, but in that case we might just not pass it through to the lower file at all but just call the no-op simple_sync_file directly. [and now actually export vfs_fsync] Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
committed by
Al Viro
parent
6110e3abbf
commit
4c728ef583
@@ -1863,26 +1863,10 @@ static int do_write(struct fsg_dev *fsg)
|
||||
static int fsync_sub(struct lun *curlun)
|
||||
{
|
||||
struct file *filp = curlun->filp;
|
||||
struct inode *inode;
|
||||
int rc, err;
|
||||
|
||||
if (curlun->ro || !filp)
|
||||
return 0;
|
||||
if (!filp->f_op->fsync)
|
||||
return -EINVAL;
|
||||
|
||||
inode = filp->f_path.dentry->d_inode;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
rc = filemap_fdatawrite(inode->i_mapping);
|
||||
err = filp->f_op->fsync(filp, filp->f_path.dentry, 1);
|
||||
if (!rc)
|
||||
rc = err;
|
||||
err = filemap_fdatawait(inode->i_mapping);
|
||||
if (!rc)
|
||||
rc = err;
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
VLDBG(curlun, "fdatasync -> %d\n", rc);
|
||||
return rc;
|
||||
return vfs_fsync(filp, filp->f_path.dentry, 1);
|
||||
}
|
||||
|
||||
static void fsync_all(struct fsg_dev *fsg)
|
||||
|
Reference in New Issue
Block a user