diff options
Diffstat (limited to 'fs/ntfs/mft.c')
-rw-r--r-- | fs/ntfs/mft.c | 186 |
1 files changed, 130 insertions, 56 deletions
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index dfa85ac2f8ba..61ce09f1b652 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /** |
2 | * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project. | 2 | * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project. |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2004 Anton Altaparmakov | 4 | * Copyright (c) 2001-2005 Anton Altaparmakov |
5 | * Copyright (c) 2002 Richard Russon | 5 | * Copyright (c) 2002 Richard Russon |
6 | * | 6 | * |
7 | * This program/include file is free software; you can redistribute it and/or | 7 | * This program/include file is free software; you can redistribute it and/or |
@@ -45,6 +45,7 @@ | |||
45 | */ | 45 | */ |
46 | static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) | 46 | static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) |
47 | { | 47 | { |
48 | loff_t i_size; | ||
48 | ntfs_volume *vol = ni->vol; | 49 | ntfs_volume *vol = ni->vol; |
49 | struct inode *mft_vi = vol->mft_ino; | 50 | struct inode *mft_vi = vol->mft_ino; |
50 | struct page *page; | 51 | struct page *page; |
@@ -60,13 +61,14 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) | |||
60 | index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT; | 61 | index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT; |
61 | ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; | 62 | ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; |
62 | 63 | ||
64 | i_size = i_size_read(mft_vi); | ||
63 | /* The maximum valid index into the page cache for $MFT's data. */ | 65 | /* The maximum valid index into the page cache for $MFT's data. */ |
64 | end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT; | 66 | end_index = i_size >> PAGE_CACHE_SHIFT; |
65 | 67 | ||
66 | /* If the wanted index is out of bounds the mft record doesn't exist. */ | 68 | /* If the wanted index is out of bounds the mft record doesn't exist. */ |
67 | if (unlikely(index >= end_index)) { | 69 | if (unlikely(index >= end_index)) { |
68 | if (index > end_index || (mft_vi->i_size & ~PAGE_CACHE_MASK) < | 70 | if (index > end_index || (i_size & ~PAGE_CACHE_MASK) < ofs + |
69 | ofs + vol->mft_record_size) { | 71 | vol->mft_record_size) { |
70 | page = ERR_PTR(-ENOENT); | 72 | page = ERR_PTR(-ENOENT); |
71 | ntfs_error(vol->sb, "Attemt to read mft record 0x%lx, " | 73 | ntfs_error(vol->sb, "Attemt to read mft record 0x%lx, " |
72 | "which is beyond the end of the mft. " | 74 | "which is beyond the end of the mft. " |
@@ -285,7 +287,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, | |||
285 | } | 287 | } |
286 | unmap_mft_record(ni); | 288 | unmap_mft_record(ni); |
287 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " | 289 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " |
288 | "reference! Corrupt file system. " | 290 | "reference! Corrupt filesystem. " |
289 | "Run chkdsk."); | 291 | "Run chkdsk."); |
290 | return ERR_PTR(-EIO); | 292 | return ERR_PTR(-EIO); |
291 | } | 293 | } |
@@ -316,7 +318,7 @@ map_err_out: | |||
316 | /* Verify the sequence number if it is present. */ | 318 | /* Verify the sequence number if it is present. */ |
317 | if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { | 319 | if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { |
318 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " | 320 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " |
319 | "reference! Corrupt file system. Run chkdsk."); | 321 | "reference! Corrupt filesystem. Run chkdsk."); |
320 | destroy_ni = TRUE; | 322 | destroy_ni = TRUE; |
321 | m = ERR_PTR(-EIO); | 323 | m = ERR_PTR(-EIO); |
322 | goto unm_err_out; | 324 | goto unm_err_out; |
@@ -1121,6 +1123,7 @@ static int ntfs_mft_bitmap_find_and_alloc_free_rec_nolock(ntfs_volume *vol, | |||
1121 | ntfs_inode *base_ni) | 1123 | ntfs_inode *base_ni) |
1122 | { | 1124 | { |
1123 | s64 pass_end, ll, data_pos, pass_start, ofs, bit; | 1125 | s64 pass_end, ll, data_pos, pass_start, ofs, bit; |
1126 | unsigned long flags; | ||
1124 | struct address_space *mftbmp_mapping; | 1127 | struct address_space *mftbmp_mapping; |
1125 | u8 *buf, *byte; | 1128 | u8 *buf, *byte; |
1126 | struct page *page; | 1129 | struct page *page; |
@@ -1134,9 +1137,13 @@ static int ntfs_mft_bitmap_find_and_alloc_free_rec_nolock(ntfs_volume *vol, | |||
1134 | * Set the end of the pass making sure we do not overflow the mft | 1137 | * Set the end of the pass making sure we do not overflow the mft |
1135 | * bitmap. | 1138 | * bitmap. |
1136 | */ | 1139 | */ |
1140 | read_lock_irqsave(&NTFS_I(vol->mft_ino)->size_lock, flags); | ||
1137 | pass_end = NTFS_I(vol->mft_ino)->allocated_size >> | 1141 | pass_end = NTFS_I(vol->mft_ino)->allocated_size >> |
1138 | vol->mft_record_size_bits; | 1142 | vol->mft_record_size_bits; |
1143 | read_unlock_irqrestore(&NTFS_I(vol->mft_ino)->size_lock, flags); | ||
1144 | read_lock_irqsave(&NTFS_I(vol->mftbmp_ino)->size_lock, flags); | ||
1139 | ll = NTFS_I(vol->mftbmp_ino)->initialized_size << 3; | 1145 | ll = NTFS_I(vol->mftbmp_ino)->initialized_size << 3; |
1146 | read_unlock_irqrestore(&NTFS_I(vol->mftbmp_ino)->size_lock, flags); | ||
1140 | if (pass_end > ll) | 1147 | if (pass_end > ll) |
1141 | pass_end = ll; | 1148 | pass_end = ll; |
1142 | pass = 1; | 1149 | pass = 1; |
@@ -1263,6 +1270,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1263 | { | 1270 | { |
1264 | LCN lcn; | 1271 | LCN lcn; |
1265 | s64 ll; | 1272 | s64 ll; |
1273 | unsigned long flags; | ||
1266 | struct page *page; | 1274 | struct page *page; |
1267 | ntfs_inode *mft_ni, *mftbmp_ni; | 1275 | ntfs_inode *mft_ni, *mftbmp_ni; |
1268 | runlist_element *rl, *rl2 = NULL; | 1276 | runlist_element *rl, *rl2 = NULL; |
@@ -1284,17 +1292,20 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1284 | /* | 1292 | /* |
1285 | * Determine the last lcn of the mft bitmap. The allocated size of the | 1293 | * Determine the last lcn of the mft bitmap. The allocated size of the |
1286 | * mft bitmap cannot be zero so we are ok to do this. | 1294 | * mft bitmap cannot be zero so we are ok to do this. |
1287 | * ntfs_find_vcn() returns the runlist locked on success. | ||
1288 | */ | 1295 | */ |
1289 | rl = ntfs_find_vcn(mftbmp_ni, (mftbmp_ni->allocated_size - 1) >> | 1296 | down_write(&mftbmp_ni->runlist.lock); |
1290 | vol->cluster_size_bits, TRUE); | 1297 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); |
1298 | ll = mftbmp_ni->allocated_size; | ||
1299 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
1300 | rl = ntfs_attr_find_vcn_nolock(mftbmp_ni, | ||
1301 | (ll - 1) >> vol->cluster_size_bits, TRUE); | ||
1291 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { | 1302 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { |
1303 | up_write(&mftbmp_ni->runlist.lock); | ||
1292 | ntfs_error(vol->sb, "Failed to determine last allocated " | 1304 | ntfs_error(vol->sb, "Failed to determine last allocated " |
1293 | "cluster of mft bitmap attribute."); | 1305 | "cluster of mft bitmap attribute."); |
1294 | if (!IS_ERR(rl)) { | 1306 | if (!IS_ERR(rl)) |
1295 | up_write(&mftbmp_ni->runlist.lock); | ||
1296 | ret = -EIO; | 1307 | ret = -EIO; |
1297 | } else | 1308 | else |
1298 | ret = PTR_ERR(rl); | 1309 | ret = PTR_ERR(rl); |
1299 | return ret; | 1310 | return ret; |
1300 | } | 1311 | } |
@@ -1418,6 +1429,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1418 | // TODO: Deal with this by moving this extent to a new mft | 1429 | // TODO: Deal with this by moving this extent to a new mft |
1419 | // record or by starting a new extent in a new mft record or by | 1430 | // record or by starting a new extent in a new mft record or by |
1420 | // moving other attributes out of this mft record. | 1431 | // moving other attributes out of this mft record. |
1432 | // Note: It will need to be a special mft record and if none of | ||
1433 | // those are available it gets rather complicated... | ||
1421 | ntfs_error(vol->sb, "Not enough space in this mft record to " | 1434 | ntfs_error(vol->sb, "Not enough space in this mft record to " |
1422 | "accomodate extended mft bitmap attribute " | 1435 | "accomodate extended mft bitmap attribute " |
1423 | "extent. Cannot handle this yet."); | 1436 | "extent. Cannot handle this yet."); |
@@ -1458,9 +1471,11 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1458 | } | 1471 | } |
1459 | a = ctx->attr; | 1472 | a = ctx->attr; |
1460 | } | 1473 | } |
1474 | write_lock_irqsave(&mftbmp_ni->size_lock, flags); | ||
1461 | mftbmp_ni->allocated_size += vol->cluster_size; | 1475 | mftbmp_ni->allocated_size += vol->cluster_size; |
1462 | a->data.non_resident.allocated_size = | 1476 | a->data.non_resident.allocated_size = |
1463 | cpu_to_sle64(mftbmp_ni->allocated_size); | 1477 | cpu_to_sle64(mftbmp_ni->allocated_size); |
1478 | write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
1464 | /* Ensure the changes make it to disk. */ | 1479 | /* Ensure the changes make it to disk. */ |
1465 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 1480 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
1466 | mark_mft_record_dirty(ctx->ntfs_ino); | 1481 | mark_mft_record_dirty(ctx->ntfs_ino); |
@@ -1476,7 +1491,9 @@ restore_undo_alloc: | |||
1476 | 0, ctx)) { | 1491 | 0, ctx)) { |
1477 | ntfs_error(vol->sb, "Failed to find last attribute extent of " | 1492 | ntfs_error(vol->sb, "Failed to find last attribute extent of " |
1478 | "mft bitmap attribute.%s", es); | 1493 | "mft bitmap attribute.%s", es); |
1494 | write_lock_irqsave(&mftbmp_ni->size_lock, flags); | ||
1479 | mftbmp_ni->allocated_size += vol->cluster_size; | 1495 | mftbmp_ni->allocated_size += vol->cluster_size; |
1496 | write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
1480 | ntfs_attr_put_search_ctx(ctx); | 1497 | ntfs_attr_put_search_ctx(ctx); |
1481 | unmap_mft_record(mft_ni); | 1498 | unmap_mft_record(mft_ni); |
1482 | up_write(&mftbmp_ni->runlist.lock); | 1499 | up_write(&mftbmp_ni->runlist.lock); |
@@ -1550,6 +1567,7 @@ undo_alloc: | |||
1550 | static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol) | 1567 | static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol) |
1551 | { | 1568 | { |
1552 | s64 old_data_size, old_initialized_size; | 1569 | s64 old_data_size, old_initialized_size; |
1570 | unsigned long flags; | ||
1553 | struct inode *mftbmp_vi; | 1571 | struct inode *mftbmp_vi; |
1554 | ntfs_inode *mft_ni, *mftbmp_ni; | 1572 | ntfs_inode *mft_ni, *mftbmp_ni; |
1555 | ntfs_attr_search_ctx *ctx; | 1573 | ntfs_attr_search_ctx *ctx; |
@@ -1583,7 +1601,8 @@ static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol) | |||
1583 | goto put_err_out; | 1601 | goto put_err_out; |
1584 | } | 1602 | } |
1585 | a = ctx->attr; | 1603 | a = ctx->attr; |
1586 | old_data_size = mftbmp_vi->i_size; | 1604 | write_lock_irqsave(&mftbmp_ni->size_lock, flags); |
1605 | old_data_size = i_size_read(mftbmp_vi); | ||
1587 | old_initialized_size = mftbmp_ni->initialized_size; | 1606 | old_initialized_size = mftbmp_ni->initialized_size; |
1588 | /* | 1607 | /* |
1589 | * We can simply update the initialized_size before filling the space | 1608 | * We can simply update the initialized_size before filling the space |
@@ -1593,11 +1612,12 @@ static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol) | |||
1593 | mftbmp_ni->initialized_size += 8; | 1612 | mftbmp_ni->initialized_size += 8; |
1594 | a->data.non_resident.initialized_size = | 1613 | a->data.non_resident.initialized_size = |
1595 | cpu_to_sle64(mftbmp_ni->initialized_size); | 1614 | cpu_to_sle64(mftbmp_ni->initialized_size); |
1596 | if (mftbmp_ni->initialized_size > mftbmp_vi->i_size) { | 1615 | if (mftbmp_ni->initialized_size > old_data_size) { |
1597 | mftbmp_vi->i_size = mftbmp_ni->initialized_size; | 1616 | i_size_write(mftbmp_vi, mftbmp_ni->initialized_size); |
1598 | a->data.non_resident.data_size = | 1617 | a->data.non_resident.data_size = |
1599 | cpu_to_sle64(mftbmp_vi->i_size); | 1618 | cpu_to_sle64(mftbmp_ni->initialized_size); |
1600 | } | 1619 | } |
1620 | write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
1601 | /* Ensure the changes make it to disk. */ | 1621 | /* Ensure the changes make it to disk. */ |
1602 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 1622 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
1603 | mark_mft_record_dirty(ctx->ntfs_ino); | 1623 | mark_mft_record_dirty(ctx->ntfs_ino); |
@@ -1636,22 +1656,28 @@ unm_err_out: | |||
1636 | goto err_out; | 1656 | goto err_out; |
1637 | } | 1657 | } |
1638 | a = ctx->attr; | 1658 | a = ctx->attr; |
1659 | write_lock_irqsave(&mftbmp_ni->size_lock, flags); | ||
1639 | mftbmp_ni->initialized_size = old_initialized_size; | 1660 | mftbmp_ni->initialized_size = old_initialized_size; |
1640 | a->data.non_resident.initialized_size = | 1661 | a->data.non_resident.initialized_size = |
1641 | cpu_to_sle64(old_initialized_size); | 1662 | cpu_to_sle64(old_initialized_size); |
1642 | if (mftbmp_vi->i_size != old_data_size) { | 1663 | if (i_size_read(mftbmp_vi) != old_data_size) { |
1643 | mftbmp_vi->i_size = old_data_size; | 1664 | i_size_write(mftbmp_vi, old_data_size); |
1644 | a->data.non_resident.data_size = cpu_to_sle64(old_data_size); | 1665 | a->data.non_resident.data_size = cpu_to_sle64(old_data_size); |
1645 | } | 1666 | } |
1667 | write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
1646 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 1668 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
1647 | mark_mft_record_dirty(ctx->ntfs_ino); | 1669 | mark_mft_record_dirty(ctx->ntfs_ino); |
1648 | ntfs_attr_put_search_ctx(ctx); | 1670 | ntfs_attr_put_search_ctx(ctx); |
1649 | unmap_mft_record(mft_ni); | 1671 | unmap_mft_record(mft_ni); |
1672 | #ifdef DEBUG | ||
1673 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); | ||
1650 | ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, " | 1674 | ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, " |
1651 | "data_size 0x%llx, initialized_size 0x%llx.", | 1675 | "data_size 0x%llx, initialized_size 0x%llx.", |
1652 | (long long)mftbmp_ni->allocated_size, | 1676 | (long long)mftbmp_ni->allocated_size, |
1653 | (long long)mftbmp_vi->i_size, | 1677 | (long long)i_size_read(mftbmp_vi), |
1654 | (long long)mftbmp_ni->initialized_size); | 1678 | (long long)mftbmp_ni->initialized_size); |
1679 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
1680 | #endif /* DEBUG */ | ||
1655 | err_out: | 1681 | err_out: |
1656 | return ret; | 1682 | return ret; |
1657 | } | 1683 | } |
@@ -1679,7 +1705,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1679 | { | 1705 | { |
1680 | LCN lcn; | 1706 | LCN lcn; |
1681 | VCN old_last_vcn; | 1707 | VCN old_last_vcn; |
1682 | s64 min_nr, nr, ll = 0; | 1708 | s64 min_nr, nr, ll; |
1709 | unsigned long flags; | ||
1683 | ntfs_inode *mft_ni; | 1710 | ntfs_inode *mft_ni; |
1684 | runlist_element *rl, *rl2; | 1711 | runlist_element *rl, *rl2; |
1685 | ntfs_attr_search_ctx *ctx = NULL; | 1712 | ntfs_attr_search_ctx *ctx = NULL; |
@@ -1695,23 +1722,25 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1695 | * Determine the preferred allocation location, i.e. the last lcn of | 1722 | * Determine the preferred allocation location, i.e. the last lcn of |
1696 | * the mft data attribute. The allocated size of the mft data | 1723 | * the mft data attribute. The allocated size of the mft data |
1697 | * attribute cannot be zero so we are ok to do this. | 1724 | * attribute cannot be zero so we are ok to do this. |
1698 | * ntfs_find_vcn() returns the runlist locked on success. | ||
1699 | */ | 1725 | */ |
1700 | rl = ntfs_find_vcn(mft_ni, (mft_ni->allocated_size - 1) >> | 1726 | down_write(&mft_ni->runlist.lock); |
1701 | vol->cluster_size_bits, TRUE); | 1727 | read_lock_irqsave(&mft_ni->size_lock, flags); |
1728 | ll = mft_ni->allocated_size; | ||
1729 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
1730 | rl = ntfs_attr_find_vcn_nolock(mft_ni, | ||
1731 | (ll - 1) >> vol->cluster_size_bits, TRUE); | ||
1702 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { | 1732 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { |
1733 | up_write(&mft_ni->runlist.lock); | ||
1703 | ntfs_error(vol->sb, "Failed to determine last allocated " | 1734 | ntfs_error(vol->sb, "Failed to determine last allocated " |
1704 | "cluster of mft data attribute."); | 1735 | "cluster of mft data attribute."); |
1705 | if (!IS_ERR(rl)) { | 1736 | if (!IS_ERR(rl)) |
1706 | up_write(&mft_ni->runlist.lock); | ||
1707 | ret = -EIO; | 1737 | ret = -EIO; |
1708 | } else | 1738 | else |
1709 | ret = PTR_ERR(rl); | 1739 | ret = PTR_ERR(rl); |
1710 | return ret; | 1740 | return ret; |
1711 | } | 1741 | } |
1712 | lcn = rl->lcn + rl->length; | 1742 | lcn = rl->lcn + rl->length; |
1713 | ntfs_debug("Last lcn of mft data attribute is 0x%llx.", | 1743 | ntfs_debug("Last lcn of mft data attribute is 0x%llx.", (long long)lcn); |
1714 | (long long)lcn); | ||
1715 | /* Minimum allocation is one mft record worth of clusters. */ | 1744 | /* Minimum allocation is one mft record worth of clusters. */ |
1716 | min_nr = vol->mft_record_size >> vol->cluster_size_bits; | 1745 | min_nr = vol->mft_record_size >> vol->cluster_size_bits; |
1717 | if (!min_nr) | 1746 | if (!min_nr) |
@@ -1721,12 +1750,13 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1721 | if (!nr) | 1750 | if (!nr) |
1722 | nr = min_nr; | 1751 | nr = min_nr; |
1723 | /* Ensure we do not go above 2^32-1 mft records. */ | 1752 | /* Ensure we do not go above 2^32-1 mft records. */ |
1724 | if (unlikely((mft_ni->allocated_size + | 1753 | read_lock_irqsave(&mft_ni->size_lock, flags); |
1725 | (nr << vol->cluster_size_bits)) >> | 1754 | ll = mft_ni->allocated_size; |
1755 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
1756 | if (unlikely((ll + (nr << vol->cluster_size_bits)) >> | ||
1726 | vol->mft_record_size_bits >= (1ll << 32))) { | 1757 | vol->mft_record_size_bits >= (1ll << 32))) { |
1727 | nr = min_nr; | 1758 | nr = min_nr; |
1728 | if (unlikely((mft_ni->allocated_size + | 1759 | if (unlikely((ll + (nr << vol->cluster_size_bits)) >> |
1729 | (nr << vol->cluster_size_bits)) >> | ||
1730 | vol->mft_record_size_bits >= (1ll << 32))) { | 1760 | vol->mft_record_size_bits >= (1ll << 32))) { |
1731 | ntfs_warning(vol->sb, "Cannot allocate mft record " | 1761 | ntfs_warning(vol->sb, "Cannot allocate mft record " |
1732 | "because the maximum number of inodes " | 1762 | "because the maximum number of inodes " |
@@ -1772,7 +1802,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1772 | return PTR_ERR(rl); | 1802 | return PTR_ERR(rl); |
1773 | } | 1803 | } |
1774 | mft_ni->runlist.rl = rl; | 1804 | mft_ni->runlist.rl = rl; |
1775 | ntfs_debug("Allocated %lli clusters.", nr); | 1805 | ntfs_debug("Allocated %lli clusters.", (long long)nr); |
1776 | /* Find the last run in the new runlist. */ | 1806 | /* Find the last run in the new runlist. */ |
1777 | for (; rl[1].length; rl++) | 1807 | for (; rl[1].length; rl++) |
1778 | ; | 1808 | ; |
@@ -1832,7 +1862,11 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1832 | // moving other attributes out of this mft record. | 1862 | // moving other attributes out of this mft record. |
1833 | // Note: Use the special reserved mft records and ensure that | 1863 | // Note: Use the special reserved mft records and ensure that |
1834 | // this extent is not required to find the mft record in | 1864 | // this extent is not required to find the mft record in |
1835 | // question. | 1865 | // question. If no free special records left we would need to |
1866 | // move an existing record away, insert ours in its place, and | ||
1867 | // then place the moved record into the newly allocated space | ||
1868 | // and we would then need to update all references to this mft | ||
1869 | // record appropriately. This is rather complicated... | ||
1836 | ntfs_error(vol->sb, "Not enough space in this mft record to " | 1870 | ntfs_error(vol->sb, "Not enough space in this mft record to " |
1837 | "accomodate extended mft data attribute " | 1871 | "accomodate extended mft data attribute " |
1838 | "extent. Cannot handle this yet."); | 1872 | "extent. Cannot handle this yet."); |
@@ -1875,9 +1909,11 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1875 | } | 1909 | } |
1876 | a = ctx->attr; | 1910 | a = ctx->attr; |
1877 | } | 1911 | } |
1912 | write_lock_irqsave(&mft_ni->size_lock, flags); | ||
1878 | mft_ni->allocated_size += nr << vol->cluster_size_bits; | 1913 | mft_ni->allocated_size += nr << vol->cluster_size_bits; |
1879 | a->data.non_resident.allocated_size = | 1914 | a->data.non_resident.allocated_size = |
1880 | cpu_to_sle64(mft_ni->allocated_size); | 1915 | cpu_to_sle64(mft_ni->allocated_size); |
1916 | write_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
1881 | /* Ensure the changes make it to disk. */ | 1917 | /* Ensure the changes make it to disk. */ |
1882 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 1918 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
1883 | mark_mft_record_dirty(ctx->ntfs_ino); | 1919 | mark_mft_record_dirty(ctx->ntfs_ino); |
@@ -1892,7 +1928,9 @@ restore_undo_alloc: | |||
1892 | CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) { | 1928 | CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) { |
1893 | ntfs_error(vol->sb, "Failed to find last attribute extent of " | 1929 | ntfs_error(vol->sb, "Failed to find last attribute extent of " |
1894 | "mft data attribute.%s", es); | 1930 | "mft data attribute.%s", es); |
1931 | write_lock_irqsave(&mft_ni->size_lock, flags); | ||
1895 | mft_ni->allocated_size += nr << vol->cluster_size_bits; | 1932 | mft_ni->allocated_size += nr << vol->cluster_size_bits; |
1933 | write_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
1896 | ntfs_attr_put_search_ctx(ctx); | 1934 | ntfs_attr_put_search_ctx(ctx); |
1897 | unmap_mft_record(mft_ni); | 1935 | unmap_mft_record(mft_ni); |
1898 | up_write(&mft_ni->runlist.lock); | 1936 | up_write(&mft_ni->runlist.lock); |
@@ -1991,7 +2029,7 @@ static int ntfs_mft_record_layout(const ntfs_volume *vol, const s64 mft_no, | |||
1991 | "reports this as corruption, please email " | 2029 | "reports this as corruption, please email " |
1992 | "linux-ntfs-dev@lists.sourceforge.net stating " | 2030 | "linux-ntfs-dev@lists.sourceforge.net stating " |
1993 | "that you saw this message and that the " | 2031 | "that you saw this message and that the " |
1994 | "modified file system created was corrupt. " | 2032 | "modified filesystem created was corrupt. " |
1995 | "Thank you."); | 2033 | "Thank you."); |
1996 | } | 2034 | } |
1997 | /* Set the update sequence number to 1. */ | 2035 | /* Set the update sequence number to 1. */ |
@@ -2036,6 +2074,7 @@ static int ntfs_mft_record_layout(const ntfs_volume *vol, const s64 mft_no, | |||
2036 | */ | 2074 | */ |
2037 | static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no) | 2075 | static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no) |
2038 | { | 2076 | { |
2077 | loff_t i_size; | ||
2039 | struct inode *mft_vi = vol->mft_ino; | 2078 | struct inode *mft_vi = vol->mft_ino; |
2040 | struct page *page; | 2079 | struct page *page; |
2041 | MFT_RECORD *m; | 2080 | MFT_RECORD *m; |
@@ -2051,10 +2090,11 @@ static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no) | |||
2051 | index = mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT; | 2090 | index = mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT; |
2052 | ofs = (mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; | 2091 | ofs = (mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; |
2053 | /* The maximum valid index into the page cache for $MFT's data. */ | 2092 | /* The maximum valid index into the page cache for $MFT's data. */ |
2054 | end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT; | 2093 | i_size = i_size_read(mft_vi); |
2094 | end_index = i_size >> PAGE_CACHE_SHIFT; | ||
2055 | if (unlikely(index >= end_index)) { | 2095 | if (unlikely(index >= end_index)) { |
2056 | if (unlikely(index > end_index || ofs + vol->mft_record_size >= | 2096 | if (unlikely(index > end_index || ofs + vol->mft_record_size >= |
2057 | (mft_vi->i_size & ~PAGE_CACHE_MASK))) { | 2097 | (i_size & ~PAGE_CACHE_MASK))) { |
2058 | ntfs_error(vol->sb, "Tried to format non-existing mft " | 2098 | ntfs_error(vol->sb, "Tried to format non-existing mft " |
2059 | "record 0x%llx.", (long long)mft_no); | 2099 | "record 0x%llx.", (long long)mft_no); |
2060 | return -ENOENT; | 2100 | return -ENOENT; |
@@ -2188,6 +2228,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, | |||
2188 | ntfs_inode *base_ni, MFT_RECORD **mrec) | 2228 | ntfs_inode *base_ni, MFT_RECORD **mrec) |
2189 | { | 2229 | { |
2190 | s64 ll, bit, old_data_initialized, old_data_size; | 2230 | s64 ll, bit, old_data_initialized, old_data_size; |
2231 | unsigned long flags; | ||
2191 | struct inode *vi; | 2232 | struct inode *vi; |
2192 | struct page *page; | 2233 | struct page *page; |
2193 | ntfs_inode *mft_ni, *mftbmp_ni, *ni; | 2234 | ntfs_inode *mft_ni, *mftbmp_ni, *ni; |
@@ -2237,9 +2278,13 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, | |||
2237 | * the first 24 mft records as they are special and whilst they may not | 2278 | * the first 24 mft records as they are special and whilst they may not |
2238 | * be in use, we do not allocate from them. | 2279 | * be in use, we do not allocate from them. |
2239 | */ | 2280 | */ |
2281 | read_lock_irqsave(&mft_ni->size_lock, flags); | ||
2240 | ll = mft_ni->initialized_size >> vol->mft_record_size_bits; | 2282 | ll = mft_ni->initialized_size >> vol->mft_record_size_bits; |
2241 | if (mftbmp_ni->initialized_size << 3 > ll && | 2283 | read_unlock_irqrestore(&mft_ni->size_lock, flags); |
2242 | mftbmp_ni->initialized_size > 3) { | 2284 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); |
2285 | old_data_initialized = mftbmp_ni->initialized_size; | ||
2286 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
2287 | if (old_data_initialized << 3 > ll && old_data_initialized > 3) { | ||
2243 | bit = ll; | 2288 | bit = ll; |
2244 | if (bit < 24) | 2289 | if (bit < 24) |
2245 | bit = 24; | 2290 | bit = 24; |
@@ -2254,15 +2299,18 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, | |||
2254 | * mft record that we can allocate. | 2299 | * mft record that we can allocate. |
2255 | * Note: The smallest mft record we allocate is mft record 24. | 2300 | * Note: The smallest mft record we allocate is mft record 24. |
2256 | */ | 2301 | */ |
2257 | bit = mftbmp_ni->initialized_size << 3; | 2302 | bit = old_data_initialized << 3; |
2258 | if (unlikely(bit >= (1ll << 32))) | 2303 | if (unlikely(bit >= (1ll << 32))) |
2259 | goto max_err_out; | 2304 | goto max_err_out; |
2305 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); | ||
2306 | old_data_size = mftbmp_ni->allocated_size; | ||
2260 | ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, " | 2307 | ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, " |
2261 | "data_size 0x%llx, initialized_size 0x%llx.", | 2308 | "data_size 0x%llx, initialized_size 0x%llx.", |
2262 | (long long)mftbmp_ni->allocated_size, | 2309 | (long long)old_data_size, |
2263 | (long long)vol->mftbmp_ino->i_size, | 2310 | (long long)i_size_read(vol->mftbmp_ino), |
2264 | (long long)mftbmp_ni->initialized_size); | 2311 | (long long)old_data_initialized); |
2265 | if (mftbmp_ni->initialized_size + 8 > mftbmp_ni->allocated_size) { | 2312 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); |
2313 | if (old_data_initialized + 8 > old_data_size) { | ||
2266 | /* Need to extend bitmap by one more cluster. */ | 2314 | /* Need to extend bitmap by one more cluster. */ |
2267 | ntfs_debug("mftbmp: initialized_size + 8 > allocated_size."); | 2315 | ntfs_debug("mftbmp: initialized_size + 8 > allocated_size."); |
2268 | err = ntfs_mft_bitmap_extend_allocation_nolock(vol); | 2316 | err = ntfs_mft_bitmap_extend_allocation_nolock(vol); |
@@ -2270,12 +2318,16 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, | |||
2270 | up_write(&vol->mftbmp_lock); | 2318 | up_write(&vol->mftbmp_lock); |
2271 | goto err_out; | 2319 | goto err_out; |
2272 | } | 2320 | } |
2321 | #ifdef DEBUG | ||
2322 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); | ||
2273 | ntfs_debug("Status of mftbmp after allocation extension: " | 2323 | ntfs_debug("Status of mftbmp after allocation extension: " |
2274 | "allocated_size 0x%llx, data_size 0x%llx, " | 2324 | "allocated_size 0x%llx, data_size 0x%llx, " |
2275 | "initialized_size 0x%llx.", | 2325 | "initialized_size 0x%llx.", |
2276 | (long long)mftbmp_ni->allocated_size, | 2326 | (long long)mftbmp_ni->allocated_size, |
2277 | (long long)vol->mftbmp_ino->i_size, | 2327 | (long long)i_size_read(vol->mftbmp_ino), |
2278 | (long long)mftbmp_ni->initialized_size); | 2328 | (long long)mftbmp_ni->initialized_size); |
2329 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
2330 | #endif /* DEBUG */ | ||
2279 | } | 2331 | } |
2280 | /* | 2332 | /* |
2281 | * We now have sufficient allocated space, extend the initialized_size | 2333 | * We now have sufficient allocated space, extend the initialized_size |
@@ -2287,12 +2339,16 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, | |||
2287 | up_write(&vol->mftbmp_lock); | 2339 | up_write(&vol->mftbmp_lock); |
2288 | goto err_out; | 2340 | goto err_out; |
2289 | } | 2341 | } |
2342 | #ifdef DEBUG | ||
2343 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); | ||
2290 | ntfs_debug("Status of mftbmp after initialized extention: " | 2344 | ntfs_debug("Status of mftbmp after initialized extention: " |
2291 | "allocated_size 0x%llx, data_size 0x%llx, " | 2345 | "allocated_size 0x%llx, data_size 0x%llx, " |
2292 | "initialized_size 0x%llx.", | 2346 | "initialized_size 0x%llx.", |
2293 | (long long)mftbmp_ni->allocated_size, | 2347 | (long long)mftbmp_ni->allocated_size, |
2294 | (long long)vol->mftbmp_ino->i_size, | 2348 | (long long)i_size_read(vol->mftbmp_ino), |
2295 | (long long)mftbmp_ni->initialized_size); | 2349 | (long long)mftbmp_ni->initialized_size); |
2350 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | ||
2351 | #endif /* DEBUG */ | ||
2296 | ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit); | 2352 | ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit); |
2297 | found_free_rec: | 2353 | found_free_rec: |
2298 | /* @bit is the found free mft record, allocate it in the mft bitmap. */ | 2354 | /* @bit is the found free mft record, allocate it in the mft bitmap. */ |
@@ -2314,7 +2370,10 @@ have_alloc_rec: | |||
2314 | * parallel allocation could allocate the same mft record as this one. | 2370 | * parallel allocation could allocate the same mft record as this one. |
2315 | */ | 2371 | */ |
2316 | ll = (bit + 1) << vol->mft_record_size_bits; | 2372 | ll = (bit + 1) << vol->mft_record_size_bits; |
2317 | if (ll <= mft_ni->initialized_size) { | 2373 | read_lock_irqsave(&mft_ni->size_lock, flags); |
2374 | old_data_initialized = mft_ni->initialized_size; | ||
2375 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2376 | if (ll <= old_data_initialized) { | ||
2318 | ntfs_debug("Allocated mft record already initialized."); | 2377 | ntfs_debug("Allocated mft record already initialized."); |
2319 | goto mft_rec_already_initialized; | 2378 | goto mft_rec_already_initialized; |
2320 | } | 2379 | } |
@@ -2325,26 +2384,30 @@ have_alloc_rec: | |||
2325 | * actually traversed more than once when a freshly formatted volume is | 2384 | * actually traversed more than once when a freshly formatted volume is |
2326 | * first written to so it optimizes away nicely in the common case. | 2385 | * first written to so it optimizes away nicely in the common case. |
2327 | */ | 2386 | */ |
2387 | read_lock_irqsave(&mft_ni->size_lock, flags); | ||
2328 | ntfs_debug("Status of mft data before extension: " | 2388 | ntfs_debug("Status of mft data before extension: " |
2329 | "allocated_size 0x%llx, data_size 0x%llx, " | 2389 | "allocated_size 0x%llx, data_size 0x%llx, " |
2330 | "initialized_size 0x%llx.", | 2390 | "initialized_size 0x%llx.", |
2331 | (long long)mft_ni->allocated_size, | 2391 | (long long)mft_ni->allocated_size, |
2332 | (long long)vol->mft_ino->i_size, | 2392 | (long long)i_size_read(vol->mft_ino), |
2333 | (long long)mft_ni->initialized_size); | 2393 | (long long)mft_ni->initialized_size); |
2334 | while (ll > mft_ni->allocated_size) { | 2394 | while (ll > mft_ni->allocated_size) { |
2395 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2335 | err = ntfs_mft_data_extend_allocation_nolock(vol); | 2396 | err = ntfs_mft_data_extend_allocation_nolock(vol); |
2336 | if (unlikely(err)) { | 2397 | if (unlikely(err)) { |
2337 | ntfs_error(vol->sb, "Failed to extend mft data " | 2398 | ntfs_error(vol->sb, "Failed to extend mft data " |
2338 | "allocation."); | 2399 | "allocation."); |
2339 | goto undo_mftbmp_alloc_nolock; | 2400 | goto undo_mftbmp_alloc_nolock; |
2340 | } | 2401 | } |
2402 | read_lock_irqsave(&mft_ni->size_lock, flags); | ||
2341 | ntfs_debug("Status of mft data after allocation extension: " | 2403 | ntfs_debug("Status of mft data after allocation extension: " |
2342 | "allocated_size 0x%llx, data_size 0x%llx, " | 2404 | "allocated_size 0x%llx, data_size 0x%llx, " |
2343 | "initialized_size 0x%llx.", | 2405 | "initialized_size 0x%llx.", |
2344 | (long long)mft_ni->allocated_size, | 2406 | (long long)mft_ni->allocated_size, |
2345 | (long long)vol->mft_ino->i_size, | 2407 | (long long)i_size_read(vol->mft_ino), |
2346 | (long long)mft_ni->initialized_size); | 2408 | (long long)mft_ni->initialized_size); |
2347 | } | 2409 | } |
2410 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2348 | /* | 2411 | /* |
2349 | * Extend mft data initialized size (and data size of course) to reach | 2412 | * Extend mft data initialized size (and data size of course) to reach |
2350 | * the allocated mft record, formatting the mft records allong the way. | 2413 | * the allocated mft record, formatting the mft records allong the way. |
@@ -2352,6 +2415,7 @@ have_alloc_rec: | |||
2352 | * needed by ntfs_mft_record_format(). We will update the attribute | 2415 | * needed by ntfs_mft_record_format(). We will update the attribute |
2353 | * record itself in one fell swoop later on. | 2416 | * record itself in one fell swoop later on. |
2354 | */ | 2417 | */ |
2418 | write_lock_irqsave(&mft_ni->size_lock, flags); | ||
2355 | old_data_initialized = mft_ni->initialized_size; | 2419 | old_data_initialized = mft_ni->initialized_size; |
2356 | old_data_size = vol->mft_ino->i_size; | 2420 | old_data_size = vol->mft_ino->i_size; |
2357 | while (ll > mft_ni->initialized_size) { | 2421 | while (ll > mft_ni->initialized_size) { |
@@ -2360,8 +2424,9 @@ have_alloc_rec: | |||
2360 | new_initialized_size = mft_ni->initialized_size + | 2424 | new_initialized_size = mft_ni->initialized_size + |
2361 | vol->mft_record_size; | 2425 | vol->mft_record_size; |
2362 | mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits; | 2426 | mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits; |
2363 | if (new_initialized_size > vol->mft_ino->i_size) | 2427 | if (new_initialized_size > i_size_read(vol->mft_ino)) |
2364 | vol->mft_ino->i_size = new_initialized_size; | 2428 | i_size_write(vol->mft_ino, new_initialized_size); |
2429 | write_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2365 | ntfs_debug("Initializing mft record 0x%llx.", | 2430 | ntfs_debug("Initializing mft record 0x%llx.", |
2366 | (long long)mft_no); | 2431 | (long long)mft_no); |
2367 | err = ntfs_mft_record_format(vol, mft_no); | 2432 | err = ntfs_mft_record_format(vol, mft_no); |
@@ -2369,8 +2434,10 @@ have_alloc_rec: | |||
2369 | ntfs_error(vol->sb, "Failed to format mft record."); | 2434 | ntfs_error(vol->sb, "Failed to format mft record."); |
2370 | goto undo_data_init; | 2435 | goto undo_data_init; |
2371 | } | 2436 | } |
2437 | write_lock_irqsave(&mft_ni->size_lock, flags); | ||
2372 | mft_ni->initialized_size = new_initialized_size; | 2438 | mft_ni->initialized_size = new_initialized_size; |
2373 | } | 2439 | } |
2440 | write_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2374 | record_formatted = TRUE; | 2441 | record_formatted = TRUE; |
2375 | /* Update the mft data attribute record to reflect the new sizes. */ | 2442 | /* Update the mft data attribute record to reflect the new sizes. */ |
2376 | m = map_mft_record(mft_ni); | 2443 | m = map_mft_record(mft_ni); |
@@ -2396,22 +2463,27 @@ have_alloc_rec: | |||
2396 | goto undo_data_init; | 2463 | goto undo_data_init; |
2397 | } | 2464 | } |
2398 | a = ctx->attr; | 2465 | a = ctx->attr; |
2466 | read_lock_irqsave(&mft_ni->size_lock, flags); | ||
2399 | a->data.non_resident.initialized_size = | 2467 | a->data.non_resident.initialized_size = |
2400 | cpu_to_sle64(mft_ni->initialized_size); | 2468 | cpu_to_sle64(mft_ni->initialized_size); |
2401 | a->data.non_resident.data_size = cpu_to_sle64(vol->mft_ino->i_size); | 2469 | a->data.non_resident.data_size = |
2470 | cpu_to_sle64(i_size_read(vol->mft_ino)); | ||
2471 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2402 | /* Ensure the changes make it to disk. */ | 2472 | /* Ensure the changes make it to disk. */ |
2403 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 2473 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
2404 | mark_mft_record_dirty(ctx->ntfs_ino); | 2474 | mark_mft_record_dirty(ctx->ntfs_ino); |
2405 | ntfs_attr_put_search_ctx(ctx); | 2475 | ntfs_attr_put_search_ctx(ctx); |
2406 | unmap_mft_record(mft_ni); | 2476 | unmap_mft_record(mft_ni); |
2477 | read_lock_irqsave(&mft_ni->size_lock, flags); | ||
2407 | ntfs_debug("Status of mft data after mft record initialization: " | 2478 | ntfs_debug("Status of mft data after mft record initialization: " |
2408 | "allocated_size 0x%llx, data_size 0x%llx, " | 2479 | "allocated_size 0x%llx, data_size 0x%llx, " |
2409 | "initialized_size 0x%llx.", | 2480 | "initialized_size 0x%llx.", |
2410 | (long long)mft_ni->allocated_size, | 2481 | (long long)mft_ni->allocated_size, |
2411 | (long long)vol->mft_ino->i_size, | 2482 | (long long)i_size_read(vol->mft_ino), |
2412 | (long long)mft_ni->initialized_size); | 2483 | (long long)mft_ni->initialized_size); |
2413 | BUG_ON(vol->mft_ino->i_size > mft_ni->allocated_size); | 2484 | BUG_ON(i_size_read(vol->mft_ino) > mft_ni->allocated_size); |
2414 | BUG_ON(mft_ni->initialized_size > vol->mft_ino->i_size); | 2485 | BUG_ON(mft_ni->initialized_size > i_size_read(vol->mft_ino)); |
2486 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2415 | mft_rec_already_initialized: | 2487 | mft_rec_already_initialized: |
2416 | /* | 2488 | /* |
2417 | * We can finally drop the mft bitmap lock as the mft data attribute | 2489 | * We can finally drop the mft bitmap lock as the mft data attribute |
@@ -2652,8 +2724,10 @@ mft_rec_already_initialized: | |||
2652 | *mrec = m; | 2724 | *mrec = m; |
2653 | return ni; | 2725 | return ni; |
2654 | undo_data_init: | 2726 | undo_data_init: |
2727 | write_lock_irqsave(&mft_ni->size_lock, flags); | ||
2655 | mft_ni->initialized_size = old_data_initialized; | 2728 | mft_ni->initialized_size = old_data_initialized; |
2656 | vol->mft_ino->i_size = old_data_size; | 2729 | i_size_write(vol->mft_ino, old_data_size); |
2730 | write_unlock_irqrestore(&mft_ni->size_lock, flags); | ||
2657 | goto undo_mftbmp_alloc_nolock; | 2731 | goto undo_mftbmp_alloc_nolock; |
2658 | undo_mftbmp_alloc: | 2732 | undo_mftbmp_alloc: |
2659 | down_write(&vol->mftbmp_lock); | 2733 | down_write(&vol->mftbmp_lock); |