diff --git a/include/ntfs-3g/volume.h b/include/ntfs-3g/volume.h index 30e07906..42800a28 100644 --- a/include/ntfs-3g/volume.h +++ b/include/ntfs-3g/volume.h @@ -117,6 +117,7 @@ typedef enum { NV_HideDotFiles, /* 1: Set hidden flag on dot files */ NV_Compression, /* 1: allow compression */ NV_NoFixupWarn, /* 1: Do not log fixup errors */ + NV_FreeSpaceKnown, /* 1: The free space is now known */ } ntfs_volume_state_bits; #define test_nvol_flag(nv, flag) test_bit(NV_##flag, (nv)->state) @@ -155,6 +156,10 @@ typedef enum { #define NVolSetNoFixupWarn(nv) set_nvol_flag(nv, NoFixupWarn) #define NVolClearNoFixupWarn(nv) clear_nvol_flag(nv, NoFixupWarn) +#define NVolFreeSpaceKnown(nv) test_nvol_flag(nv, FreeSpaceKnown) +#define NVolSetFreeSpaceKnown(nv) set_nvol_flag(nv, FreeSpaceKnown) +#define NVolClearFreeSpaceKnown(nv) clear_nvol_flag(nv, FreeSpaceKnown) + /* * NTFS version 1.1 and 1.2 are used by Windows NT4. * NTFS version 2.x is used by Windows 2000 Beta diff --git a/libntfs-3g/lcnalloc.c b/libntfs-3g/lcnalloc.c index 486e3510..a1c1ee33 100644 --- a/libntfs-3g/lcnalloc.c +++ b/libntfs-3g/lcnalloc.c @@ -368,12 +368,14 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, /* Allocate the bitmap bit. */ *byte |= bit; writeback = 1; - if (vol->free_clusters <= 0) - ntfs_log_error("Non-positive free clusters " - "(%lld)!\n", + if (NVolFreeSpaceKnown(vol)) { + if (vol->free_clusters <= 0) + ntfs_log_error("Non-positive free" + " clusters (%lld)!\n", (long long)vol->free_clusters); - else - vol->free_clusters--; + else + vol->free_clusters--; + } /* * Coalesce with previous run if adjacent LCNs. @@ -602,7 +604,8 @@ int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl) ret = 0; out: vol->free_clusters += nr_freed; - if (vol->free_clusters > vol->nr_clusters) + if (NVolFreeSpaceKnown(vol) + && (vol->free_clusters > vol->nr_clusters)) ntfs_log_error("Too many free clusters (%lld > %lld)!", (long long)vol->free_clusters, (long long)vol->nr_clusters); diff --git a/libntfs-3g/volume.c b/libntfs-3g/volume.c index d1a5f2f0..2cc827bd 100644 --- a/libntfs-3g/volume.c +++ b/libntfs-3g/volume.c @@ -1894,8 +1894,10 @@ int ntfs_volume_get_free_space(ntfs_volume *vol) if (vol->free_mft_records < 0) ntfs_log_perror("Failed to calculate free MFT records"); - else + else { + NVolSetFreeSpaceKnown(vol); ret = 0; + } } return (ret); } diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index cfa61626..f28d7e0e 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -4347,8 +4347,7 @@ static int ntfs_open(const char *device) if (ctx->ignore_case && ntfs_set_ignore_case(vol)) goto err_out; - vol->free_clusters = ntfs_attr_get_free_bits(vol->lcnbmp_na); - if (vol->free_clusters < 0) { + if (ntfs_volume_get_free_space(ctx->vol)) { ntfs_log_perror("Failed to read NTFS $Bitmap"); goto err_out; } diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 1f148ba0..5c07f23f 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -4056,8 +4056,7 @@ static int ntfs_open(const char *device) !ctx->hide_hid_files, ctx->hide_dot_files)) goto err_out; - ctx->vol->free_clusters = ntfs_attr_get_free_bits(ctx->vol->lcnbmp_na); - if (ctx->vol->free_clusters < 0) { + if (ntfs_volume_get_free_space(ctx->vol)) { ntfs_log_perror("Failed to read NTFS $Bitmap"); goto err_out; }