get_nr_free_clusters() is run from the precalc_free_clusters() worker queued at the end of ntfs_fill_super(). It is also the only place that publishes the result by atomic64_set(&vol->free_clusters, ...), sets NVolSetFreeClusterKnown(), and wakes vol->free_waitq. The function currently allocates a temporary file_ra_state with kzalloc() before that publication happens. If the allocation fails, get_nr_free_clusters() returns 0 without setting NVolFreeClusterKnown() or waking vol->free_waitq, so callers that wait for the free count can block forever. The readahead state is only used synchronously while scanning the bitmap and struct file_ra_state is small. Keep it on the stack and pass it to the readahead helper by address, eliminating the early allocation failure path. Zero-initialize the on-stack state because file_ra_state_init() only sets ra_pages and prev_pos. Signed-off-by: DaeMyung Kang --- fs/ntfs/super.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 7e3561265b47..14fd244f29fe 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -1954,7 +1954,7 @@ s64 get_nr_free_clusters(struct ntfs_volume *vol) struct address_space *mapping = vol->lcnbmp_ino->i_mapping; struct folio *folio; pgoff_t index, max_index; - struct file_ra_state *ra; + struct file_ra_state ra = {}; ntfs_debug("Entering."); /* Serialize accesses to the cluster bitmap. */ @@ -1962,11 +1962,7 @@ s64 get_nr_free_clusters(struct ntfs_volume *vol) if (NVolFreeClusterKnown(vol)) return atomic64_read(&vol->free_clusters); - ra = kzalloc(sizeof(*ra), GFP_NOFS); - if (!ra) - return 0; - - file_ra_state_init(ra, mapping); + file_ra_state_init(&ra, mapping); /* * Convert the number of bits into bytes rounded up, then convert into @@ -1985,7 +1981,7 @@ s64 get_nr_free_clusters(struct ntfs_volume *vol) * Get folio from page cache, getting it from backing store * if necessary, and increment the use count. */ - folio = ntfs_get_locked_folio(mapping, index, max_index, ra); + folio = ntfs_get_locked_folio(mapping, index, max_index, &ra); /* Ignore pages which errored synchronously. */ if (IS_ERR(folio)) { @@ -2024,7 +2020,6 @@ s64 get_nr_free_clusters(struct ntfs_volume *vol) else atomic64_set(&vol->free_clusters, nr_free); - kfree(ra); NVolSetFreeClusterKnown(vol); wake_up_all(&vol->free_waitq); ntfs_debug("Exiting."); -- 2.43.0