aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/buffer.c43
-rw-r--r--include/linux/fs.h1
2 files changed, 24 insertions, 20 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 24262ea8cc50..6d77ce9f54e5 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -327,31 +327,24 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
327 return ret; 327 return ret;
328} 328}
329 329
330static long do_fsync(unsigned int fd, int datasync) 330long do_fsync(struct file *file, int datasync)
331{ 331{
332 struct file * file; 332 int ret;
333 struct address_space *mapping; 333 int err;
334 int ret, err; 334 struct address_space *mapping = file->f_mapping;
335
336 ret = -EBADF;
337 file = fget(fd);
338 if (!file)
339 goto out;
340 335
341 ret = -EINVAL;
342 if (!file->f_op || !file->f_op->fsync) { 336 if (!file->f_op || !file->f_op->fsync) {
343 /* Why? We can still call filemap_fdatawrite */ 337 /* Why? We can still call filemap_fdatawrite */
344 goto out_putf; 338 ret = -EINVAL;
339 goto out;
345 } 340 }
346 341
347 mapping = file->f_mapping;
348
349 current->flags |= PF_SYNCWRITE; 342 current->flags |= PF_SYNCWRITE;
350 ret = filemap_fdatawrite(mapping); 343 ret = filemap_fdatawrite(mapping);
351 344
352 /* 345 /*
353 * We need to protect against concurrent writers, 346 * We need to protect against concurrent writers, which could cause
354 * which could cause livelocks in fsync_buffers_list 347 * livelocks in fsync_buffers_list().
355 */ 348 */
356 mutex_lock(&mapping->host->i_mutex); 349 mutex_lock(&mapping->host->i_mutex);
357 err = file->f_op->fsync(file, file->f_dentry, datasync); 350 err = file->f_op->fsync(file, file->f_dentry, datasync);
@@ -362,21 +355,31 @@ static long do_fsync(unsigned int fd, int datasync)
362 if (!ret) 355 if (!ret)
363 ret = err; 356 ret = err;
364 current->flags &= ~PF_SYNCWRITE; 357 current->flags &= ~PF_SYNCWRITE;
365
366out_putf:
367 fput(file);
368out: 358out:
369 return ret; 359 return ret;
370} 360}
371 361
362static long __do_fsync(unsigned int fd, int datasync)
363{
364 struct file *file;
365 int ret = -EBADF;
366
367 file = fget(fd);
368 if (file) {
369 ret = do_fsync(file, datasync);
370 fput(file);
371 }
372 return ret;
373}
374
372asmlinkage long sys_fsync(unsigned int fd) 375asmlinkage long sys_fsync(unsigned int fd)
373{ 376{
374 return do_fsync(fd, 0); 377 return __do_fsync(fd, 0);
375} 378}
376 379
377asmlinkage long sys_fdatasync(unsigned int fd) 380asmlinkage long sys_fdatasync(unsigned int fd)
378{ 381{
379 return do_fsync(fd, 1); 382 return __do_fsync(fd, 1);
380} 383}
381 384
382/* 385/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 092cfaee0cd2..215696a0f16f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1478,6 +1478,7 @@ extern int wait_on_page_writeback_range(struct address_space *mapping,
1478extern int __filemap_fdatawrite_range(struct address_space *mapping, 1478extern int __filemap_fdatawrite_range(struct address_space *mapping,
1479 loff_t start, loff_t end, int sync_mode); 1479 loff_t start, loff_t end, int sync_mode);
1480 1480
1481extern long do_fsync(struct file *file, int datasync);
1481extern void sync_supers(void); 1482extern void sync_supers(void);
1482extern void sync_filesystems(int wait); 1483extern void sync_filesystems(int wait);
1483extern void emergency_sync(void); 1484extern void emergency_sync(void);