aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/mft.c
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-01-12 08:08:26 -0500
committerAnton Altaparmakov <aia21@cantab.net>2005-05-05 05:39:08 -0400
commit07a4e2da7dd3c9345f84b2552872f9d38c257451 (patch)
tree8fbd4c3e11196752ae8ff7944ccb26b93cafbb1c /fs/ntfs/mft.c
parentf50f3ac51983025405a71b70b033cc6bcb0d1fc1 (diff)
NTFS: Use i_size_{read,write}() in fs/ntfs/{aops.c,mft.c} and protect
access to the i_size and other size fields using the size_lock. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/mft.c')
-rw-r--r--fs/ntfs/mft.c157
1 files changed, 113 insertions, 44 deletions
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index dfa85ac2f8ba..20011e02f5b6 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -45,6 +45,7 @@
45 */ 45 */
46static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) 46static 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. "
@@ -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;
@@ -1286,8 +1294,10 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
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. 1295 * ntfs_find_vcn() returns the runlist locked on success.
1288 */ 1296 */
1289 rl = ntfs_find_vcn(mftbmp_ni, (mftbmp_ni->allocated_size - 1) >> 1297 read_lock_irqsave(&mftbmp_ni->size_lock, flags);
1290 vol->cluster_size_bits, TRUE); 1298 ll = mftbmp_ni->allocated_size;
1299 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
1300 rl = ntfs_find_vcn(mftbmp_ni, (ll - 1) >> vol->cluster_size_bits, TRUE);
1291 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { 1301 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
1292 ntfs_error(vol->sb, "Failed to determine last allocated " 1302 ntfs_error(vol->sb, "Failed to determine last allocated "
1293 "cluster of mft bitmap attribute."); 1303 "cluster of mft bitmap attribute.");
@@ -1458,9 +1468,11 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
1458 } 1468 }
1459 a = ctx->attr; 1469 a = ctx->attr;
1460 } 1470 }
1471 write_lock_irqsave(&mftbmp_ni->size_lock, flags);
1461 mftbmp_ni->allocated_size += vol->cluster_size; 1472 mftbmp_ni->allocated_size += vol->cluster_size;
1462 a->data.non_resident.allocated_size = 1473 a->data.non_resident.allocated_size =
1463 cpu_to_sle64(mftbmp_ni->allocated_size); 1474 cpu_to_sle64(mftbmp_ni->allocated_size);
1475 write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
1464 /* Ensure the changes make it to disk. */ 1476 /* Ensure the changes make it to disk. */
1465 flush_dcache_mft_record_page(ctx->ntfs_ino); 1477 flush_dcache_mft_record_page(ctx->ntfs_ino);
1466 mark_mft_record_dirty(ctx->ntfs_ino); 1478 mark_mft_record_dirty(ctx->ntfs_ino);
@@ -1476,7 +1488,9 @@ restore_undo_alloc:
1476 0, ctx)) { 1488 0, ctx)) {
1477 ntfs_error(vol->sb, "Failed to find last attribute extent of " 1489 ntfs_error(vol->sb, "Failed to find last attribute extent of "
1478 "mft bitmap attribute.%s", es); 1490 "mft bitmap attribute.%s", es);
1491 write_lock_irqsave(&mftbmp_ni->size_lock, flags);
1479 mftbmp_ni->allocated_size += vol->cluster_size; 1492 mftbmp_ni->allocated_size += vol->cluster_size;
1493 write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
1480 ntfs_attr_put_search_ctx(ctx); 1494 ntfs_attr_put_search_ctx(ctx);
1481 unmap_mft_record(mft_ni); 1495 unmap_mft_record(mft_ni);
1482 up_write(&mftbmp_ni->runlist.lock); 1496 up_write(&mftbmp_ni->runlist.lock);
@@ -1550,6 +1564,7 @@ undo_alloc:
1550static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol) 1564static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol)
1551{ 1565{
1552 s64 old_data_size, old_initialized_size; 1566 s64 old_data_size, old_initialized_size;
1567 unsigned long flags;
1553 struct inode *mftbmp_vi; 1568 struct inode *mftbmp_vi;
1554 ntfs_inode *mft_ni, *mftbmp_ni; 1569 ntfs_inode *mft_ni, *mftbmp_ni;
1555 ntfs_attr_search_ctx *ctx; 1570 ntfs_attr_search_ctx *ctx;
@@ -1583,7 +1598,8 @@ static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol)
1583 goto put_err_out; 1598 goto put_err_out;
1584 } 1599 }
1585 a = ctx->attr; 1600 a = ctx->attr;
1586 old_data_size = mftbmp_vi->i_size; 1601 write_lock_irqsave(&mftbmp_ni->size_lock, flags);
1602 old_data_size = i_size_read(mftbmp_vi);
1587 old_initialized_size = mftbmp_ni->initialized_size; 1603 old_initialized_size = mftbmp_ni->initialized_size;
1588 /* 1604 /*
1589 * We can simply update the initialized_size before filling the space 1605 * We can simply update the initialized_size before filling the space
@@ -1593,11 +1609,12 @@ static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol)
1593 mftbmp_ni->initialized_size += 8; 1609 mftbmp_ni->initialized_size += 8;
1594 a->data.non_resident.initialized_size = 1610 a->data.non_resident.initialized_size =
1595 cpu_to_sle64(mftbmp_ni->initialized_size); 1611 cpu_to_sle64(mftbmp_ni->initialized_size);
1596 if (mftbmp_ni->initialized_size > mftbmp_vi->i_size) { 1612 if (mftbmp_ni->initialized_size > old_data_size) {
1597 mftbmp_vi->i_size = mftbmp_ni->initialized_size; 1613 i_size_write(mftbmp_vi, mftbmp_ni->initialized_size);
1598 a->data.non_resident.data_size = 1614 a->data.non_resident.data_size =
1599 cpu_to_sle64(mftbmp_vi->i_size); 1615 cpu_to_sle64(mftbmp_ni->initialized_size);
1600 } 1616 }
1617 write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
1601 /* Ensure the changes make it to disk. */ 1618 /* Ensure the changes make it to disk. */
1602 flush_dcache_mft_record_page(ctx->ntfs_ino); 1619 flush_dcache_mft_record_page(ctx->ntfs_ino);
1603 mark_mft_record_dirty(ctx->ntfs_ino); 1620 mark_mft_record_dirty(ctx->ntfs_ino);
@@ -1636,22 +1653,28 @@ unm_err_out:
1636 goto err_out; 1653 goto err_out;
1637 } 1654 }
1638 a = ctx->attr; 1655 a = ctx->attr;
1656 write_lock_irqsave(&mftbmp_ni->size_lock, flags);
1639 mftbmp_ni->initialized_size = old_initialized_size; 1657 mftbmp_ni->initialized_size = old_initialized_size;
1640 a->data.non_resident.initialized_size = 1658 a->data.non_resident.initialized_size =
1641 cpu_to_sle64(old_initialized_size); 1659 cpu_to_sle64(old_initialized_size);
1642 if (mftbmp_vi->i_size != old_data_size) { 1660 if (i_size_read(mftbmp_vi) != old_data_size) {
1643 mftbmp_vi->i_size = old_data_size; 1661 i_size_write(mftbmp_vi, old_data_size);
1644 a->data.non_resident.data_size = cpu_to_sle64(old_data_size); 1662 a->data.non_resident.data_size = cpu_to_sle64(old_data_size);
1645 } 1663 }
1664 write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
1646 flush_dcache_mft_record_page(ctx->ntfs_ino); 1665 flush_dcache_mft_record_page(ctx->ntfs_ino);
1647 mark_mft_record_dirty(ctx->ntfs_ino); 1666 mark_mft_record_dirty(ctx->ntfs_ino);
1648 ntfs_attr_put_search_ctx(ctx); 1667 ntfs_attr_put_search_ctx(ctx);
1649 unmap_mft_record(mft_ni); 1668 unmap_mft_record(mft_ni);
1669#ifdef DEBUG
1670 read_lock_irqsave(&mftbmp_ni->size_lock, flags);
1650 ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, " 1671 ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, "
1651 "data_size 0x%llx, initialized_size 0x%llx.", 1672 "data_size 0x%llx, initialized_size 0x%llx.",
1652 (long long)mftbmp_ni->allocated_size, 1673 (long long)mftbmp_ni->allocated_size,
1653 (long long)mftbmp_vi->i_size, 1674 (long long)i_size_read(mftbmp_vi),
1654 (long long)mftbmp_ni->initialized_size); 1675 (long long)mftbmp_ni->initialized_size);
1676 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
1677#endif /* DEBUG */
1655err_out: 1678err_out:
1656 return ret; 1679 return ret;
1657} 1680}
@@ -1679,7 +1702,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1679{ 1702{
1680 LCN lcn; 1703 LCN lcn;
1681 VCN old_last_vcn; 1704 VCN old_last_vcn;
1682 s64 min_nr, nr, ll = 0; 1705 s64 min_nr, nr, ll;
1706 unsigned long flags;
1683 ntfs_inode *mft_ni; 1707 ntfs_inode *mft_ni;
1684 runlist_element *rl, *rl2; 1708 runlist_element *rl, *rl2;
1685 ntfs_attr_search_ctx *ctx = NULL; 1709 ntfs_attr_search_ctx *ctx = NULL;
@@ -1697,8 +1721,10 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1697 * attribute cannot be zero so we are ok to do this. 1721 * attribute cannot be zero so we are ok to do this.
1698 * ntfs_find_vcn() returns the runlist locked on success. 1722 * ntfs_find_vcn() returns the runlist locked on success.
1699 */ 1723 */
1700 rl = ntfs_find_vcn(mft_ni, (mft_ni->allocated_size - 1) >> 1724 read_lock_irqsave(&mft_ni->size_lock, flags);
1701 vol->cluster_size_bits, TRUE); 1725 ll = mft_ni->allocated_size;
1726 read_unlock_irqrestore(&mft_ni->size_lock, flags);
1727 rl = ntfs_find_vcn(mft_ni, (ll - 1) >> vol->cluster_size_bits, TRUE);
1702 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { 1728 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
1703 ntfs_error(vol->sb, "Failed to determine last allocated " 1729 ntfs_error(vol->sb, "Failed to determine last allocated "
1704 "cluster of mft data attribute."); 1730 "cluster of mft data attribute.");
@@ -1710,8 +1736,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1710 return ret; 1736 return ret;
1711 } 1737 }
1712 lcn = rl->lcn + rl->length; 1738 lcn = rl->lcn + rl->length;
1713 ntfs_debug("Last lcn of mft data attribute is 0x%llx.", 1739 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. */ 1740 /* Minimum allocation is one mft record worth of clusters. */
1716 min_nr = vol->mft_record_size >> vol->cluster_size_bits; 1741 min_nr = vol->mft_record_size >> vol->cluster_size_bits;
1717 if (!min_nr) 1742 if (!min_nr)
@@ -1721,12 +1746,13 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1721 if (!nr) 1746 if (!nr)
1722 nr = min_nr; 1747 nr = min_nr;
1723 /* Ensure we do not go above 2^32-1 mft records. */ 1748 /* Ensure we do not go above 2^32-1 mft records. */
1724 if (unlikely((mft_ni->allocated_size + 1749 read_lock_irqsave(&mft_ni->size_lock, flags);
1725 (nr << vol->cluster_size_bits)) >> 1750 ll = mft_ni->allocated_size;
1751 read_unlock_irqrestore(&mft_ni->size_lock, flags);
1752 if (unlikely((ll + (nr << vol->cluster_size_bits)) >>
1726 vol->mft_record_size_bits >= (1ll << 32))) { 1753 vol->mft_record_size_bits >= (1ll << 32))) {
1727 nr = min_nr; 1754 nr = min_nr;
1728 if (unlikely((mft_ni->allocated_size + 1755 if (unlikely((ll + (nr << vol->cluster_size_bits)) >>
1729 (nr << vol->cluster_size_bits)) >>
1730 vol->mft_record_size_bits >= (1ll << 32))) { 1756 vol->mft_record_size_bits >= (1ll << 32))) {
1731 ntfs_warning(vol->sb, "Cannot allocate mft record " 1757 ntfs_warning(vol->sb, "Cannot allocate mft record "
1732 "because the maximum number of inodes " 1758 "because the maximum number of inodes "
@@ -1875,9 +1901,11 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1875 } 1901 }
1876 a = ctx->attr; 1902 a = ctx->attr;
1877 } 1903 }
1904 write_lock_irqsave(&mft_ni->size_lock, flags);
1878 mft_ni->allocated_size += nr << vol->cluster_size_bits; 1905 mft_ni->allocated_size += nr << vol->cluster_size_bits;
1879 a->data.non_resident.allocated_size = 1906 a->data.non_resident.allocated_size =
1880 cpu_to_sle64(mft_ni->allocated_size); 1907 cpu_to_sle64(mft_ni->allocated_size);
1908 write_unlock_irqrestore(&mft_ni->size_lock, flags);
1881 /* Ensure the changes make it to disk. */ 1909 /* Ensure the changes make it to disk. */
1882 flush_dcache_mft_record_page(ctx->ntfs_ino); 1910 flush_dcache_mft_record_page(ctx->ntfs_ino);
1883 mark_mft_record_dirty(ctx->ntfs_ino); 1911 mark_mft_record_dirty(ctx->ntfs_ino);
@@ -1892,7 +1920,9 @@ restore_undo_alloc:
1892 CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) { 1920 CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) {
1893 ntfs_error(vol->sb, "Failed to find last attribute extent of " 1921 ntfs_error(vol->sb, "Failed to find last attribute extent of "
1894 "mft data attribute.%s", es); 1922 "mft data attribute.%s", es);
1923 write_lock_irqsave(&mft_ni->size_lock, flags);
1895 mft_ni->allocated_size += nr << vol->cluster_size_bits; 1924 mft_ni->allocated_size += nr << vol->cluster_size_bits;
1925 write_unlock_irqrestore(&mft_ni->size_lock, flags);
1896 ntfs_attr_put_search_ctx(ctx); 1926 ntfs_attr_put_search_ctx(ctx);
1897 unmap_mft_record(mft_ni); 1927 unmap_mft_record(mft_ni);
1898 up_write(&mft_ni->runlist.lock); 1928 up_write(&mft_ni->runlist.lock);
@@ -2036,6 +2066,7 @@ static int ntfs_mft_record_layout(const ntfs_volume *vol, const s64 mft_no,
2036 */ 2066 */
2037static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no) 2067static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no)
2038{ 2068{
2069 loff_t i_size;
2039 struct inode *mft_vi = vol->mft_ino; 2070 struct inode *mft_vi = vol->mft_ino;
2040 struct page *page; 2071 struct page *page;
2041 MFT_RECORD *m; 2072 MFT_RECORD *m;
@@ -2051,10 +2082,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; 2082 index = mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;
2052 ofs = (mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; 2083 ofs = (mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
2053 /* The maximum valid index into the page cache for $MFT's data. */ 2084 /* The maximum valid index into the page cache for $MFT's data. */
2054 end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT; 2085 i_size = i_size_read(mft_vi);
2086 end_index = i_size >> PAGE_CACHE_SHIFT;
2055 if (unlikely(index >= end_index)) { 2087 if (unlikely(index >= end_index)) {
2056 if (unlikely(index > end_index || ofs + vol->mft_record_size >= 2088 if (unlikely(index > end_index || ofs + vol->mft_record_size >=
2057 (mft_vi->i_size & ~PAGE_CACHE_MASK))) { 2089 (i_size & ~PAGE_CACHE_MASK))) {
2058 ntfs_error(vol->sb, "Tried to format non-existing mft " 2090 ntfs_error(vol->sb, "Tried to format non-existing mft "
2059 "record 0x%llx.", (long long)mft_no); 2091 "record 0x%llx.", (long long)mft_no);
2060 return -ENOENT; 2092 return -ENOENT;
@@ -2188,6 +2220,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
2188 ntfs_inode *base_ni, MFT_RECORD **mrec) 2220 ntfs_inode *base_ni, MFT_RECORD **mrec)
2189{ 2221{
2190 s64 ll, bit, old_data_initialized, old_data_size; 2222 s64 ll, bit, old_data_initialized, old_data_size;
2223 unsigned long flags;
2191 struct inode *vi; 2224 struct inode *vi;
2192 struct page *page; 2225 struct page *page;
2193 ntfs_inode *mft_ni, *mftbmp_ni, *ni; 2226 ntfs_inode *mft_ni, *mftbmp_ni, *ni;
@@ -2237,9 +2270,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 2270 * the first 24 mft records as they are special and whilst they may not
2238 * be in use, we do not allocate from them. 2271 * be in use, we do not allocate from them.
2239 */ 2272 */
2273 read_lock_irqsave(&mft_ni->size_lock, flags);
2240 ll = mft_ni->initialized_size >> vol->mft_record_size_bits; 2274 ll = mft_ni->initialized_size >> vol->mft_record_size_bits;
2241 if (mftbmp_ni->initialized_size << 3 > ll && 2275 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2242 mftbmp_ni->initialized_size > 3) { 2276 read_lock_irqsave(&mftbmp_ni->size_lock, flags);
2277 old_data_initialized = mftbmp_ni->initialized_size;
2278 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
2279 if (old_data_initialized << 3 > ll && old_data_initialized > 3) {
2243 bit = ll; 2280 bit = ll;
2244 if (bit < 24) 2281 if (bit < 24)
2245 bit = 24; 2282 bit = 24;
@@ -2254,15 +2291,18 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
2254 * mft record that we can allocate. 2291 * mft record that we can allocate.
2255 * Note: The smallest mft record we allocate is mft record 24. 2292 * Note: The smallest mft record we allocate is mft record 24.
2256 */ 2293 */
2257 bit = mftbmp_ni->initialized_size << 3; 2294 bit = old_data_initialized << 3;
2258 if (unlikely(bit >= (1ll << 32))) 2295 if (unlikely(bit >= (1ll << 32)))
2259 goto max_err_out; 2296 goto max_err_out;
2297 read_lock_irqsave(&mftbmp_ni->size_lock, flags);
2298 old_data_size = mftbmp_ni->allocated_size;
2260 ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, " 2299 ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, "
2261 "data_size 0x%llx, initialized_size 0x%llx.", 2300 "data_size 0x%llx, initialized_size 0x%llx.",
2262 (long long)mftbmp_ni->allocated_size, 2301 (long long)old_data_size,
2263 (long long)vol->mftbmp_ino->i_size, 2302 (long long)i_size_read(vol->mftbmp_ino),
2264 (long long)mftbmp_ni->initialized_size); 2303 (long long)old_data_initialized);
2265 if (mftbmp_ni->initialized_size + 8 > mftbmp_ni->allocated_size) { 2304 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
2305 if (old_data_initialized + 8 > old_data_size) {
2266 /* Need to extend bitmap by one more cluster. */ 2306 /* Need to extend bitmap by one more cluster. */
2267 ntfs_debug("mftbmp: initialized_size + 8 > allocated_size."); 2307 ntfs_debug("mftbmp: initialized_size + 8 > allocated_size.");
2268 err = ntfs_mft_bitmap_extend_allocation_nolock(vol); 2308 err = ntfs_mft_bitmap_extend_allocation_nolock(vol);
@@ -2270,12 +2310,16 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
2270 up_write(&vol->mftbmp_lock); 2310 up_write(&vol->mftbmp_lock);
2271 goto err_out; 2311 goto err_out;
2272 } 2312 }
2313#ifdef DEBUG
2314 read_lock_irqsave(&mftbmp_ni->size_lock, flags);
2273 ntfs_debug("Status of mftbmp after allocation extension: " 2315 ntfs_debug("Status of mftbmp after allocation extension: "
2274 "allocated_size 0x%llx, data_size 0x%llx, " 2316 "allocated_size 0x%llx, data_size 0x%llx, "
2275 "initialized_size 0x%llx.", 2317 "initialized_size 0x%llx.",
2276 (long long)mftbmp_ni->allocated_size, 2318 (long long)mftbmp_ni->allocated_size,
2277 (long long)vol->mftbmp_ino->i_size, 2319 (long long)i_size_read(vol->mftbmp_ino),
2278 (long long)mftbmp_ni->initialized_size); 2320 (long long)mftbmp_ni->initialized_size);
2321 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
2322#endif /* DEBUG */
2279 } 2323 }
2280 /* 2324 /*
2281 * We now have sufficient allocated space, extend the initialized_size 2325 * We now have sufficient allocated space, extend the initialized_size
@@ -2287,12 +2331,16 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
2287 up_write(&vol->mftbmp_lock); 2331 up_write(&vol->mftbmp_lock);
2288 goto err_out; 2332 goto err_out;
2289 } 2333 }
2334#ifdef DEBUG
2335 read_lock_irqsave(&mftbmp_ni->size_lock, flags);
2290 ntfs_debug("Status of mftbmp after initialized extention: " 2336 ntfs_debug("Status of mftbmp after initialized extention: "
2291 "allocated_size 0x%llx, data_size 0x%llx, " 2337 "allocated_size 0x%llx, data_size 0x%llx, "
2292 "initialized_size 0x%llx.", 2338 "initialized_size 0x%llx.",
2293 (long long)mftbmp_ni->allocated_size, 2339 (long long)mftbmp_ni->allocated_size,
2294 (long long)vol->mftbmp_ino->i_size, 2340 (long long)i_size_read(vol->mftbmp_ino),
2295 (long long)mftbmp_ni->initialized_size); 2341 (long long)mftbmp_ni->initialized_size);
2342 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
2343#endif /* DEBUG */
2296 ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit); 2344 ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit);
2297found_free_rec: 2345found_free_rec:
2298 /* @bit is the found free mft record, allocate it in the mft bitmap. */ 2346 /* @bit is the found free mft record, allocate it in the mft bitmap. */
@@ -2314,7 +2362,10 @@ have_alloc_rec:
2314 * parallel allocation could allocate the same mft record as this one. 2362 * parallel allocation could allocate the same mft record as this one.
2315 */ 2363 */
2316 ll = (bit + 1) << vol->mft_record_size_bits; 2364 ll = (bit + 1) << vol->mft_record_size_bits;
2317 if (ll <= mft_ni->initialized_size) { 2365 read_lock_irqsave(&mft_ni->size_lock, flags);
2366 old_data_initialized = mft_ni->initialized_size;
2367 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2368 if (ll <= old_data_initialized) {
2318 ntfs_debug("Allocated mft record already initialized."); 2369 ntfs_debug("Allocated mft record already initialized.");
2319 goto mft_rec_already_initialized; 2370 goto mft_rec_already_initialized;
2320 } 2371 }
@@ -2325,25 +2376,32 @@ have_alloc_rec:
2325 * actually traversed more than once when a freshly formatted volume is 2376 * actually traversed more than once when a freshly formatted volume is
2326 * first written to so it optimizes away nicely in the common case. 2377 * first written to so it optimizes away nicely in the common case.
2327 */ 2378 */
2379 read_lock_irqsave(&mft_ni->size_lock, flags);
2380 old_data_size = mft_ni->allocated_size;
2328 ntfs_debug("Status of mft data before extension: " 2381 ntfs_debug("Status of mft data before extension: "
2329 "allocated_size 0x%llx, data_size 0x%llx, " 2382 "allocated_size 0x%llx, data_size 0x%llx, "
2330 "initialized_size 0x%llx.", 2383 "initialized_size 0x%llx.",
2331 (long long)mft_ni->allocated_size, 2384 (long long)old_data_size,
2332 (long long)vol->mft_ino->i_size, 2385 (long long)i_size_read(vol->mft_ino),
2333 (long long)mft_ni->initialized_size); 2386 (long long)mft_ni->initialized_size);
2334 while (ll > mft_ni->allocated_size) { 2387 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2388 while (ll > old_data_size) {
2335 err = ntfs_mft_data_extend_allocation_nolock(vol); 2389 err = ntfs_mft_data_extend_allocation_nolock(vol);
2336 if (unlikely(err)) { 2390 if (unlikely(err)) {
2337 ntfs_error(vol->sb, "Failed to extend mft data " 2391 ntfs_error(vol->sb, "Failed to extend mft data "
2338 "allocation."); 2392 "allocation.");
2339 goto undo_mftbmp_alloc_nolock; 2393 goto undo_mftbmp_alloc_nolock;
2340 } 2394 }
2395#ifdef DEBUG
2396 read_lock_irqsave(&mft_ni->size_lock, flags);
2341 ntfs_debug("Status of mft data after allocation extension: " 2397 ntfs_debug("Status of mft data after allocation extension: "
2342 "allocated_size 0x%llx, data_size 0x%llx, " 2398 "allocated_size 0x%llx, data_size 0x%llx, "
2343 "initialized_size 0x%llx.", 2399 "initialized_size 0x%llx.",
2344 (long long)mft_ni->allocated_size, 2400 (long long)mft_ni->allocated_size,
2345 (long long)vol->mft_ino->i_size, 2401 (long long)i_size_read(vol->mft_ino),
2346 (long long)mft_ni->initialized_size); 2402 (long long)mft_ni->initialized_size);
2403 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2404#endif /* DEBUG */
2347 } 2405 }
2348 /* 2406 /*
2349 * Extend mft data initialized size (and data size of course) to reach 2407 * Extend mft data initialized size (and data size of course) to reach
@@ -2352,6 +2410,7 @@ have_alloc_rec:
2352 * needed by ntfs_mft_record_format(). We will update the attribute 2410 * needed by ntfs_mft_record_format(). We will update the attribute
2353 * record itself in one fell swoop later on. 2411 * record itself in one fell swoop later on.
2354 */ 2412 */
2413 write_lock_irqsave(&mft_ni->size_lock, flags);
2355 old_data_initialized = mft_ni->initialized_size; 2414 old_data_initialized = mft_ni->initialized_size;
2356 old_data_size = vol->mft_ino->i_size; 2415 old_data_size = vol->mft_ino->i_size;
2357 while (ll > mft_ni->initialized_size) { 2416 while (ll > mft_ni->initialized_size) {
@@ -2360,8 +2419,9 @@ have_alloc_rec:
2360 new_initialized_size = mft_ni->initialized_size + 2419 new_initialized_size = mft_ni->initialized_size +
2361 vol->mft_record_size; 2420 vol->mft_record_size;
2362 mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits; 2421 mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits;
2363 if (new_initialized_size > vol->mft_ino->i_size) 2422 if (new_initialized_size > i_size_read(vol->mft_ino))
2364 vol->mft_ino->i_size = new_initialized_size; 2423 i_size_write(vol->mft_ino, new_initialized_size);
2424 write_unlock_irqrestore(&mft_ni->size_lock, flags);
2365 ntfs_debug("Initializing mft record 0x%llx.", 2425 ntfs_debug("Initializing mft record 0x%llx.",
2366 (long long)mft_no); 2426 (long long)mft_no);
2367 err = ntfs_mft_record_format(vol, mft_no); 2427 err = ntfs_mft_record_format(vol, mft_no);
@@ -2369,8 +2429,10 @@ have_alloc_rec:
2369 ntfs_error(vol->sb, "Failed to format mft record."); 2429 ntfs_error(vol->sb, "Failed to format mft record.");
2370 goto undo_data_init; 2430 goto undo_data_init;
2371 } 2431 }
2432 write_lock_irqsave(&mft_ni->size_lock, flags);
2372 mft_ni->initialized_size = new_initialized_size; 2433 mft_ni->initialized_size = new_initialized_size;
2373 } 2434 }
2435 write_unlock_irqrestore(&mft_ni->size_lock, flags);
2374 record_formatted = TRUE; 2436 record_formatted = TRUE;
2375 /* Update the mft data attribute record to reflect the new sizes. */ 2437 /* Update the mft data attribute record to reflect the new sizes. */
2376 m = map_mft_record(mft_ni); 2438 m = map_mft_record(mft_ni);
@@ -2396,22 +2458,27 @@ have_alloc_rec:
2396 goto undo_data_init; 2458 goto undo_data_init;
2397 } 2459 }
2398 a = ctx->attr; 2460 a = ctx->attr;
2461 read_lock_irqsave(&mft_ni->size_lock, flags);
2399 a->data.non_resident.initialized_size = 2462 a->data.non_resident.initialized_size =
2400 cpu_to_sle64(mft_ni->initialized_size); 2463 cpu_to_sle64(mft_ni->initialized_size);
2401 a->data.non_resident.data_size = cpu_to_sle64(vol->mft_ino->i_size); 2464 a->data.non_resident.data_size =
2465 cpu_to_sle64(i_size_read(vol->mft_ino));
2466 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2402 /* Ensure the changes make it to disk. */ 2467 /* Ensure the changes make it to disk. */
2403 flush_dcache_mft_record_page(ctx->ntfs_ino); 2468 flush_dcache_mft_record_page(ctx->ntfs_ino);
2404 mark_mft_record_dirty(ctx->ntfs_ino); 2469 mark_mft_record_dirty(ctx->ntfs_ino);
2405 ntfs_attr_put_search_ctx(ctx); 2470 ntfs_attr_put_search_ctx(ctx);
2406 unmap_mft_record(mft_ni); 2471 unmap_mft_record(mft_ni);
2472 read_lock_irqsave(&mft_ni->size_lock, flags);
2407 ntfs_debug("Status of mft data after mft record initialization: " 2473 ntfs_debug("Status of mft data after mft record initialization: "
2408 "allocated_size 0x%llx, data_size 0x%llx, " 2474 "allocated_size 0x%llx, data_size 0x%llx, "
2409 "initialized_size 0x%llx.", 2475 "initialized_size 0x%llx.",
2410 (long long)mft_ni->allocated_size, 2476 (long long)mft_ni->allocated_size,
2411 (long long)vol->mft_ino->i_size, 2477 (long long)i_size_read(vol->mft_ino),
2412 (long long)mft_ni->initialized_size); 2478 (long long)mft_ni->initialized_size);
2413 BUG_ON(vol->mft_ino->i_size > mft_ni->allocated_size); 2479 BUG_ON(i_size_read(vol->mft_ino) > mft_ni->allocated_size);
2414 BUG_ON(mft_ni->initialized_size > vol->mft_ino->i_size); 2480 BUG_ON(mft_ni->initialized_size > i_size_read(vol->mft_ino));
2481 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2415mft_rec_already_initialized: 2482mft_rec_already_initialized:
2416 /* 2483 /*
2417 * We can finally drop the mft bitmap lock as the mft data attribute 2484 * We can finally drop the mft bitmap lock as the mft data attribute
@@ -2652,8 +2719,10 @@ mft_rec_already_initialized:
2652 *mrec = m; 2719 *mrec = m;
2653 return ni; 2720 return ni;
2654undo_data_init: 2721undo_data_init:
2722 write_lock_irqsave(&mft_ni->size_lock, flags);
2655 mft_ni->initialized_size = old_data_initialized; 2723 mft_ni->initialized_size = old_data_initialized;
2656 vol->mft_ino->i_size = old_data_size; 2724 i_size_write(vol->mft_ino, old_data_size);
2725 write_unlock_irqrestore(&mft_ni->size_lock, flags);
2657 goto undo_mftbmp_alloc_nolock; 2726 goto undo_mftbmp_alloc_nolock;
2658undo_mftbmp_alloc: 2727undo_mftbmp_alloc:
2659 down_write(&vol->mftbmp_lock); 2728 down_write(&vol->mftbmp_lock);