aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ntfs/ChangeLog6
-rw-r--r--fs/ntfs/attrib.c10
-rw-r--r--fs/ntfs/lcnalloc.c15
-rw-r--r--fs/ntfs/lcnalloc.h3
-rw-r--r--fs/ntfs/mft.c6
5 files changed, 25 insertions, 15 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 6e4f44eed6fa..aad2a3f2d1f8 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -31,6 +31,12 @@ ToDo/Notes:
31 - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock() 31 - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
32 error handling by passing in the active search context when calling 32 error handling by passing in the active search context when calling
33 ntfs_cluster_free(). 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
352.1.24 - Lots of bug fixes and support more clean journal states. 412.1.24 - Lots of bug fixes and support more clean journal states.
36 42
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 2aafc87e9601..33e689f82a55 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1566,8 +1566,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1566 new_size = (i_size_read(vi) + vol->cluster_size - 1) & 1566 new_size = (i_size_read(vi) + vol->cluster_size - 1) &
1567 ~(vol->cluster_size - 1); 1567 ~(vol->cluster_size - 1);
1568 if (new_size > 0) { 1568 if (new_size > 0) {
1569 runlist_element *rl2;
1570
1571 /* 1569 /*
1572 * Will need the page later and since the page lock nests 1570 * Will need the page later and since the page lock nests
1573 * outside all ntfs locks, we need to get the page now. 1571 * outside all ntfs locks, we need to get the page now.
@@ -1578,7 +1576,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1578 return -ENOMEM; 1576 return -ENOMEM;
1579 /* Start by allocating clusters to hold the attribute value. */ 1577 /* Start by allocating clusters to hold the attribute value. */
1580 rl = ntfs_cluster_alloc(vol, 0, new_size >> 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 if (IS_ERR(rl)) { 1580 if (IS_ERR(rl)) {
1583 err = PTR_ERR(rl); 1581 err = PTR_ERR(rl);
1584 ntfs_debug("Failed to allocate cluster%s, error code " 1582 ntfs_debug("Failed to allocate cluster%s, error code "
@@ -1587,12 +1585,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1587 err); 1585 err);
1588 goto page_err_out; 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 } else { 1588 } else {
1597 rl = NULL; 1589 rl = NULL;
1598 page = NULL; 1590 page = NULL;
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index 75313f4307e3..29cabf93d2d2 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -76,6 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
76 * @count: number of clusters to allocate 76 * @count: number of clusters to allocate
77 * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none) 77 * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none)
78 * @zone: zone from which to allocate the clusters 78 * @zone: zone from which to allocate the clusters
79 * @is_extension: if TRUE, this is an attribute extension
79 * 80 *
80 * Allocate @count clusters preferably starting at cluster @start_lcn or at the 81 * Allocate @count clusters preferably starting at cluster @start_lcn or at the
81 * current allocator position if @start_lcn is -1, on the mounted ntfs volume 82 * current allocator position if @start_lcn is -1, on the mounted ntfs volume
@@ -86,6 +87,13 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
86 * @start_vcn specifies the vcn of the first allocated cluster. This makes 87 * @start_vcn specifies the vcn of the first allocated cluster. This makes
87 * merging the resulting runlist with the old runlist easier. 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 * You need to check the return value with IS_ERR(). If this is false, the 97 * You need to check the return value with IS_ERR(). If this is false, the
90 * function was successful and the return value is a runlist describing the 98 * function was successful and the return value is a runlist describing the
91 * allocated cluster(s). If IS_ERR() is true, the function failed and 99 * allocated cluster(s). If IS_ERR() is true, the function failed and
@@ -137,7 +145,8 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
137 */ 145 */
138runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, 146runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
139 const s64 count, const LCN start_lcn, 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 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; 151 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
143 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; 152 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
@@ -310,7 +319,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
310 continue; 319 continue;
311 } 320 }
312 bit = 1 << (lcn & 7); 321 bit = 1 << (lcn & 7);
313 ntfs_debug("bit %i.", bit); 322 ntfs_debug("bit 0x%x.", bit);
314 /* If the bit is already set, go onto the next one. */ 323 /* If the bit is already set, go onto the next one. */
315 if (*byte & bit) { 324 if (*byte & bit) {
316 lcn++; 325 lcn++;
@@ -729,7 +738,7 @@ out:
729 /* Add runlist terminator element. */ 738 /* Add runlist terminator element. */
730 if (likely(rl)) { 739 if (likely(rl)) {
731 rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; 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 rl[rlpos].length = 0; 742 rl[rlpos].length = 0;
734 } 743 }
735 if (likely(page && !IS_ERR(page))) { 744 if (likely(page && !IS_ERR(page))) {
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
index aa0518509cd3..72cbca7003b2 100644
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -42,7 +42,8 @@ typedef enum {
42 42
43extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, 43extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
44 const VCN start_vcn, const s64 count, const LCN start_lcn, 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
47extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, 48extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
48 s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback); 49 s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback);
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 5577fc6e190f..0c65cbb8c5cf 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1355,7 +1355,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
1355 up_write(&vol->lcnbmp_lock); 1355 up_write(&vol->lcnbmp_lock);
1356 ntfs_unmap_page(page); 1356 ntfs_unmap_page(page);
1357 /* Allocate a cluster from the DATA_ZONE. */ 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 if (IS_ERR(rl2)) { 1360 if (IS_ERR(rl2)) {
1360 up_write(&mftbmp_ni->runlist.lock); 1361 up_write(&mftbmp_ni->runlist.lock);
1361 ntfs_error(vol->sb, "Failed to allocate a cluster for " 1362 ntfs_error(vol->sb, "Failed to allocate a cluster for "
@@ -1780,7 +1781,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1780 nr > min_nr ? "default" : "minimal", (long long)nr); 1781 nr > min_nr ? "default" : "minimal", (long long)nr);
1781 old_last_vcn = rl[1].vcn; 1782 old_last_vcn = rl[1].vcn;
1782 do { 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 if (likely(!IS_ERR(rl2))) 1786 if (likely(!IS_ERR(rl2)))
1785 break; 1787 break;
1786 if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { 1788 if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {