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>
This commit is contained in:
parent
511bea5ea2
commit
fc0fa7dc7d
@ -31,6 +31,12 @@ ToDo/Notes:
|
||||
- Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
|
||||
error handling by passing in the active search context when calling
|
||||
ntfs_cluster_free().
|
||||
- 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().
|
||||
|
||||
2.1.24 - Lots of bug fixes and support more clean journal states.
|
||||
|
||||
|
@ -1566,8 +1566,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
|
||||
new_size = (i_size_read(vi) + vol->cluster_size - 1) &
|
||||
~(vol->cluster_size - 1);
|
||||
if (new_size > 0) {
|
||||
runlist_element *rl2;
|
||||
|
||||
/*
|
||||
* Will need the page later and since the page lock nests
|
||||
* outside all ntfs locks, we need to get the page now.
|
||||
@ -1578,7 +1576,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
|
||||
return -ENOMEM;
|
||||
/* Start by allocating clusters to hold the attribute value. */
|
||||
rl = ntfs_cluster_alloc(vol, 0, new_size >>
|
||||
vol->cluster_size_bits, -1, DATA_ZONE);
|
||||
vol->cluster_size_bits, -1, DATA_ZONE, TRUE);
|
||||
if (IS_ERR(rl)) {
|
||||
err = PTR_ERR(rl);
|
||||
ntfs_debug("Failed to allocate cluster%s, error code "
|
||||
@ -1587,12 +1585,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
|
||||
err);
|
||||
goto page_err_out;
|
||||
}
|
||||
/* Change the runlist terminator to LCN_ENOENT. */
|
||||
rl2 = rl;
|
||||
while (rl2->length)
|
||||
rl2++;
|
||||
BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
|
||||
rl2->lcn = LCN_ENOENT;
|
||||
} else {
|
||||
rl = NULL;
|
||||
page = NULL;
|
||||
|
@ -76,6 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
|
||||
* @count: number of clusters to allocate
|
||||
* @start_lcn: starting lcn at which to allocate the clusters (or -1 if none)
|
||||
* @zone: zone from which to allocate the clusters
|
||||
* @is_extension: if TRUE, this is an attribute extension
|
||||
*
|
||||
* Allocate @count clusters preferably starting at cluster @start_lcn or at the
|
||||
* 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,
|
||||
* @start_vcn specifies the vcn of the first allocated cluster. This makes
|
||||
* merging the resulting runlist with the old runlist easier.
|
||||
*
|
||||
* If @is_extension is TRUE, the caller is allocating clusters to extend an
|
||||
* attribute and if it is FALSE, the caller is allocating clusters to fill a
|
||||
* hole in an attribute. Practically the difference is that if @is_extension
|
||||
* is TRUE the returned runlist will be terminated with LCN_ENOENT and if
|
||||
* @is_extension is FALSE the runlist will be terminated with
|
||||
* LCN_RL_NOT_MAPPED.
|
||||
*
|
||||
* You need to check the return value with IS_ERR(). If this is false, the
|
||||
* function was successful and the return value is a runlist describing the
|
||||
* 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,
|
||||
*/
|
||||
runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
|
||||
const s64 count, const LCN start_lcn,
|
||||
const NTFS_CLUSTER_ALLOCATION_ZONES zone)
|
||||
const NTFS_CLUSTER_ALLOCATION_ZONES zone,
|
||||
const BOOL is_extension)
|
||||
{
|
||||
LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
|
||||
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,
|
||||
continue;
|
||||
}
|
||||
bit = 1 << (lcn & 7);
|
||||
ntfs_debug("bit %i.", bit);
|
||||
ntfs_debug("bit 0x%x.", bit);
|
||||
/* If the bit is already set, go onto the next one. */
|
||||
if (*byte & bit) {
|
||||
lcn++;
|
||||
@ -729,7 +738,7 @@ out:
|
||||
/* Add runlist terminator element. */
|
||||
if (likely(rl)) {
|
||||
rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
|
||||
rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
|
||||
rl[rlpos].lcn = is_extension ? LCN_ENOENT : LCN_RL_NOT_MAPPED;
|
||||
rl[rlpos].length = 0;
|
||||
}
|
||||
if (likely(page && !IS_ERR(page))) {
|
||||
|
@ -42,7 +42,8 @@ typedef enum {
|
||||
|
||||
extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
|
||||
const VCN start_vcn, const s64 count, const LCN start_lcn,
|
||||
const NTFS_CLUSTER_ALLOCATION_ZONES zone);
|
||||
const NTFS_CLUSTER_ALLOCATION_ZONES zone,
|
||||
const BOOL is_extension);
|
||||
|
||||
extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
|
||||
s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback);
|
||||
|
@ -1355,7 +1355,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
|
||||
up_write(&vol->lcnbmp_lock);
|
||||
ntfs_unmap_page(page);
|
||||
/* Allocate a cluster from the DATA_ZONE. */
|
||||
rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE);
|
||||
rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
|
||||
TRUE);
|
||||
if (IS_ERR(rl2)) {
|
||||
up_write(&mftbmp_ni->runlist.lock);
|
||||
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)
|
||||
nr > min_nr ? "default" : "minimal", (long long)nr);
|
||||
old_last_vcn = rl[1].vcn;
|
||||
do {
|
||||
rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE);
|
||||
rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
|
||||
TRUE);
|
||||
if (likely(!IS_ERR(rl2)))
|
||||
break;
|
||||
if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
|
||||
|
Loading…
Reference in New Issue
Block a user