From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 862FB3E95B3 for ; Fri, 12 Jun 2026 11:50:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781265023; cv=none; b=OPbpINvR7Gnvl9M1Q/tyQvBpeVbeJH0AVvSSosFPl50pGvLl1vVu7rQAy0V13gVdM0kCzmyCtlTyG0vfuvdSNTSYnVgeoAdipaRRaANVgGfDK1kXN9s8xQ9grl4gJCN5bZK7NJqc0Ts8EMhUlIrncKkY48FsEBDxYfGa7enMXng= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781265023; c=relaxed/simple; bh=nsdGdRnewbkphCvqP+UZ2H9JLYrAPvPh7iBMkhu9FiI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BFA2Z4tMdonXQGVCNA2Jn+cbWOecxLTZUWvDueEdOFff01EwGbeJhxHezFpVfaVKnCJYS9kKDjjdUoiUVBXsIe76lZd80hDAyRezFGTIjQYM2IQbKT0ITcr31R9vNe0S6ZsiKaHe2/fs6OF5UMK0ZPh95irgjHgYEFG3/BjVyDk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jL7oTEH0; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jL7oTEH0" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-2bf1cda2b17so7032765ad.1 for ; Fri, 12 Jun 2026 04:50:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781265022; x=1781869822; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fQOC3hYWZyES9WLzkPg8MyHU7k3IwFGtS7FQklxrDKo=; b=jL7oTEH0tAM+7GR/fnBFAAaMhXxpOQSihQH306qeG8rsr1DvPY4w73WN/fe8E929Qn VrfGXnkYBgKMGx3KzuATpBj3qw0kH6WiOdfGPlYrMdifccKDK3R0DBJ9jBXonqANf7kT 3BE3WOZndDYwTOjjjzmTyhwsTTOpM60NRGT/Y0b6ByXQFO58yBTydkKL4w6pnopvev4r sN5eWAEIr2oVTFuD1b1eNSwGs6ZcImcldVZJj3gUCElDJdScRSfI+A64jEgs9O8NduGc VOhZ+O/r5cX1A/Hl+98QMHszQzFf4cPw6nKBRk0vmtH1cKL9sTe3+58Od9l2JVmL/AvF N7hg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781265022; x=1781869822; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=fQOC3hYWZyES9WLzkPg8MyHU7k3IwFGtS7FQklxrDKo=; b=FKhBEUa+VWAYQr8CDWMAoLp6fY2kXEndWUd79+B0koSPlE95Ahkl7TakOND5Ralg2l mOMq1QtXMISFnPa6klgp3WVh92jU3zSy/n3y7ydUUzgPA2+UkqMISphocDSbCu5ynAjJ zEMbJWsKZAmB5pkMp/BcVnoZ6QIjkcLi4QF9IjF62PSkBJKKyN+QzOfVayNvtuHVgdfo Qhm+i/E/5t1cmG8Uq+OcmP3G0jsrJP8OC0S1CPuxm/nqM2f5/IkhZVp23sLji8sj0RBW ZTa7a3bzGJLw7q/2F7HMVDC853WluKQKA6UKGgPEAp90S069C5lrGgHWwS5p7YsQdhU6 K0nw== X-Forwarded-Encrypted: i=1; AFNElJ8HwXidLVfnrmE+U5rbmQCTXtYetDAKqi9o1T8vDG/FXRFrSeuxRRmJEJqNkLaXd+rwKn7pM8wJrFtdzwM=@vger.kernel.org X-Gm-Message-State: AOJu0YyF3nI5TzlId3KsE4PanpLLlZZIZQB6uSoAt77H8di4qsh2iI0H YlDAiYE1eyeFvUoxBdLj1MQjbI6jZCw0L67NoNOxd2UHs9n6EN0na/vY X-Gm-Gg: Acq92OHK3xWKCo3UyguEhrxRt6rNjZRm9UWbTv3ix5dnJMY2I8Sa1ErwFguEpLHCyMV c+4aVdsgFpJ1V5erh4y6M0IbPZjTwOLl7wdvhxlfSqqkULGAxN7GJ/BErXRPOu8/Jgn6curKbZk QmtSDW2hwG/Eymf9RjggJ9BLkOBbGxG2haU4bjI3SelwiMYTAWkyxj9eoU0CKSRldS67yKrAjht x42pjijjS09okIL97wcuhfepgyLs5OY+9BuoJHWCArIXwIun5kRpOXP08jOPWpo7S1VkAbVVgnf 3sSc6aEUUtd1exAA8H7CS8UTmAHGIiZ530AJIrICjvp/K2znUW8X5y8DTLz3KwGj0gtcZCZzOec kGxKQlkrH3oPySL7H6gOnEXN8zEZGCjIi0UZca2umTsw01Yb8agSL/BzYTJEdRRojcH0Gapi9ph uzHX/6jXh7aR7VvDB3u0Xb2puEx8xrxDL8Y22VHbrVsB7XN8LmBGtXqq4fAcjQNv1Odi3ey0Emm 7GOW5+45Rdk+9ptHT3m/yBtaeVJj3bO3XyLWeJj7TKJYj2ph42nV1q5QCvzuE9tSDw+uue3q3d5 voPWw4XlVa6cGs4oFHh+VtCNt+RM4RWpucln X-Received: by 2002:a17:903:2ec6:b0:2c1:41f8:7ef5 with SMTP id d9443c01a7336-2c3fd1304f7mr28480935ad.22.1781265021627; Fri, 12 Jun 2026 04:50:21 -0700 (PDT) Received: from cs-1047136853211-default.asia-southeast1-a.c.d33bddc1d573818c7-tp.internal (139.104.87.34.bc.googleusercontent.com. [34.87.104.139]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2c43307a259sm19993085ad.68.2026.06.12.04.50.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jun 2026 04:50:21 -0700 (PDT) From: Aditya Srivastava To: Carlos Maiolino Cc: Christoph Hellwig , linux-xfs@vger.kernel.org, linux-kernel@vger.kernel.org, Aditya Prakash Srivastava Subject: [PATCH v2 2/2] xfs: prevent close() from hanging on frozen filesystems Date: Fri, 12 Jun 2026 11:49:17 +0000 Message-ID: <20260612114917.2192-3-aditya.ansh182@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260612114917.2192-1-aditya.ansh182@gmail.com> References: <20260612114917.2192-1-aditya.ansh182@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Aditya Prakash Srivastava When a file with active speculative post-EOF preallocations is closed, xfs_file_release() synchronously triggers xfs_free_eofblocks() to clean them up. This requires allocating a write transaction (xfs_trans_alloc), which blocks indefinitely if the filesystem is currently frozen or in the process of freezing, as it waits to acquire the superblock's write lock. As a result, a close() system call on a read-write file descriptor can hang indefinitely in percpu_rwsem_wait() until the filesystem is thawed, even if the file is closed by a non-writer process or after all writing activity has already ceased. To fix this properly and avoid any potential race conditions where a freeze might come in immediately after a writable check, pass the new XFS_TRANS_WRITECOUNT_TRYLOCK flag to xfs_trans_alloc() when freeing speculative preallocations in xfs_file_release(). If xfs_free_eofblocks() returns -EAGAIN on a trylock failure, we cleanly bypass setting XFS_EOFBLOCKS_RELEASED on the inode, ensuring subsequent releases or the background blockgc garbage collector can successfully retry the cleanup once the filesystem thaws. Also, rename the flags parameter in xfs_free_eofblocks() to trans_flags as suggested to make its usage stand out, and update existing callers to pass 0 to preserve standard blocking paths. Suggested-by: Christoph Hellwig Signed-off-by: Aditya Prakash Srivastava --- fs/xfs/xfs_bmap_util.c | 9 +++++---- fs/xfs/xfs_bmap_util.h | 2 +- fs/xfs/xfs_file.c | 8 +++++--- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_inode.c | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 0ab00615f1ad..faf0630717dc 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -574,7 +574,8 @@ xfs_can_free_eofblocks( */ int xfs_free_eofblocks( - struct xfs_inode *ip) + struct xfs_inode *ip, + uint trans_flags) { struct xfs_trans *tp; struct xfs_mount *mp = ip->i_mount; @@ -604,9 +605,9 @@ xfs_free_eofblocks( return 0; } - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, trans_flags, &tp); if (error) { - ASSERT(xfs_is_shutdown(mp)); + ASSERT(error == -EAGAIN || xfs_is_shutdown(mp)); return error; } @@ -928,7 +929,7 @@ xfs_prepare_shift( * into the accessible region of the file. */ if (xfs_can_free_eofblocks(ip)) { - error = xfs_free_eofblocks(ip); + error = xfs_free_eofblocks(ip, 0); if (error) return error; } diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index c477b3361630..c13774aa0892 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h @@ -66,7 +66,7 @@ int xfs_insert_file_space(struct xfs_inode *, xfs_off_t offset, /* EOF block manipulation functions */ bool xfs_can_free_eofblocks(struct xfs_inode *ip); -int xfs_free_eofblocks(struct xfs_inode *ip); +int xfs_free_eofblocks(struct xfs_inode *ip, uint trans_flags); int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, struct xfs_swapext *sx); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 845a97c9b063..76c9b2fe7c51 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1806,9 +1806,11 @@ xfs_file_release( */ if (!xfs_iflags_test(ip, XFS_EOFBLOCKS_RELEASED) && xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { - if (xfs_can_free_eofblocks(ip) && - !xfs_iflags_test_and_set(ip, XFS_EOFBLOCKS_RELEASED)) - xfs_free_eofblocks(ip); + if (!xfs_iflags_test(ip, XFS_EOFBLOCKS_RELEASED) && + xfs_can_free_eofblocks(ip) && + !xfs_free_eofblocks(ip, XFS_TRANS_WRITECOUNT_TRYLOCK)) + xfs_iflags_set(ip, XFS_EOFBLOCKS_RELEASED); + xfs_iunlock(ip, XFS_IOLOCK_EXCL); } diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 2040a9292ee6..c575b4acb24c 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1259,7 +1259,7 @@ xfs_inode_free_eofblocks( *lockflags |= XFS_IOLOCK_EXCL; if (xfs_can_free_eofblocks(ip)) - return xfs_free_eofblocks(ip); + return xfs_free_eofblocks(ip, 0); /* inode could be preallocated */ trace_xfs_inode_free_eofblocks_invalid(ip); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 9978ac1422fc..1c75f51af4d7 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1423,7 +1423,7 @@ xfs_inactive( * reference to the inode at this point anyways. */ if (xfs_can_free_eofblocks(ip)) - error = xfs_free_eofblocks(ip); + error = xfs_free_eofblocks(ip, 0); goto out; } -- 2.47.3