diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 0d6cd08ee2e7..c58e689fb585 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c @@ -506,13 +506,32 @@ struct runlist_element *ntfs_cluster_alloc(struct ntfs_volume *vol, const s64 st } if (!used_zone_pos) { + /* + * The run at @start_lcn reached the end of the buffer + * or the zone. A contiguous request gets that run + * alone, not a second one from the zone position. + */ + if (is_contig && rlpos) + goto out; + /* + * Leaving @start_lcn for the zone position starts the + * zone over as if no hint had been given, even if the + * search had already reached pass 2, whose range ends + * at @start_lcn. + */ used_zone_pos = 1; - if (search_zone == 1) + has_guess = 0; + pass = 1; + if (search_zone == 1) { zone_start = vol->mft_zone_pos; - else if (search_zone == 2) + zone_end = vol->mft_zone_end; + } else if (search_zone == 2) { zone_start = vol->data1_zone_pos; - else + zone_end = vol->nr_clusters; + } else { zone_start = vol->data2_zone_pos; + zone_end = vol->mft_zone_start; + } if (!zone_start || zone_start == vol->mft_zone_start || zone_start == vol->mft_zone_end)