diff options
Diffstat (limited to 'fs/ocfs2/file.c')
| -rw-r--r-- | fs/ocfs2/file.c | 77 |
1 files changed, 39 insertions, 38 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8450262bcf2a..ff33c5ef87f2 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -175,9 +175,13 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, | |||
| 175 | int datasync) | 175 | int datasync) |
| 176 | { | 176 | { |
| 177 | int err = 0; | 177 | int err = 0; |
| 178 | journal_t *journal; | ||
| 179 | struct inode *inode = file->f_mapping->host; | 178 | struct inode *inode = file->f_mapping->host; |
| 180 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 179 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 180 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | ||
| 181 | journal_t *journal = osb->journal->j_journal; | ||
| 182 | int ret; | ||
| 183 | tid_t commit_tid; | ||
| 184 | bool needs_barrier = false; | ||
| 181 | 185 | ||
| 182 | trace_ocfs2_sync_file(inode, file, file->f_path.dentry, | 186 | trace_ocfs2_sync_file(inode, file, file->f_path.dentry, |
| 183 | OCFS2_I(inode)->ip_blkno, | 187 | OCFS2_I(inode)->ip_blkno, |
| @@ -192,29 +196,19 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, | |||
| 192 | if (err) | 196 | if (err) |
| 193 | return err; | 197 | return err; |
| 194 | 198 | ||
| 195 | /* | 199 | commit_tid = datasync ? oi->i_datasync_tid : oi->i_sync_tid; |
| 196 | * Probably don't need the i_mutex at all in here, just putting it here | 200 | if (journal->j_flags & JBD2_BARRIER && |
| 197 | * to be consistent with how fsync used to be called, someone more | 201 | !jbd2_trans_will_send_data_barrier(journal, commit_tid)) |
| 198 | * familiar with the fs could possibly remove it. | 202 | needs_barrier = true; |
| 199 | */ | 203 | err = jbd2_complete_transaction(journal, commit_tid); |
| 200 | mutex_lock(&inode->i_mutex); | 204 | if (needs_barrier) { |
| 201 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { | 205 | ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); |
| 202 | /* | 206 | if (!err) |
| 203 | * We still have to flush drive's caches to get data to the | 207 | err = ret; |
| 204 | * platter | ||
| 205 | */ | ||
| 206 | if (osb->s_mount_opt & OCFS2_MOUNT_BARRIER) | ||
| 207 | blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); | ||
| 208 | goto bail; | ||
| 209 | } | 208 | } |
| 210 | 209 | ||
| 211 | journal = osb->journal->j_journal; | ||
| 212 | err = jbd2_journal_force_commit(journal); | ||
| 213 | |||
| 214 | bail: | ||
| 215 | if (err) | 210 | if (err) |
| 216 | mlog_errno(err); | 211 | mlog_errno(err); |
| 217 | mutex_unlock(&inode->i_mutex); | ||
| 218 | 212 | ||
| 219 | return (err < 0) ? -EIO : 0; | 213 | return (err < 0) ? -EIO : 0; |
| 220 | } | 214 | } |
| @@ -292,6 +286,7 @@ int ocfs2_update_inode_atime(struct inode *inode, | |||
| 292 | inode->i_atime = CURRENT_TIME; | 286 | inode->i_atime = CURRENT_TIME; |
| 293 | di->i_atime = cpu_to_le64(inode->i_atime.tv_sec); | 287 | di->i_atime = cpu_to_le64(inode->i_atime.tv_sec); |
| 294 | di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); | 288 | di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); |
| 289 | ocfs2_update_inode_fsync_trans(handle, inode, 0); | ||
| 295 | ocfs2_journal_dirty(handle, bh); | 290 | ocfs2_journal_dirty(handle, bh); |
| 296 | 291 | ||
| 297 | out_commit: | 292 | out_commit: |
| @@ -341,6 +336,7 @@ int ocfs2_simple_size_update(struct inode *inode, | |||
| 341 | if (ret < 0) | 336 | if (ret < 0) |
| 342 | mlog_errno(ret); | 337 | mlog_errno(ret); |
| 343 | 338 | ||
| 339 | ocfs2_update_inode_fsync_trans(handle, inode, 0); | ||
| 344 | ocfs2_commit_trans(osb, handle); | 340 | ocfs2_commit_trans(osb, handle); |
| 345 | out: | 341 | out: |
| 346 | return ret; | 342 | return ret; |
| @@ -435,6 +431,7 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, | |||
| 435 | di->i_size = cpu_to_le64(new_i_size); | 431 | di->i_size = cpu_to_le64(new_i_size); |
| 436 | di->i_ctime = di->i_mtime = cpu_to_le64(inode->i_ctime.tv_sec); | 432 | di->i_ctime = di->i_mtime = cpu_to_le64(inode->i_ctime.tv_sec); |
| 437 | di->i_ctime_nsec = di->i_mtime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); | 433 | di->i_ctime_nsec = di->i_mtime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); |
| 434 | ocfs2_update_inode_fsync_trans(handle, inode, 0); | ||
| 438 | 435 | ||
| 439 | ocfs2_journal_dirty(handle, fe_bh); | 436 | ocfs2_journal_dirty(handle, fe_bh); |
| 440 | 437 | ||
| @@ -650,7 +647,7 @@ restarted_transaction: | |||
| 650 | mlog_errno(status); | 647 | mlog_errno(status); |
| 651 | goto leave; | 648 | goto leave; |
| 652 | } | 649 | } |
| 653 | 650 | ocfs2_update_inode_fsync_trans(handle, inode, 1); | |
| 654 | ocfs2_journal_dirty(handle, bh); | 651 | ocfs2_journal_dirty(handle, bh); |
| 655 | 652 | ||
| 656 | spin_lock(&OCFS2_I(inode)->ip_lock); | 653 | spin_lock(&OCFS2_I(inode)->ip_lock); |
| @@ -743,6 +740,7 @@ static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode, | |||
| 743 | OCFS2_JOURNAL_ACCESS_WRITE); | 740 | OCFS2_JOURNAL_ACCESS_WRITE); |
| 744 | if (ret) | 741 | if (ret) |
| 745 | mlog_errno(ret); | 742 | mlog_errno(ret); |
| 743 | ocfs2_update_inode_fsync_trans(handle, inode, 1); | ||
| 746 | 744 | ||
| 747 | out: | 745 | out: |
| 748 | if (ret) { | 746 | if (ret) { |
| @@ -840,6 +838,7 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 840 | di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); | 838 | di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); |
| 841 | di->i_mtime_nsec = di->i_ctime_nsec; | 839 | di->i_mtime_nsec = di->i_ctime_nsec; |
| 842 | ocfs2_journal_dirty(handle, di_bh); | 840 | ocfs2_journal_dirty(handle, di_bh); |
| 841 | ocfs2_update_inode_fsync_trans(handle, inode, 1); | ||
| 843 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 842 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
| 844 | } | 843 | } |
| 845 | 844 | ||
| @@ -1344,6 +1343,7 @@ static int __ocfs2_write_remove_suid(struct inode *inode, | |||
| 1344 | 1343 | ||
| 1345 | di = (struct ocfs2_dinode *) bh->b_data; | 1344 | di = (struct ocfs2_dinode *) bh->b_data; |
| 1346 | di->i_mode = cpu_to_le16(inode->i_mode); | 1345 | di->i_mode = cpu_to_le16(inode->i_mode); |
| 1346 | ocfs2_update_inode_fsync_trans(handle, inode, 0); | ||
| 1347 | 1347 | ||
| 1348 | ocfs2_journal_dirty(handle, bh); | 1348 | ocfs2_journal_dirty(handle, bh); |
| 1349 | 1349 | ||
| @@ -1576,6 +1576,7 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, | |||
| 1576 | if (ret) | 1576 | if (ret) |
| 1577 | mlog_errno(ret); | 1577 | mlog_errno(ret); |
| 1578 | } | 1578 | } |
| 1579 | ocfs2_update_inode_fsync_trans(handle, inode, 1); | ||
| 1579 | 1580 | ||
| 1580 | ocfs2_commit_trans(osb, handle); | 1581 | ocfs2_commit_trans(osb, handle); |
| 1581 | out: | 1582 | out: |
| @@ -2061,13 +2062,6 @@ out: | |||
| 2061 | return ret; | 2062 | return ret; |
| 2062 | } | 2063 | } |
| 2063 | 2064 | ||
| 2064 | static void ocfs2_aiodio_wait(struct inode *inode) | ||
| 2065 | { | ||
| 2066 | wait_queue_head_t *wq = ocfs2_ioend_wq(inode); | ||
| 2067 | |||
| 2068 | wait_event(*wq, (atomic_read(&OCFS2_I(inode)->ip_unaligned_aio) == 0)); | ||
| 2069 | } | ||
| 2070 | |||
| 2071 | static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos) | 2065 | static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos) |
| 2072 | { | 2066 | { |
| 2073 | int blockmask = inode->i_sb->s_blocksize - 1; | 2067 | int blockmask = inode->i_sb->s_blocksize - 1; |
| @@ -2345,10 +2339,8 @@ relock: | |||
| 2345 | * Wait on previous unaligned aio to complete before | 2339 | * Wait on previous unaligned aio to complete before |
| 2346 | * proceeding. | 2340 | * proceeding. |
| 2347 | */ | 2341 | */ |
| 2348 | ocfs2_aiodio_wait(inode); | 2342 | mutex_lock(&OCFS2_I(inode)->ip_unaligned_aio); |
| 2349 | 2343 | /* Mark the iocb as needing an unlock in ocfs2_dio_end_io */ | |
| 2350 | /* Mark the iocb as needing a decrement in ocfs2_dio_end_io */ | ||
| 2351 | atomic_inc(&OCFS2_I(inode)->ip_unaligned_aio); | ||
| 2352 | ocfs2_iocb_set_unaligned_aio(iocb); | 2344 | ocfs2_iocb_set_unaligned_aio(iocb); |
| 2353 | } | 2345 | } |
| 2354 | 2346 | ||
| @@ -2393,8 +2385,8 @@ out_dio: | |||
| 2393 | 2385 | ||
| 2394 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || | 2386 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || |
| 2395 | ((file->f_flags & O_DIRECT) && !direct_io)) { | 2387 | ((file->f_flags & O_DIRECT) && !direct_io)) { |
| 2396 | ret = filemap_fdatawrite_range(file->f_mapping, pos, | 2388 | ret = filemap_fdatawrite_range(file->f_mapping, *ppos, |
| 2397 | pos + count - 1); | 2389 | *ppos + count - 1); |
| 2398 | if (ret < 0) | 2390 | if (ret < 0) |
| 2399 | written = ret; | 2391 | written = ret; |
| 2400 | 2392 | ||
| @@ -2407,8 +2399,8 @@ out_dio: | |||
| 2407 | } | 2399 | } |
| 2408 | 2400 | ||
| 2409 | if (!ret) | 2401 | if (!ret) |
| 2410 | ret = filemap_fdatawait_range(file->f_mapping, pos, | 2402 | ret = filemap_fdatawait_range(file->f_mapping, *ppos, |
| 2411 | pos + count - 1); | 2403 | *ppos + count - 1); |
| 2412 | } | 2404 | } |
| 2413 | 2405 | ||
| 2414 | /* | 2406 | /* |
| @@ -2428,7 +2420,7 @@ out_dio: | |||
| 2428 | 2420 | ||
| 2429 | if (unaligned_dio) { | 2421 | if (unaligned_dio) { |
| 2430 | ocfs2_iocb_clear_unaligned_aio(iocb); | 2422 | ocfs2_iocb_clear_unaligned_aio(iocb); |
| 2431 | atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio); | 2423 | mutex_unlock(&OCFS2_I(inode)->ip_unaligned_aio); |
| 2432 | } | 2424 | } |
| 2433 | 2425 | ||
| 2434 | out: | 2426 | out: |
| @@ -2645,7 +2637,16 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence) | |||
| 2645 | case SEEK_SET: | 2637 | case SEEK_SET: |
| 2646 | break; | 2638 | break; |
| 2647 | case SEEK_END: | 2639 | case SEEK_END: |
| 2648 | offset += inode->i_size; | 2640 | /* SEEK_END requires the OCFS2 inode lock for the file |
| 2641 | * because it references the file's size. | ||
| 2642 | */ | ||
| 2643 | ret = ocfs2_inode_lock(inode, NULL, 0); | ||
| 2644 | if (ret < 0) { | ||
| 2645 | mlog_errno(ret); | ||
| 2646 | goto out; | ||
| 2647 | } | ||
| 2648 | offset += i_size_read(inode); | ||
| 2649 | ocfs2_inode_unlock(inode, 0); | ||
| 2649 | break; | 2650 | break; |
| 2650 | case SEEK_CUR: | 2651 | case SEEK_CUR: |
| 2651 | if (offset == 0) { | 2652 | if (offset == 0) { |
