aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-07-16 20:44:56 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 20:47:59 -0400
commit02c24a82187d5a628c68edfe71ae60dc135cd178 (patch)
treec8dbaba4d82e2b20ed4335910a564a1f7d90fcf6 /drivers
parent22735068d53c7115e384bc88dea95b17e76a6839 (diff)
fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers
Btrfs needs to be able to control how filemap_write_and_wait_range() is called in fsync to make it less of a painful operation, so push down taking i_mutex and the calling of filemap_write_and_wait() down into the ->fsync() handlers. Some file systems can drop taking the i_mutex altogether it seems, like ext3 and ocfs2. For correctness sake I just pushed everything down in all cases to make sure that we keep the current behavior the same for everybody, and then each individual fs maintainer can make up their mind about what to do from there. Thanks, Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/ps3flash.c9
-rw-r--r--drivers/mtd/ubi/cdev.c10
-rw-r--r--drivers/staging/pohmelfs/inode.c11
-rw-r--r--drivers/usb/gadget/printer.c5
-rw-r--r--drivers/video/fb_defio.c11
5 files changed, 35 insertions, 11 deletions
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index 5a06787e5be3..d0c57c2e2909 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -309,9 +309,14 @@ static int ps3flash_flush(struct file *file, fl_owner_t id)
309 return ps3flash_writeback(ps3flash_dev); 309 return ps3flash_writeback(ps3flash_dev);
310} 310}
311 311
312static int ps3flash_fsync(struct file *file, int datasync) 312static int ps3flash_fsync(struct file *file, loff_t start, loff_t end, int datasync)
313{ 313{
314 return ps3flash_writeback(ps3flash_dev); 314 struct inode *inode = file->f_path.dentry->d_inode;
315 int err;
316 mutex_lock(&inode->i_mutex);
317 err = ps3flash_writeback(ps3flash_dev);
318 mutex_unlock(&inode->i_mutex);
319 return err;
315} 320}
316 321
317static irqreturn_t ps3flash_interrupt(int irq, void *data) 322static irqreturn_t ps3flash_interrupt(int irq, void *data)
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 191f3bb3c41a..3320a50ba4f0 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -189,12 +189,16 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
189 return new_offset; 189 return new_offset;
190} 190}
191 191
192static int vol_cdev_fsync(struct file *file, int datasync) 192static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, int datasync)
193{ 193{
194 struct ubi_volume_desc *desc = file->private_data; 194 struct ubi_volume_desc *desc = file->private_data;
195 struct ubi_device *ubi = desc->vol->ubi; 195 struct ubi_device *ubi = desc->vol->ubi;
196 196 struct inode *inode = file->f_path.dentry->d_inode;
197 return ubi_sync(ubi->ubi_num); 197 int err;
198 mutex_lock(&inode->i_mutex);
199 err = ubi_sync(ubi->ubi_num);
200 mutex_unlock(&inode->i_mutex);
201 return err;
198} 202}
199 203
200 204
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index c0f0ac7c1cdb..f3c6060c96b8 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -887,11 +887,16 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
887/* 887/*
888 * We want fsync() to work on POHMELFS. 888 * We want fsync() to work on POHMELFS.
889 */ 889 */
890static int pohmelfs_fsync(struct file *file, int datasync) 890static int pohmelfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
891{ 891{
892 struct inode *inode = file->f_mapping->host; 892 struct inode *inode = file->f_mapping->host;
893 893 int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
894 return sync_inode_metadata(inode, 1); 894 if (!err) {
895 mutex_lock(&inode->i_mutex);
896 err = sync_inode_metadata(inode, 1);
897 mutex_unlock(&inode->i_mutex);
898 }
899 return err;
895} 900}
896 901
897ssize_t pohmelfs_write(struct file *file, const char __user *buf, 902ssize_t pohmelfs_write(struct file *file, const char __user *buf,
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 271ef94668e7..978e6a101bf2 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -795,12 +795,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
795} 795}
796 796
797static int 797static int
798printer_fsync(struct file *fd, int datasync) 798printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync)
799{ 799{
800 struct printer_dev *dev = fd->private_data; 800 struct printer_dev *dev = fd->private_data;
801 struct inode *inode = fd->f_path.dentry->d_inode;
801 unsigned long flags; 802 unsigned long flags;
802 int tx_list_empty; 803 int tx_list_empty;
803 804
805 mutex_lock(&inode->i_mutex);
804 spin_lock_irqsave(&dev->lock, flags); 806 spin_lock_irqsave(&dev->lock, flags);
805 tx_list_empty = (likely(list_empty(&dev->tx_reqs))); 807 tx_list_empty = (likely(list_empty(&dev->tx_reqs)));
806 spin_unlock_irqrestore(&dev->lock, flags); 808 spin_unlock_irqrestore(&dev->lock, flags);
@@ -810,6 +812,7 @@ printer_fsync(struct file *fd, int datasync)
810 wait_event_interruptible(dev->tx_flush_wait, 812 wait_event_interruptible(dev->tx_flush_wait,
811 (likely(list_empty(&dev->tx_reqs_active)))); 813 (likely(list_empty(&dev->tx_reqs_active))));
812 } 814 }
815 mutex_unlock(&inode->i_mutex);
813 816
814 return 0; 817 return 0;
815} 818}
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 804000183c5e..32814e8800e0 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -66,19 +66,26 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
66 return 0; 66 return 0;
67} 67}
68 68
69int fb_deferred_io_fsync(struct file *file, int datasync) 69int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasync)
70{ 70{
71 struct fb_info *info = file->private_data; 71 struct fb_info *info = file->private_data;
72 struct inode *inode = file->f_path.dentry->d_inode;
73 int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
74 if (err)
75 return err;
72 76
73 /* Skip if deferred io is compiled-in but disabled on this fbdev */ 77 /* Skip if deferred io is compiled-in but disabled on this fbdev */
74 if (!info->fbdefio) 78 if (!info->fbdefio)
75 return 0; 79 return 0;
76 80
81 mutex_lock(&inode->i_mutex);
77 /* Kill off the delayed work */ 82 /* Kill off the delayed work */
78 cancel_delayed_work_sync(&info->deferred_work); 83 cancel_delayed_work_sync(&info->deferred_work);
79 84
80 /* Run it immediately */ 85 /* Run it immediately */
81 return schedule_delayed_work(&info->deferred_work, 0); 86 err = schedule_delayed_work(&info->deferred_work, 0);
87 mutex_unlock(&inode->i_mutex);
88 return err;
82} 89}
83EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); 90EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
84 91