diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2013-01-29 05:11:59 -0500 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-02-20 12:59:06 -0500 |
commit | df0af1a57f72c74d53a9377c60ff20095afab97d (patch) | |
tree | 588048ea16f8564a2eb449c0e9b7ba22c49eebc6 /fs/btrfs/inode.c | |
parent | 963d678b0f7649300e3a67f2513ca9d830c6e303 (diff) |
Btrfs: use the inode own lock to protect its delalloc_bytes
We need not use a global lock to protect the delalloc_bytes of the
inode, just use its own lock. In this way, we can reduce the lock
contention and ->delalloc_lock will just protect delalloc inode
list.
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 24c0b7805fe1..82c7c66f8523 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1514,15 +1514,22 @@ static void btrfs_set_bit_hook(struct inode *inode, | |||
1514 | spin_unlock(&BTRFS_I(inode)->lock); | 1514 | spin_unlock(&BTRFS_I(inode)->lock); |
1515 | } | 1515 | } |
1516 | 1516 | ||
1517 | spin_lock(&root->fs_info->delalloc_lock); | ||
1518 | BTRFS_I(inode)->delalloc_bytes += len; | ||
1519 | __percpu_counter_add(&root->fs_info->delalloc_bytes, len, | 1517 | __percpu_counter_add(&root->fs_info->delalloc_bytes, len, |
1520 | root->fs_info->delalloc_batch); | 1518 | root->fs_info->delalloc_batch); |
1521 | if (do_list && list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | 1519 | spin_lock(&BTRFS_I(inode)->lock); |
1522 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, | 1520 | BTRFS_I(inode)->delalloc_bytes += len; |
1523 | &root->fs_info->delalloc_inodes); | 1521 | if (do_list && !test_bit(BTRFS_INODE_IN_DELALLOC_LIST, |
1522 | &BTRFS_I(inode)->runtime_flags)) { | ||
1523 | spin_lock(&root->fs_info->delalloc_lock); | ||
1524 | if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | ||
1525 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, | ||
1526 | &root->fs_info->delalloc_inodes); | ||
1527 | set_bit(BTRFS_INODE_IN_DELALLOC_LIST, | ||
1528 | &BTRFS_I(inode)->runtime_flags); | ||
1529 | } | ||
1530 | spin_unlock(&root->fs_info->delalloc_lock); | ||
1524 | } | 1531 | } |
1525 | spin_unlock(&root->fs_info->delalloc_lock); | 1532 | spin_unlock(&BTRFS_I(inode)->lock); |
1526 | } | 1533 | } |
1527 | } | 1534 | } |
1528 | 1535 | ||
@@ -1557,16 +1564,22 @@ static void btrfs_clear_bit_hook(struct inode *inode, | |||
1557 | && do_list) | 1564 | && do_list) |
1558 | btrfs_free_reserved_data_space(inode, len); | 1565 | btrfs_free_reserved_data_space(inode, len); |
1559 | 1566 | ||
1560 | spin_lock(&root->fs_info->delalloc_lock); | ||
1561 | __percpu_counter_add(&root->fs_info->delalloc_bytes, -len, | 1567 | __percpu_counter_add(&root->fs_info->delalloc_bytes, -len, |
1562 | root->fs_info->delalloc_batch); | 1568 | root->fs_info->delalloc_batch); |
1569 | spin_lock(&BTRFS_I(inode)->lock); | ||
1563 | BTRFS_I(inode)->delalloc_bytes -= len; | 1570 | BTRFS_I(inode)->delalloc_bytes -= len; |
1564 | |||
1565 | if (do_list && BTRFS_I(inode)->delalloc_bytes == 0 && | 1571 | if (do_list && BTRFS_I(inode)->delalloc_bytes == 0 && |
1566 | !list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | 1572 | test_bit(BTRFS_INODE_IN_DELALLOC_LIST, |
1567 | list_del_init(&BTRFS_I(inode)->delalloc_inodes); | 1573 | &BTRFS_I(inode)->runtime_flags)) { |
1574 | spin_lock(&root->fs_info->delalloc_lock); | ||
1575 | if (!list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | ||
1576 | list_del_init(&BTRFS_I(inode)->delalloc_inodes); | ||
1577 | clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, | ||
1578 | &BTRFS_I(inode)->runtime_flags); | ||
1579 | } | ||
1580 | spin_unlock(&root->fs_info->delalloc_lock); | ||
1568 | } | 1581 | } |
1569 | spin_unlock(&root->fs_info->delalloc_lock); | 1582 | spin_unlock(&BTRFS_I(inode)->lock); |
1570 | } | 1583 | } |
1571 | } | 1584 | } |
1572 | 1585 | ||
@@ -7326,14 +7339,19 @@ fail: | |||
7326 | static int btrfs_getattr(struct vfsmount *mnt, | 7339 | static int btrfs_getattr(struct vfsmount *mnt, |
7327 | struct dentry *dentry, struct kstat *stat) | 7340 | struct dentry *dentry, struct kstat *stat) |
7328 | { | 7341 | { |
7342 | u64 delalloc_bytes; | ||
7329 | struct inode *inode = dentry->d_inode; | 7343 | struct inode *inode = dentry->d_inode; |
7330 | u32 blocksize = inode->i_sb->s_blocksize; | 7344 | u32 blocksize = inode->i_sb->s_blocksize; |
7331 | 7345 | ||
7332 | generic_fillattr(inode, stat); | 7346 | generic_fillattr(inode, stat); |
7333 | stat->dev = BTRFS_I(inode)->root->anon_dev; | 7347 | stat->dev = BTRFS_I(inode)->root->anon_dev; |
7334 | stat->blksize = PAGE_CACHE_SIZE; | 7348 | stat->blksize = PAGE_CACHE_SIZE; |
7349 | |||
7350 | spin_lock(&BTRFS_I(inode)->lock); | ||
7351 | delalloc_bytes = BTRFS_I(inode)->delalloc_bytes; | ||
7352 | spin_unlock(&BTRFS_I(inode)->lock); | ||
7335 | stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) + | 7353 | stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) + |
7336 | ALIGN(BTRFS_I(inode)->delalloc_bytes, blocksize)) >> 9; | 7354 | ALIGN(delalloc_bytes, blocksize)) >> 9; |
7337 | return 0; | 7355 | return 0; |
7338 | } | 7356 | } |
7339 | 7357 | ||
@@ -7620,8 +7638,11 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) | |||
7620 | list_del_init(&binode->delalloc_inodes); | 7638 | list_del_init(&binode->delalloc_inodes); |
7621 | 7639 | ||
7622 | inode = igrab(&binode->vfs_inode); | 7640 | inode = igrab(&binode->vfs_inode); |
7623 | if (!inode) | 7641 | if (!inode) { |
7642 | clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, | ||
7643 | &binode->runtime_flags); | ||
7624 | continue; | 7644 | continue; |
7645 | } | ||
7625 | 7646 | ||
7626 | list_add_tail(&binode->delalloc_inodes, | 7647 | list_add_tail(&binode->delalloc_inodes, |
7627 | &root->fs_info->delalloc_inodes); | 7648 | &root->fs_info->delalloc_inodes); |