diff options
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/dir.c | 5 | ||||
-rw-r--r-- | fs/fuse/file.c | 24 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 3 |
3 files changed, 23 insertions, 9 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 02063dde272..9f63e493a9b 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1176,9 +1176,10 @@ static int fuse_dir_release(struct inode *inode, struct file *file) | |||
1176 | return 0; | 1176 | return 0; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static int fuse_dir_fsync(struct file *file, int datasync) | 1179 | static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end, |
1180 | int datasync) | ||
1180 | { | 1181 | { |
1181 | return fuse_fsync_common(file, datasync, 1); | 1182 | return fuse_fsync_common(file, start, end, datasync, 1); |
1182 | } | 1183 | } |
1183 | 1184 | ||
1184 | static bool update_mtime(unsigned ivalid) | 1185 | static bool update_mtime(unsigned ivalid) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 73b89df2085..7bb685cdd00 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -400,7 +400,8 @@ static void fuse_sync_writes(struct inode *inode) | |||
400 | fuse_release_nowrite(inode); | 400 | fuse_release_nowrite(inode); |
401 | } | 401 | } |
402 | 402 | ||
403 | int fuse_fsync_common(struct file *file, int datasync, int isdir) | 403 | int fuse_fsync_common(struct file *file, loff_t start, loff_t end, |
404 | int datasync, int isdir) | ||
404 | { | 405 | { |
405 | struct inode *inode = file->f_mapping->host; | 406 | struct inode *inode = file->f_mapping->host; |
406 | struct fuse_conn *fc = get_fuse_conn(inode); | 407 | struct fuse_conn *fc = get_fuse_conn(inode); |
@@ -412,9 +413,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir) | |||
412 | if (is_bad_inode(inode)) | 413 | if (is_bad_inode(inode)) |
413 | return -EIO; | 414 | return -EIO; |
414 | 415 | ||
416 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
417 | if (err) | ||
418 | return err; | ||
419 | |||
415 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) | 420 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) |
416 | return 0; | 421 | return 0; |
417 | 422 | ||
423 | mutex_lock(&inode->i_mutex); | ||
424 | |||
418 | /* | 425 | /* |
419 | * Start writeback against all dirty pages of the inode, then | 426 | * Start writeback against all dirty pages of the inode, then |
420 | * wait for all outstanding writes, before sending the FSYNC | 427 | * wait for all outstanding writes, before sending the FSYNC |
@@ -422,13 +429,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir) | |||
422 | */ | 429 | */ |
423 | err = write_inode_now(inode, 0); | 430 | err = write_inode_now(inode, 0); |
424 | if (err) | 431 | if (err) |
425 | return err; | 432 | goto out; |
426 | 433 | ||
427 | fuse_sync_writes(inode); | 434 | fuse_sync_writes(inode); |
428 | 435 | ||
429 | req = fuse_get_req(fc); | 436 | req = fuse_get_req(fc); |
430 | if (IS_ERR(req)) | 437 | if (IS_ERR(req)) { |
431 | return PTR_ERR(req); | 438 | err = PTR_ERR(req); |
439 | goto out; | ||
440 | } | ||
432 | 441 | ||
433 | memset(&inarg, 0, sizeof(inarg)); | 442 | memset(&inarg, 0, sizeof(inarg)); |
434 | inarg.fh = ff->fh; | 443 | inarg.fh = ff->fh; |
@@ -448,12 +457,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir) | |||
448 | fc->no_fsync = 1; | 457 | fc->no_fsync = 1; |
449 | err = 0; | 458 | err = 0; |
450 | } | 459 | } |
460 | out: | ||
461 | mutex_unlock(&inode->i_mutex); | ||
451 | return err; | 462 | return err; |
452 | } | 463 | } |
453 | 464 | ||
454 | static int fuse_fsync(struct file *file, int datasync) | 465 | static int fuse_fsync(struct file *file, loff_t start, loff_t end, |
466 | int datasync) | ||
455 | { | 467 | { |
456 | return fuse_fsync_common(file, datasync, 0); | 468 | return fuse_fsync_common(file, start, end, datasync, 0); |
457 | } | 469 | } |
458 | 470 | ||
459 | void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, | 471 | void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index b788becada7..c6aa2d4b851 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -589,7 +589,8 @@ void fuse_release_common(struct file *file, int opcode); | |||
589 | /** | 589 | /** |
590 | * Send FSYNC or FSYNCDIR request | 590 | * Send FSYNC or FSYNCDIR request |
591 | */ | 591 | */ |
592 | int fuse_fsync_common(struct file *file, int datasync, int isdir); | 592 | int fuse_fsync_common(struct file *file, loff_t start, loff_t end, |
593 | int datasync, int isdir); | ||
593 | 594 | ||
594 | /** | 595 | /** |
595 | * Notify poll wakeup | 596 | * Notify poll wakeup |