diff options
author | Christoph Hellwig <hch@lst.de> | 2008-12-22 15:11:15 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-01-05 11:54:28 -0500 |
commit | 4c728ef583b3d82266584da5cb068294c09df31e (patch) | |
tree | 1252fa82b5a7cf60c0898c3da810228b4c34ebb3 /drivers/usb/gadget/file_storage.c | |
parent | 6110e3abbff8b785907d4db50240e63c1be726e3 (diff) |
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>
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 18 |
1 files changed, 1 insertions, 17 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index c4e62a6297d7..2e71368f45b4 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -1863,26 +1863,10 @@ static int do_write(struct fsg_dev *fsg) | |||
1863 | static int fsync_sub(struct lun *curlun) | 1863 | static int fsync_sub(struct lun *curlun) |
1864 | { | 1864 | { |
1865 | struct file *filp = curlun->filp; | 1865 | struct file *filp = curlun->filp; |
1866 | struct inode *inode; | ||
1867 | int rc, err; | ||
1868 | 1866 | ||
1869 | if (curlun->ro || !filp) | 1867 | if (curlun->ro || !filp) |
1870 | return 0; | 1868 | return 0; |
1871 | if (!filp->f_op->fsync) | 1869 | return vfs_fsync(filp, filp->f_path.dentry, 1); |
1872 | return -EINVAL; | ||
1873 | |||
1874 | inode = filp->f_path.dentry->d_inode; | ||
1875 | mutex_lock(&inode->i_mutex); | ||
1876 | rc = filemap_fdatawrite(inode->i_mapping); | ||
1877 | err = filp->f_op->fsync(filp, filp->f_path.dentry, 1); | ||
1878 | if (!rc) | ||
1879 | rc = err; | ||
1880 | err = filemap_fdatawait(inode->i_mapping); | ||
1881 | if (!rc) | ||
1882 | rc = err; | ||
1883 | mutex_unlock(&inode->i_mutex); | ||
1884 | VLDBG(curlun, "fdatasync -> %d\n", rc); | ||
1885 | return rc; | ||
1886 | } | 1870 | } |
1887 | 1871 | ||
1888 | static void fsync_all(struct fsg_dev *fsg) | 1872 | static void fsync_all(struct fsg_dev *fsg) |