aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-11-09 10:53:21 -0500
committerChris Mason <chris.mason@fusionio.com>2012-12-16 20:46:27 -0500
commit6c760c072403f446ff829ec9e89568943a3c2ef2 (patch)
treec751a0aeb81809401df1fd87a36376034ef53a87 /fs/btrfs/file.c
parent5124e00ec5b0be56155a11aec416fcc5125339f1 (diff)
Btrfs: do not call file_update_time in aio_write
This starts a transaction and dirties the inode everytime we call it, which is super expensive if you have a write heavy workload. We will be updating the inode when the IO completes and we reserve the space for the inode update when we reserve space for the write, so there is no chance of loss of information or enospc issues. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index c56088ece500..20452c110d7d 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1464,6 +1464,24 @@ out:
1464 return written ? written : err; 1464 return written ? written : err;
1465} 1465}
1466 1466
1467static void update_time_for_write(struct inode *inode)
1468{
1469 struct timespec now;
1470
1471 if (IS_NOCMTIME(inode))
1472 return;
1473
1474 now = current_fs_time(inode->i_sb);
1475 if (!timespec_equal(&inode->i_mtime, &now))
1476 inode->i_mtime = now;
1477
1478 if (!timespec_equal(&inode->i_ctime, &now))
1479 inode->i_ctime = now;
1480
1481 if (IS_I_VERSION(inode))
1482 inode_inc_iversion(inode);
1483}
1484
1467static ssize_t btrfs_file_aio_write(struct kiocb *iocb, 1485static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1468 const struct iovec *iov, 1486 const struct iovec *iov,
1469 unsigned long nr_segs, loff_t pos) 1487 unsigned long nr_segs, loff_t pos)
@@ -1519,11 +1537,13 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1519 goto out; 1537 goto out;
1520 } 1538 }
1521 1539
1522 err = file_update_time(file); 1540 /*
1523 if (err) { 1541 * We reserve space for updating the inode when we reserve space for the
1524 mutex_unlock(&inode->i_mutex); 1542 * extent we are going to write, so we will enospc out there. We don't
1525 goto out; 1543 * need to start yet another transaction to update the inode as we will
1526 } 1544 * update the inode when we finish writing whatever data we write.
1545 */
1546 update_time_for_write(inode);
1527 1547
1528 start_pos = round_down(pos, root->sectorsize); 1548 start_pos = round_down(pos, root->sectorsize);
1529 if (start_pos > i_size_read(inode)) { 1549 if (start_pos > i_size_read(inode)) {
@@ -1563,8 +1583,13 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1563 * this will either be one more than the running transaction 1583 * this will either be one more than the running transaction
1564 * or the generation used for the next transaction if there isn't 1584 * or the generation used for the next transaction if there isn't
1565 * one running right now. 1585 * one running right now.
1586 *
1587 * We also have to set last_sub_trans to the current log transid,
1588 * otherwise subsequent syncs to a file that's been synced in this
1589 * transaction will appear to have already occured.
1566 */ 1590 */
1567 BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; 1591 BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
1592 BTRFS_I(inode)->last_sub_trans = root->log_transid;
1568 if (num_written > 0 || num_written == -EIOCBQUEUED) { 1593 if (num_written > 0 || num_written == -EIOCBQUEUED) {
1569 err = generic_write_sync(file, pos, num_written); 1594 err = generic_write_sync(file, pos, num_written);
1570 if (err < 0 && num_written > 0) 1595 if (err < 0 && num_written > 0)