diff options
Diffstat (limited to 'fs/afs/write.c')
-rw-r--r-- | fs/afs/write.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/afs/write.c b/fs/afs/write.c index b806285ff853..9aa52d93c73c 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
@@ -681,9 +681,10 @@ int afs_writeback_all(struct afs_vnode *vnode) | |||
681 | * - the return status from this call provides a reliable indication of | 681 | * - the return status from this call provides a reliable indication of |
682 | * whether any write errors occurred for this process. | 682 | * whether any write errors occurred for this process. |
683 | */ | 683 | */ |
684 | int afs_fsync(struct file *file, int datasync) | 684 | int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
685 | { | 685 | { |
686 | struct dentry *dentry = file->f_path.dentry; | 686 | struct dentry *dentry = file->f_path.dentry; |
687 | struct inode *inode = file->f_mapping->host; | ||
687 | struct afs_writeback *wb, *xwb; | 688 | struct afs_writeback *wb, *xwb; |
688 | struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); | 689 | struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); |
689 | int ret; | 690 | int ret; |
@@ -692,12 +693,19 @@ int afs_fsync(struct file *file, int datasync) | |||
692 | vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name, | 693 | vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name, |
693 | datasync); | 694 | datasync); |
694 | 695 | ||
696 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
697 | if (ret) | ||
698 | return ret; | ||
699 | mutex_lock(&inode->i_mutex); | ||
700 | |||
695 | /* use a writeback record as a marker in the queue - when this reaches | 701 | /* use a writeback record as a marker in the queue - when this reaches |
696 | * the front of the queue, all the outstanding writes are either | 702 | * the front of the queue, all the outstanding writes are either |
697 | * completed or rejected */ | 703 | * completed or rejected */ |
698 | wb = kzalloc(sizeof(*wb), GFP_KERNEL); | 704 | wb = kzalloc(sizeof(*wb), GFP_KERNEL); |
699 | if (!wb) | 705 | if (!wb) { |
700 | return -ENOMEM; | 706 | ret = -ENOMEM; |
707 | goto out; | ||
708 | } | ||
701 | wb->vnode = vnode; | 709 | wb->vnode = vnode; |
702 | wb->first = 0; | 710 | wb->first = 0; |
703 | wb->last = -1; | 711 | wb->last = -1; |
@@ -720,7 +728,7 @@ int afs_fsync(struct file *file, int datasync) | |||
720 | if (ret < 0) { | 728 | if (ret < 0) { |
721 | afs_put_writeback(wb); | 729 | afs_put_writeback(wb); |
722 | _leave(" = %d [wb]", ret); | 730 | _leave(" = %d [wb]", ret); |
723 | return ret; | 731 | goto out; |
724 | } | 732 | } |
725 | 733 | ||
726 | /* wait for the preceding writes to actually complete */ | 734 | /* wait for the preceding writes to actually complete */ |
@@ -729,6 +737,8 @@ int afs_fsync(struct file *file, int datasync) | |||
729 | vnode->writebacks.next == &wb->link); | 737 | vnode->writebacks.next == &wb->link); |
730 | afs_put_writeback(wb); | 738 | afs_put_writeback(wb); |
731 | _leave(" = %d", ret); | 739 | _leave(" = %d", ret); |
740 | out: | ||
741 | mutex_unlock(&inode->i_mutex); | ||
732 | return ret; | 742 | return ret; |
733 | } | 743 | } |
734 | 744 | ||