Commit fc0fa7dc7d243afabdb3fb6a11d59a944a9c91f8
1 parent
511bea5ea2
Exists in
master
and in
4 other branches
NTFS: - Change ntfs_cluster_alloc() to take an extra boolean parameter
specifying whether the cluster are being allocated to extend an attribute or to fill a hole. - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc() with @is_extension set to TRUE and remove the runlist terminator fixup code as this is now done by ntfs_cluster_alloc(). Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Showing 5 changed files with 25 additions and 15 deletions Side-by-side Diff
fs/ntfs/ChangeLog
... | ... | @@ -31,6 +31,12 @@ |
31 | 31 | - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock() |
32 | 32 | error handling by passing in the active search context when calling |
33 | 33 | ntfs_cluster_free(). |
34 | + - Change ntfs_cluster_alloc() to take an extra boolean parameter | |
35 | + specifying whether the cluster are being allocated to extend an | |
36 | + attribute or to fill a hole. | |
37 | + - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc() | |
38 | + with @is_extension set to TRUE and remove the runlist terminator | |
39 | + fixup code as this is now done by ntfs_cluster_alloc(). | |
34 | 40 | |
35 | 41 | 2.1.24 - Lots of bug fixes and support more clean journal states. |
36 | 42 |
fs/ntfs/attrib.c
... | ... | @@ -1566,8 +1566,6 @@ |
1566 | 1566 | new_size = (i_size_read(vi) + vol->cluster_size - 1) & |
1567 | 1567 | ~(vol->cluster_size - 1); |
1568 | 1568 | if (new_size > 0) { |
1569 | - runlist_element *rl2; | |
1570 | - | |
1571 | 1569 | /* |
1572 | 1570 | * Will need the page later and since the page lock nests |
1573 | 1571 | * outside all ntfs locks, we need to get the page now. |
... | ... | @@ -1578,7 +1576,7 @@ |
1578 | 1576 | return -ENOMEM; |
1579 | 1577 | /* Start by allocating clusters to hold the attribute value. */ |
1580 | 1578 | rl = ntfs_cluster_alloc(vol, 0, new_size >> |
1581 | - vol->cluster_size_bits, -1, DATA_ZONE); | |
1579 | + vol->cluster_size_bits, -1, DATA_ZONE, TRUE); | |
1582 | 1580 | if (IS_ERR(rl)) { |
1583 | 1581 | err = PTR_ERR(rl); |
1584 | 1582 | ntfs_debug("Failed to allocate cluster%s, error code " |
... | ... | @@ -1587,12 +1585,6 @@ |
1587 | 1585 | err); |
1588 | 1586 | goto page_err_out; |
1589 | 1587 | } |
1590 | - /* Change the runlist terminator to LCN_ENOENT. */ | |
1591 | - rl2 = rl; | |
1592 | - while (rl2->length) | |
1593 | - rl2++; | |
1594 | - BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED); | |
1595 | - rl2->lcn = LCN_ENOENT; | |
1596 | 1588 | } else { |
1597 | 1589 | rl = NULL; |
1598 | 1590 | page = NULL; |
fs/ntfs/lcnalloc.c
... | ... | @@ -76,6 +76,7 @@ |
76 | 76 | * @count: number of clusters to allocate |
77 | 77 | * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none) |
78 | 78 | * @zone: zone from which to allocate the clusters |
79 | + * @is_extension: if TRUE, this is an attribute extension | |
79 | 80 | * |
80 | 81 | * Allocate @count clusters preferably starting at cluster @start_lcn or at the |
81 | 82 | * current allocator position if @start_lcn is -1, on the mounted ntfs volume |
... | ... | @@ -86,6 +87,13 @@ |
86 | 87 | * @start_vcn specifies the vcn of the first allocated cluster. This makes |
87 | 88 | * merging the resulting runlist with the old runlist easier. |
88 | 89 | * |
90 | + * If @is_extension is TRUE, the caller is allocating clusters to extend an | |
91 | + * attribute and if it is FALSE, the caller is allocating clusters to fill a | |
92 | + * hole in an attribute. Practically the difference is that if @is_extension | |
93 | + * is TRUE the returned runlist will be terminated with LCN_ENOENT and if | |
94 | + * @is_extension is FALSE the runlist will be terminated with | |
95 | + * LCN_RL_NOT_MAPPED. | |
96 | + * | |
89 | 97 | * You need to check the return value with IS_ERR(). If this is false, the |
90 | 98 | * function was successful and the return value is a runlist describing the |
91 | 99 | * allocated cluster(s). If IS_ERR() is true, the function failed and |
... | ... | @@ -137,7 +145,8 @@ |
137 | 145 | */ |
138 | 146 | runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, |
139 | 147 | const s64 count, const LCN start_lcn, |
140 | - const NTFS_CLUSTER_ALLOCATION_ZONES zone) | |
148 | + const NTFS_CLUSTER_ALLOCATION_ZONES zone, | |
149 | + const BOOL is_extension) | |
141 | 150 | { |
142 | 151 | LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; |
143 | 152 | LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; |
... | ... | @@ -310,7 +319,7 @@ |
310 | 319 | continue; |
311 | 320 | } |
312 | 321 | bit = 1 << (lcn & 7); |
313 | - ntfs_debug("bit %i.", bit); | |
322 | + ntfs_debug("bit 0x%x.", bit); | |
314 | 323 | /* If the bit is already set, go onto the next one. */ |
315 | 324 | if (*byte & bit) { |
316 | 325 | lcn++; |
... | ... | @@ -729,7 +738,7 @@ |
729 | 738 | /* Add runlist terminator element. */ |
730 | 739 | if (likely(rl)) { |
731 | 740 | rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; |
732 | - rl[rlpos].lcn = LCN_RL_NOT_MAPPED; | |
741 | + rl[rlpos].lcn = is_extension ? LCN_ENOENT : LCN_RL_NOT_MAPPED; | |
733 | 742 | rl[rlpos].length = 0; |
734 | 743 | } |
735 | 744 | if (likely(page && !IS_ERR(page))) { |
fs/ntfs/lcnalloc.h
... | ... | @@ -42,7 +42,8 @@ |
42 | 42 | |
43 | 43 | extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, |
44 | 44 | const VCN start_vcn, const s64 count, const LCN start_lcn, |
45 | - const NTFS_CLUSTER_ALLOCATION_ZONES zone); | |
45 | + const NTFS_CLUSTER_ALLOCATION_ZONES zone, | |
46 | + const BOOL is_extension); | |
46 | 47 | |
47 | 48 | extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, |
48 | 49 | s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback); |
fs/ntfs/mft.c
... | ... | @@ -1355,7 +1355,8 @@ |
1355 | 1355 | up_write(&vol->lcnbmp_lock); |
1356 | 1356 | ntfs_unmap_page(page); |
1357 | 1357 | /* Allocate a cluster from the DATA_ZONE. */ |
1358 | - 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); | |
1359 | 1360 | if (IS_ERR(rl2)) { |
1360 | 1361 | up_write(&mftbmp_ni->runlist.lock); |
1361 | 1362 | ntfs_error(vol->sb, "Failed to allocate a cluster for " |
... | ... | @@ -1780,7 +1781,8 @@ |
1780 | 1781 | nr > min_nr ? "default" : "minimal", (long long)nr); |
1781 | 1782 | old_last_vcn = rl[1].vcn; |
1782 | 1783 | do { |
1783 | - 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); | |
1784 | 1786 | if (likely(!IS_ERR(rl2))) |
1785 | 1787 | break; |
1786 | 1788 | if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { |