diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/file.c | 35 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 42 |
2 files changed, 48 insertions, 29 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 | ||
1467 | static 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 | |||
1467 | static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | 1485 | static 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) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 355a297e7988..1673dbdf1f76 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1922,22 +1922,20 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) | |||
1922 | 1922 | ||
1923 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { | 1923 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { |
1924 | BUG_ON(!list_empty(&ordered_extent->list)); /* Logic error */ | 1924 | BUG_ON(!list_empty(&ordered_extent->list)); /* Logic error */ |
1925 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1925 | btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1926 | if (!ret) { | 1926 | if (nolock) |
1927 | if (nolock) | 1927 | trans = btrfs_join_transaction_nolock(root); |
1928 | trans = btrfs_join_transaction_nolock(root); | 1928 | else |
1929 | else | 1929 | trans = btrfs_join_transaction(root); |
1930 | trans = btrfs_join_transaction(root); | 1930 | if (IS_ERR(trans)) { |
1931 | if (IS_ERR(trans)) { | 1931 | ret = PTR_ERR(trans); |
1932 | ret = PTR_ERR(trans); | 1932 | trans = NULL; |
1933 | trans = NULL; | 1933 | goto out; |
1934 | goto out; | ||
1935 | } | ||
1936 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | ||
1937 | ret = btrfs_update_inode_fallback(trans, root, inode); | ||
1938 | if (ret) /* -ENOMEM or corruption */ | ||
1939 | btrfs_abort_transaction(trans, root, ret); | ||
1940 | } | 1934 | } |
1935 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | ||
1936 | ret = btrfs_update_inode_fallback(trans, root, inode); | ||
1937 | if (ret) /* -ENOMEM or corruption */ | ||
1938 | btrfs_abort_transaction(trans, root, ret); | ||
1941 | goto out; | 1939 | goto out; |
1942 | } | 1940 | } |
1943 | 1941 | ||
@@ -1986,15 +1984,11 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) | |||
1986 | add_pending_csums(trans, inode, ordered_extent->file_offset, | 1984 | add_pending_csums(trans, inode, ordered_extent->file_offset, |
1987 | &ordered_extent->list); | 1985 | &ordered_extent->list); |
1988 | 1986 | ||
1989 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1987 | btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1990 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { | 1988 | ret = btrfs_update_inode_fallback(trans, root, inode); |
1991 | ret = btrfs_update_inode_fallback(trans, root, inode); | 1989 | if (ret) { /* -ENOMEM or corruption */ |
1992 | if (ret) { /* -ENOMEM or corruption */ | 1990 | btrfs_abort_transaction(trans, root, ret); |
1993 | btrfs_abort_transaction(trans, root, ret); | 1991 | goto out_unlock; |
1994 | goto out_unlock; | ||
1995 | } | ||
1996 | } else { | ||
1997 | btrfs_set_inode_last_trans(trans, inode); | ||
1998 | } | 1992 | } |
1999 | ret = 0; | 1993 | ret = 0; |
2000 | out_unlock: | 1994 | out_unlock: |