From f85ce6ff2e34464ceb68ea2d9766750b61512bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Mon, 19 Jul 2021 09:23:23 +0200 Subject: [PATCH] Skipped errors for bad free clusters before they are computed The count of free clusters may be updated while mounting before it has been initialized, which may lead to irrelevant error messages. Moreover the count is not computed at all in some ntfsprogs utilities. So set up a flags to avoid outputting irrelevant errors. --- include/ntfs-3g/volume.h | 5 +++++ libntfs-3g/lcnalloc.c | 15 +++++++++------ libntfs-3g/volume.c | 4 +++- src/lowntfs-3g.c | 3 +-- src/ntfs-3g.c | 3 +-- 5 files changed, 19 insertions(+), 11 deletions(-) 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; }