diff options
Diffstat (limited to 'fs/ext3/fsync.c')
| -rw-r--r-- | fs/ext3/fsync.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c index 451d166bbe93..8209f266e9ad 100644 --- a/fs/ext3/fsync.c +++ b/fs/ext3/fsync.c | |||
| @@ -46,19 +46,21 @@ | |||
| 46 | int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) | 46 | int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) |
| 47 | { | 47 | { |
| 48 | struct inode *inode = dentry->d_inode; | 48 | struct inode *inode = dentry->d_inode; |
| 49 | struct ext3_inode_info *ei = EXT3_I(inode); | ||
| 50 | journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; | ||
| 49 | int ret = 0; | 51 | int ret = 0; |
| 52 | tid_t commit_tid; | ||
| 53 | |||
| 54 | if (inode->i_sb->s_flags & MS_RDONLY) | ||
| 55 | return 0; | ||
| 50 | 56 | ||
| 51 | J_ASSERT(ext3_journal_current_handle() == NULL); | 57 | J_ASSERT(ext3_journal_current_handle() == NULL); |
| 52 | 58 | ||
| 53 | /* | 59 | /* |
| 54 | * data=writeback: | 60 | * data=writeback,ordered: |
| 55 | * The caller's filemap_fdatawrite()/wait will sync the data. | 61 | * The caller's filemap_fdatawrite()/wait will sync the data. |
| 56 | * sync_inode() will sync the metadata | 62 | * Metadata is in the journal, we wait for a proper transaction |
| 57 | * | 63 | * to commit here. |
| 58 | * data=ordered: | ||
| 59 | * The caller's filemap_fdatawrite() will write the data and | ||
| 60 | * sync_inode() will write the inode if it is dirty. Then the caller's | ||
| 61 | * filemap_fdatawait() will wait on the pages. | ||
| 62 | * | 64 | * |
| 63 | * data=journal: | 65 | * data=journal: |
| 64 | * filemap_fdatawrite won't do anything (the buffers are clean). | 66 | * filemap_fdatawrite won't do anything (the buffers are clean). |
| @@ -73,22 +75,16 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) | |||
| 73 | goto out; | 75 | goto out; |
| 74 | } | 76 | } |
| 75 | 77 | ||
| 76 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) | 78 | if (datasync) |
| 77 | goto flush; | 79 | commit_tid = atomic_read(&ei->i_datasync_tid); |
| 80 | else | ||
| 81 | commit_tid = atomic_read(&ei->i_sync_tid); | ||
| 78 | 82 | ||
| 79 | /* | 83 | if (log_start_commit(journal, commit_tid)) { |
| 80 | * The VFS has written the file data. If the inode is unaltered | 84 | log_wait_commit(journal, commit_tid); |
| 81 | * then we need not start a commit. | ||
| 82 | */ | ||
| 83 | if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) { | ||
| 84 | struct writeback_control wbc = { | ||
| 85 | .sync_mode = WB_SYNC_ALL, | ||
| 86 | .nr_to_write = 0, /* sys_fsync did this */ | ||
| 87 | }; | ||
| 88 | ret = sync_inode(inode, &wbc); | ||
| 89 | goto out; | 85 | goto out; |
| 90 | } | 86 | } |
| 91 | flush: | 87 | |
| 92 | /* | 88 | /* |
| 93 | * In case we didn't commit a transaction, we have to flush | 89 | * In case we didn't commit a transaction, we have to flush |
| 94 | * disk caches manually so that data really is on persistent | 90 | * disk caches manually so that data really is on persistent |
