Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc0fa7dc authored by Anton Altaparmakov's avatar Anton Altaparmakov
Browse files

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: default avatarAnton Altaparmakov <aia21@cantab.net>
parent 511bea5e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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.

+1 −9
Original line number Diff line number Diff line
@@ -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;
+12 −3
Original line number Diff line number Diff line
@@ -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 @@ switch_to_data1_zone: search_zone = 2;
	/* 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))) {
+2 −1
Original line number Diff line number Diff line
@@ -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);
+4 −2
Original line number Diff line number Diff line
@@ -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) {