aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/xattr.c')
-rw-r--r--fs/ext4/xattr.c166
1 files changed, 100 insertions, 66 deletions
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index a95151e875bd..0441e055c8e8 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -545,30 +545,44 @@ static void
545ext4_xattr_release_block(handle_t *handle, struct inode *inode, 545ext4_xattr_release_block(handle_t *handle, struct inode *inode,
546 struct buffer_head *bh) 546 struct buffer_head *bh)
547{ 547{
548 struct mb_cache_entry *ce = NULL;
549 int error = 0;
550 struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode); 548 struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
549 u32 hash, ref;
550 int error = 0;
551 551
552 ce = mb_cache_entry_get(ext4_mb_cache, bh->b_bdev, bh->b_blocknr);
553 BUFFER_TRACE(bh, "get_write_access"); 552 BUFFER_TRACE(bh, "get_write_access");
554 error = ext4_journal_get_write_access(handle, bh); 553 error = ext4_journal_get_write_access(handle, bh);
555 if (error) 554 if (error)
556 goto out; 555 goto out;
557 556
558 lock_buffer(bh); 557 lock_buffer(bh);
559 if (BHDR(bh)->h_refcount == cpu_to_le32(1)) { 558 hash = le32_to_cpu(BHDR(bh)->h_hash);
559 ref = le32_to_cpu(BHDR(bh)->h_refcount);
560 if (ref == 1) {
560 ea_bdebug(bh, "refcount now=0; freeing"); 561 ea_bdebug(bh, "refcount now=0; freeing");
561 if (ce) 562 /*
562 mb_cache_entry_free(ce); 563 * This must happen under buffer lock for
564 * ext4_xattr_block_set() to reliably detect freed block
565 */
566 mb_cache_entry_delete_block(ext4_mb_cache, hash, bh->b_blocknr);
563 get_bh(bh); 567 get_bh(bh);
564 unlock_buffer(bh); 568 unlock_buffer(bh);
565 ext4_free_blocks(handle, inode, bh, 0, 1, 569 ext4_free_blocks(handle, inode, bh, 0, 1,
566 EXT4_FREE_BLOCKS_METADATA | 570 EXT4_FREE_BLOCKS_METADATA |
567 EXT4_FREE_BLOCKS_FORGET); 571 EXT4_FREE_BLOCKS_FORGET);
568 } else { 572 } else {
569 le32_add_cpu(&BHDR(bh)->h_refcount, -1); 573 ref--;
570 if (ce) 574 BHDR(bh)->h_refcount = cpu_to_le32(ref);
571 mb_cache_entry_release(ce); 575 if (ref == EXT4_XATTR_REFCOUNT_MAX - 1) {
576 struct mb_cache_entry *ce;
577
578 ce = mb_cache_entry_get(ext4_mb_cache, hash,
579 bh->b_blocknr);
580 if (ce) {
581 ce->e_reusable = 1;
582 mb_cache_entry_put(ext4_mb_cache, ce);
583 }
584 }
585
572 /* 586 /*
573 * Beware of this ugliness: Releasing of xattr block references 587 * Beware of this ugliness: Releasing of xattr block references
574 * from different inodes can race and so we have to protect 588 * from different inodes can race and so we have to protect
@@ -790,8 +804,6 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
790 if (i->value && i->value_len > sb->s_blocksize) 804 if (i->value && i->value_len > sb->s_blocksize)
791 return -ENOSPC; 805 return -ENOSPC;
792 if (s->base) { 806 if (s->base) {
793 ce = mb_cache_entry_get(ext4_mb_cache, bs->bh->b_bdev,
794 bs->bh->b_blocknr);
795 BUFFER_TRACE(bs->bh, "get_write_access"); 807 BUFFER_TRACE(bs->bh, "get_write_access");
796 error = ext4_journal_get_write_access(handle, bs->bh); 808 error = ext4_journal_get_write_access(handle, bs->bh);
797 if (error) 809 if (error)
@@ -799,10 +811,15 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
799 lock_buffer(bs->bh); 811 lock_buffer(bs->bh);
800 812
801 if (header(s->base)->h_refcount == cpu_to_le32(1)) { 813 if (header(s->base)->h_refcount == cpu_to_le32(1)) {
802 if (ce) { 814 __u32 hash = le32_to_cpu(BHDR(bs->bh)->h_hash);
803 mb_cache_entry_free(ce); 815
804 ce = NULL; 816 /*
805 } 817 * This must happen under buffer lock for
818 * ext4_xattr_block_set() to reliably detect modified
819 * block
820 */
821 mb_cache_entry_delete_block(ext4_mb_cache, hash,
822 bs->bh->b_blocknr);
806 ea_bdebug(bs->bh, "modifying in-place"); 823 ea_bdebug(bs->bh, "modifying in-place");
807 error = ext4_xattr_set_entry(i, s); 824 error = ext4_xattr_set_entry(i, s);
808 if (!error) { 825 if (!error) {
@@ -826,10 +843,6 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
826 int offset = (char *)s->here - bs->bh->b_data; 843 int offset = (char *)s->here - bs->bh->b_data;
827 844
828 unlock_buffer(bs->bh); 845 unlock_buffer(bs->bh);
829 if (ce) {
830 mb_cache_entry_release(ce);
831 ce = NULL;
832 }
833 ea_bdebug(bs->bh, "cloning"); 846 ea_bdebug(bs->bh, "cloning");
834 s->base = kmalloc(bs->bh->b_size, GFP_NOFS); 847 s->base = kmalloc(bs->bh->b_size, GFP_NOFS);
835 error = -ENOMEM; 848 error = -ENOMEM;
@@ -872,6 +885,8 @@ inserted:
872 if (new_bh == bs->bh) 885 if (new_bh == bs->bh)
873 ea_bdebug(new_bh, "keeping"); 886 ea_bdebug(new_bh, "keeping");
874 else { 887 else {
888 u32 ref;
889
875 /* The old block is released after updating 890 /* The old block is released after updating
876 the inode. */ 891 the inode. */
877 error = dquot_alloc_block(inode, 892 error = dquot_alloc_block(inode,
@@ -884,9 +899,40 @@ inserted:
884 if (error) 899 if (error)
885 goto cleanup_dquot; 900 goto cleanup_dquot;
886 lock_buffer(new_bh); 901 lock_buffer(new_bh);
887 le32_add_cpu(&BHDR(new_bh)->h_refcount, 1); 902 /*
903 * We have to be careful about races with
904 * freeing, rehashing or adding references to
905 * xattr block. Once we hold buffer lock xattr
906 * block's state is stable so we can check
907 * whether the block got freed / rehashed or
908 * not. Since we unhash mbcache entry under
909 * buffer lock when freeing / rehashing xattr
910 * block, checking whether entry is still
911 * hashed is reliable. Same rules hold for
912 * e_reusable handling.
913 */
914 if (hlist_bl_unhashed(&ce->e_hash_list) ||
915 !ce->e_reusable) {
916 /*
917 * Undo everything and check mbcache
918 * again.
919 */
920 unlock_buffer(new_bh);
921 dquot_free_block(inode,
922 EXT4_C2B(EXT4_SB(sb),
923 1));
924 brelse(new_bh);
925 mb_cache_entry_put(ext4_mb_cache, ce);
926 ce = NULL;
927 new_bh = NULL;
928 goto inserted;
929 }
930 ref = le32_to_cpu(BHDR(new_bh)->h_refcount) + 1;
931 BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
932 if (ref >= EXT4_XATTR_REFCOUNT_MAX)
933 ce->e_reusable = 0;
888 ea_bdebug(new_bh, "reusing; refcount now=%d", 934 ea_bdebug(new_bh, "reusing; refcount now=%d",
889 le32_to_cpu(BHDR(new_bh)->h_refcount)); 935 ref);
890 unlock_buffer(new_bh); 936 unlock_buffer(new_bh);
891 error = ext4_handle_dirty_xattr_block(handle, 937 error = ext4_handle_dirty_xattr_block(handle,
892 inode, 938 inode,
@@ -894,7 +940,8 @@ inserted:
894 if (error) 940 if (error)
895 goto cleanup_dquot; 941 goto cleanup_dquot;
896 } 942 }
897 mb_cache_entry_release(ce); 943 mb_cache_entry_touch(ext4_mb_cache, ce);
944 mb_cache_entry_put(ext4_mb_cache, ce);
898 ce = NULL; 945 ce = NULL;
899 } else if (bs->bh && s->base == bs->bh->b_data) { 946 } else if (bs->bh && s->base == bs->bh->b_data) {
900 /* We were modifying this block in-place. */ 947 /* We were modifying this block in-place. */
@@ -959,7 +1006,7 @@ getblk_failed:
959 1006
960cleanup: 1007cleanup:
961 if (ce) 1008 if (ce)
962 mb_cache_entry_release(ce); 1009 mb_cache_entry_put(ext4_mb_cache, ce);
963 brelse(new_bh); 1010 brelse(new_bh);
964 if (!(bs->bh && s->base == bs->bh->b_data)) 1011 if (!(bs->bh && s->base == bs->bh->b_data))
965 kfree(s->base); 1012 kfree(s->base);
@@ -1070,6 +1117,17 @@ static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
1070 return 0; 1117 return 0;
1071} 1118}
1072 1119
1120static int ext4_xattr_value_same(struct ext4_xattr_search *s,
1121 struct ext4_xattr_info *i)
1122{
1123 void *value;
1124
1125 if (le32_to_cpu(s->here->e_value_size) != i->value_len)
1126 return 0;
1127 value = ((void *)s->base) + le16_to_cpu(s->here->e_value_offs);
1128 return !memcmp(value, i->value, i->value_len);
1129}
1130
1073/* 1131/*
1074 * ext4_xattr_set_handle() 1132 * ext4_xattr_set_handle()
1075 * 1133 *
@@ -1146,6 +1204,13 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
1146 else if (!bs.s.not_found) 1204 else if (!bs.s.not_found)
1147 error = ext4_xattr_block_set(handle, inode, &i, &bs); 1205 error = ext4_xattr_block_set(handle, inode, &i, &bs);
1148 } else { 1206 } else {
1207 error = 0;
1208 /* Xattr value did not change? Save us some work and bail out */
1209 if (!is.s.not_found && ext4_xattr_value_same(&is.s, &i))
1210 goto cleanup;
1211 if (!bs.s.not_found && ext4_xattr_value_same(&bs.s, &i))
1212 goto cleanup;
1213
1149 error = ext4_xattr_ibody_set(handle, inode, &i, &is); 1214 error = ext4_xattr_ibody_set(handle, inode, &i, &is);
1150 if (!error && !bs.s.not_found) { 1215 if (!error && !bs.s.not_found) {
1151 i.value = NULL; 1216 i.value = NULL;
@@ -1512,17 +1577,6 @@ cleanup:
1512} 1577}
1513 1578
1514/* 1579/*
1515 * ext4_xattr_put_super()
1516 *
1517 * This is called when a file system is unmounted.
1518 */
1519void
1520ext4_xattr_put_super(struct super_block *sb)
1521{
1522 mb_cache_shrink(sb->s_bdev);
1523}
1524
1525/*
1526 * ext4_xattr_cache_insert() 1580 * ext4_xattr_cache_insert()
1527 * 1581 *
1528 * Create a new entry in the extended attribute cache, and insert 1582 * Create a new entry in the extended attribute cache, and insert
@@ -1533,26 +1587,19 @@ ext4_xattr_put_super(struct super_block *sb)
1533static void 1587static void
1534ext4_xattr_cache_insert(struct mb_cache *ext4_mb_cache, struct buffer_head *bh) 1588ext4_xattr_cache_insert(struct mb_cache *ext4_mb_cache, struct buffer_head *bh)
1535{ 1589{
1536 __u32 hash = le32_to_cpu(BHDR(bh)->h_hash); 1590 struct ext4_xattr_header *header = BHDR(bh);
1537 struct mb_cache_entry *ce; 1591 __u32 hash = le32_to_cpu(header->h_hash);
1592 int reusable = le32_to_cpu(header->h_refcount) <
1593 EXT4_XATTR_REFCOUNT_MAX;
1538 int error; 1594 int error;
1539 1595
1540 ce = mb_cache_entry_alloc(ext4_mb_cache, GFP_NOFS); 1596 error = mb_cache_entry_create(ext4_mb_cache, GFP_NOFS, hash,
1541 if (!ce) { 1597 bh->b_blocknr, reusable);
1542 ea_bdebug(bh, "out of memory");
1543 return;
1544 }
1545 error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, hash);
1546 if (error) { 1598 if (error) {
1547 mb_cache_entry_free(ce); 1599 if (error == -EBUSY)
1548 if (error == -EBUSY) {
1549 ea_bdebug(bh, "already in cache"); 1600 ea_bdebug(bh, "already in cache");
1550 error = 0; 1601 } else
1551 }
1552 } else {
1553 ea_bdebug(bh, "inserting [%x]", (int)hash); 1602 ea_bdebug(bh, "inserting [%x]", (int)hash);
1554 mb_cache_entry_release(ce);
1555 }
1556} 1603}
1557 1604
1558/* 1605/*
@@ -1614,33 +1661,20 @@ ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header,
1614 if (!header->h_hash) 1661 if (!header->h_hash)
1615 return NULL; /* never share */ 1662 return NULL; /* never share */
1616 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); 1663 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
1617again: 1664 ce = mb_cache_entry_find_first(ext4_mb_cache, hash);
1618 ce = mb_cache_entry_find_first(ext4_mb_cache, inode->i_sb->s_bdev,
1619 hash);
1620 while (ce) { 1665 while (ce) {
1621 struct buffer_head *bh; 1666 struct buffer_head *bh;
1622 1667
1623 if (IS_ERR(ce)) {
1624 if (PTR_ERR(ce) == -EAGAIN)
1625 goto again;
1626 break;
1627 }
1628 bh = sb_bread(inode->i_sb, ce->e_block); 1668 bh = sb_bread(inode->i_sb, ce->e_block);
1629 if (!bh) { 1669 if (!bh) {
1630 EXT4_ERROR_INODE(inode, "block %lu read error", 1670 EXT4_ERROR_INODE(inode, "block %lu read error",
1631 (unsigned long) ce->e_block); 1671 (unsigned long) ce->e_block);
1632 } else if (le32_to_cpu(BHDR(bh)->h_refcount) >=
1633 EXT4_XATTR_REFCOUNT_MAX) {
1634 ea_idebug(inode, "block %lu refcount %d>=%d",
1635 (unsigned long) ce->e_block,
1636 le32_to_cpu(BHDR(bh)->h_refcount),
1637 EXT4_XATTR_REFCOUNT_MAX);
1638 } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) { 1672 } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) {
1639 *pce = ce; 1673 *pce = ce;
1640 return bh; 1674 return bh;
1641 } 1675 }
1642 brelse(bh); 1676 brelse(bh);
1643 ce = mb_cache_entry_find_next(ce, inode->i_sb->s_bdev, hash); 1677 ce = mb_cache_entry_find_next(ext4_mb_cache, ce);
1644 } 1678 }
1645 return NULL; 1679 return NULL;
1646} 1680}
@@ -1716,9 +1750,9 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *header,
1716#define HASH_BUCKET_BITS 10 1750#define HASH_BUCKET_BITS 10
1717 1751
1718struct mb_cache * 1752struct mb_cache *
1719ext4_xattr_create_cache(char *name) 1753ext4_xattr_create_cache(void)
1720{ 1754{
1721 return mb_cache_create(name, HASH_BUCKET_BITS); 1755 return mb_cache_create(HASH_BUCKET_BITS);
1722} 1756}
1723 1757
1724void ext4_xattr_destroy_cache(struct mb_cache *cache) 1758void ext4_xattr_destroy_cache(struct mb_cache *cache)