diff options
Diffstat (limited to 'fs/ntfs/mft.c')
-rw-r--r-- | fs/ntfs/mft.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 4e0bf39426cf..0975d738834c 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 |
@@ -287,7 +287,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, | |||
287 | } | 287 | } |
288 | unmap_mft_record(ni); | 288 | unmap_mft_record(ni); |
289 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " | 289 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " |
290 | "reference! Corrupt file system. " | 290 | "reference! Corrupt filesystem. " |
291 | "Run chkdsk."); | 291 | "Run chkdsk."); |
292 | return ERR_PTR(-EIO); | 292 | return ERR_PTR(-EIO); |
293 | } | 293 | } |
@@ -318,7 +318,7 @@ map_err_out: | |||
318 | /* Verify the sequence number if it is present. */ | 318 | /* Verify the sequence number if it is present. */ |
319 | if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { | 319 | if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { |
320 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " | 320 | ntfs_error(base_ni->vol->sb, "Found stale extent mft " |
321 | "reference! Corrupt file system. Run chkdsk."); | 321 | "reference! Corrupt filesystem. Run chkdsk."); |
322 | destroy_ni = TRUE; | 322 | destroy_ni = TRUE; |
323 | m = ERR_PTR(-EIO); | 323 | m = ERR_PTR(-EIO); |
324 | goto unm_err_out; | 324 | goto unm_err_out; |
@@ -1292,19 +1292,20 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1292 | /* | 1292 | /* |
1293 | * 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 |
1294 | * 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. |
1295 | * ntfs_find_vcn() returns the runlist locked on success. | ||
1296 | */ | 1295 | */ |
1296 | down_write(&mftbmp_ni->runlist.lock); | ||
1297 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); | 1297 | read_lock_irqsave(&mftbmp_ni->size_lock, flags); |
1298 | ll = mftbmp_ni->allocated_size; | 1298 | ll = mftbmp_ni->allocated_size; |
1299 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | 1299 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); |
1300 | rl = ntfs_find_vcn(mftbmp_ni, (ll - 1) >> vol->cluster_size_bits, TRUE); | 1300 | rl = ntfs_find_vcn_nolock(mftbmp_ni, |
1301 | (ll - 1) >> vol->cluster_size_bits, TRUE); | ||
1301 | 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); | ||
1302 | ntfs_error(vol->sb, "Failed to determine last allocated " | 1304 | ntfs_error(vol->sb, "Failed to determine last allocated " |
1303 | "cluster of mft bitmap attribute."); | 1305 | "cluster of mft bitmap attribute."); |
1304 | if (!IS_ERR(rl)) { | 1306 | if (!IS_ERR(rl)) |
1305 | up_write(&mftbmp_ni->runlist.lock); | ||
1306 | ret = -EIO; | 1307 | ret = -EIO; |
1307 | } else | 1308 | else |
1308 | ret = PTR_ERR(rl); | 1309 | ret = PTR_ERR(rl); |
1309 | return ret; | 1310 | return ret; |
1310 | } | 1311 | } |
@@ -1428,6 +1429,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1428 | // 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 |
1429 | // 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 |
1430 | // 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... | ||
1431 | 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 " |
1432 | "accomodate extended mft bitmap attribute " | 1435 | "accomodate extended mft bitmap attribute " |
1433 | "extent. Cannot handle this yet."); | 1436 | "extent. Cannot handle this yet."); |
@@ -1719,19 +1722,20 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1719 | * Determine the preferred allocation location, i.e. the last lcn of | 1722 | * Determine the preferred allocation location, i.e. the last lcn of |
1720 | * the mft data attribute. The allocated size of the mft data | 1723 | * the mft data attribute. The allocated size of the mft data |
1721 | * attribute cannot be zero so we are ok to do this. | 1724 | * attribute cannot be zero so we are ok to do this. |
1722 | * ntfs_find_vcn() returns the runlist locked on success. | ||
1723 | */ | 1725 | */ |
1726 | down_write(&mft_ni->runlist.lock); | ||
1724 | read_lock_irqsave(&mft_ni->size_lock, flags); | 1727 | read_lock_irqsave(&mft_ni->size_lock, flags); |
1725 | ll = mft_ni->allocated_size; | 1728 | ll = mft_ni->allocated_size; |
1726 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | 1729 | read_unlock_irqrestore(&mft_ni->size_lock, flags); |
1727 | rl = ntfs_find_vcn(mft_ni, (ll - 1) >> vol->cluster_size_bits, TRUE); | 1730 | rl = ntfs_find_vcn_nolock(mft_ni, (ll - 1) >> vol->cluster_size_bits, |
1731 | TRUE); | ||
1728 | 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); | ||
1729 | ntfs_error(vol->sb, "Failed to determine last allocated " | 1734 | ntfs_error(vol->sb, "Failed to determine last allocated " |
1730 | "cluster of mft data attribute."); | 1735 | "cluster of mft data attribute."); |
1731 | if (!IS_ERR(rl)) { | 1736 | if (!IS_ERR(rl)) |
1732 | up_write(&mft_ni->runlist.lock); | ||
1733 | ret = -EIO; | 1737 | ret = -EIO; |
1734 | } else | 1738 | else |
1735 | ret = PTR_ERR(rl); | 1739 | ret = PTR_ERR(rl); |
1736 | return ret; | 1740 | return ret; |
1737 | } | 1741 | } |
@@ -1858,7 +1862,11 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1858 | // moving other attributes out of this mft record. | 1862 | // moving other attributes out of this mft record. |
1859 | // Note: Use the special reserved mft records and ensure that | 1863 | // Note: Use the special reserved mft records and ensure that |
1860 | // this extent is not required to find the mft record in | 1864 | // this extent is not required to find the mft record in |
1861 | // 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... | ||
1862 | 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 " |
1863 | "accomodate extended mft data attribute " | 1871 | "accomodate extended mft data attribute " |
1864 | "extent. Cannot handle this yet."); | 1872 | "extent. Cannot handle this yet."); |
@@ -2021,7 +2029,7 @@ static int ntfs_mft_record_layout(const ntfs_volume *vol, const s64 mft_no, | |||
2021 | "reports this as corruption, please email " | 2029 | "reports this as corruption, please email " |
2022 | "linux-ntfs-dev@lists.sourceforge.net stating " | 2030 | "linux-ntfs-dev@lists.sourceforge.net stating " |
2023 | "that you saw this message and that the " | 2031 | "that you saw this message and that the " |
2024 | "modified file system created was corrupt. " | 2032 | "modified filesystem created was corrupt. " |
2025 | "Thank you."); | 2033 | "Thank you."); |
2026 | } | 2034 | } |
2027 | /* Set the update sequence number to 1. */ | 2035 | /* Set the update sequence number to 1. */ |