diff options
Diffstat (limited to 'fs/ntfs/mft.c')
-rw-r--r-- | fs/ntfs/mft.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index b011369b5956..0c65cbb8c5cf 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c | |||
@@ -49,7 +49,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) | |||
49 | ntfs_volume *vol = ni->vol; | 49 | ntfs_volume *vol = ni->vol; |
50 | struct inode *mft_vi = vol->mft_ino; | 50 | struct inode *mft_vi = vol->mft_ino; |
51 | struct page *page; | 51 | struct page *page; |
52 | unsigned long index, ofs, end_index; | 52 | unsigned long index, end_index; |
53 | unsigned ofs; | ||
53 | 54 | ||
54 | BUG_ON(ni->page); | 55 | BUG_ON(ni->page); |
55 | /* | 56 | /* |
@@ -1308,7 +1309,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1308 | ll = mftbmp_ni->allocated_size; | 1309 | ll = mftbmp_ni->allocated_size; |
1309 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); | 1310 | read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); |
1310 | rl = ntfs_attr_find_vcn_nolock(mftbmp_ni, | 1311 | rl = ntfs_attr_find_vcn_nolock(mftbmp_ni, |
1311 | (ll - 1) >> vol->cluster_size_bits, TRUE); | 1312 | (ll - 1) >> vol->cluster_size_bits, NULL); |
1312 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { | 1313 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { |
1313 | up_write(&mftbmp_ni->runlist.lock); | 1314 | up_write(&mftbmp_ni->runlist.lock); |
1314 | ntfs_error(vol->sb, "Failed to determine last allocated " | 1315 | ntfs_error(vol->sb, "Failed to determine last allocated " |
@@ -1354,7 +1355,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
1354 | up_write(&vol->lcnbmp_lock); | 1355 | up_write(&vol->lcnbmp_lock); |
1355 | ntfs_unmap_page(page); | 1356 | ntfs_unmap_page(page); |
1356 | /* Allocate a cluster from the DATA_ZONE. */ | 1357 | /* Allocate a cluster from the DATA_ZONE. */ |
1357 | rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE); | 1358 | rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE, |
1359 | TRUE); | ||
1358 | if (IS_ERR(rl2)) { | 1360 | if (IS_ERR(rl2)) { |
1359 | up_write(&mftbmp_ni->runlist.lock); | 1361 | up_write(&mftbmp_ni->runlist.lock); |
1360 | ntfs_error(vol->sb, "Failed to allocate a cluster for " | 1362 | ntfs_error(vol->sb, "Failed to allocate a cluster for " |
@@ -1738,7 +1740,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1738 | ll = mft_ni->allocated_size; | 1740 | ll = mft_ni->allocated_size; |
1739 | read_unlock_irqrestore(&mft_ni->size_lock, flags); | 1741 | read_unlock_irqrestore(&mft_ni->size_lock, flags); |
1740 | rl = ntfs_attr_find_vcn_nolock(mft_ni, | 1742 | rl = ntfs_attr_find_vcn_nolock(mft_ni, |
1741 | (ll - 1) >> vol->cluster_size_bits, TRUE); | 1743 | (ll - 1) >> vol->cluster_size_bits, NULL); |
1742 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { | 1744 | if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { |
1743 | up_write(&mft_ni->runlist.lock); | 1745 | up_write(&mft_ni->runlist.lock); |
1744 | ntfs_error(vol->sb, "Failed to determine last allocated " | 1746 | ntfs_error(vol->sb, "Failed to determine last allocated " |
@@ -1779,7 +1781,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
1779 | nr > min_nr ? "default" : "minimal", (long long)nr); | 1781 | nr > min_nr ? "default" : "minimal", (long long)nr); |
1780 | old_last_vcn = rl[1].vcn; | 1782 | old_last_vcn = rl[1].vcn; |
1781 | do { | 1783 | do { |
1782 | rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE); | 1784 | rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE, |
1785 | TRUE); | ||
1783 | if (likely(!IS_ERR(rl2))) | 1786 | if (likely(!IS_ERR(rl2))) |
1784 | break; | 1787 | break; |
1785 | if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { | 1788 | if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { |
@@ -1951,20 +1954,21 @@ restore_undo_alloc: | |||
1951 | NVolSetErrors(vol); | 1954 | NVolSetErrors(vol); |
1952 | return ret; | 1955 | return ret; |
1953 | } | 1956 | } |
1954 | a = ctx->attr; | 1957 | ctx->attr->data.non_resident.highest_vcn = |
1955 | a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1); | 1958 | cpu_to_sle64(old_last_vcn - 1); |
1956 | undo_alloc: | 1959 | undo_alloc: |
1957 | if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) { | 1960 | if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) { |
1958 | ntfs_error(vol->sb, "Failed to free clusters from mft data " | 1961 | ntfs_error(vol->sb, "Failed to free clusters from mft data " |
1959 | "attribute.%s", es); | 1962 | "attribute.%s", es); |
1960 | NVolSetErrors(vol); | 1963 | NVolSetErrors(vol); |
1961 | } | 1964 | } |
1965 | a = ctx->attr; | ||
1962 | if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) { | 1966 | if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) { |
1963 | ntfs_error(vol->sb, "Failed to truncate mft data attribute " | 1967 | ntfs_error(vol->sb, "Failed to truncate mft data attribute " |
1964 | "runlist.%s", es); | 1968 | "runlist.%s", es); |
1965 | NVolSetErrors(vol); | 1969 | NVolSetErrors(vol); |
1966 | } | 1970 | } |
1967 | if (mp_rebuilt) { | 1971 | if (mp_rebuilt && !IS_ERR(ctx->mrec)) { |
1968 | if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( | 1972 | if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( |
1969 | a->data.non_resident.mapping_pairs_offset), | 1973 | a->data.non_resident.mapping_pairs_offset), |
1970 | old_alen - le16_to_cpu( | 1974 | old_alen - le16_to_cpu( |
@@ -1981,6 +1985,10 @@ undo_alloc: | |||
1981 | } | 1985 | } |
1982 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 1986 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
1983 | mark_mft_record_dirty(ctx->ntfs_ino); | 1987 | mark_mft_record_dirty(ctx->ntfs_ino); |
1988 | } else if (IS_ERR(ctx->mrec)) { | ||
1989 | ntfs_error(vol->sb, "Failed to restore attribute search " | ||
1990 | "context.%s", es); | ||
1991 | NVolSetErrors(vol); | ||
1984 | } | 1992 | } |
1985 | if (ctx) | 1993 | if (ctx) |
1986 | ntfs_attr_put_search_ctx(ctx); | 1994 | ntfs_attr_put_search_ctx(ctx); |