From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) (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 5A29F43A809 for ; Mon, 24 Aug 2026 14:42:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787582530; cv=none; b=Pyqb/SbITBKUCusyyVL5dFltLIJqS5eamrlZVMKYkx2OfEhSDN3M1+Hs8yGutNhSbVWQd7PYka5Fw4s9OrbeaeW+TiHGZ9zob6QHlUUHB+nG8dvOuJFzaEraHrDXbIeAG+FCHaZ5ply4Eunh++O7Z1TeeC/s4PhDcV4tcn4hvJA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787582530; c=relaxed/simple; bh=5pUkOkLccK36XELXD3ceBO77sDrh/+6Ylu/iCl1SdJI=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=VOVof1eIf8766u0LkFaCo/SJpa5bEBth6gwO1AhHQk7Ze4YbWdFAgWZVghooKkutXOtKkDZ4Jz16pqLDoNT1HCkaZ+MrdgXptSJq4imo6qjOfuw7czDBk+UspN0IjLz0F4jsP1Kfv3lXayi1ANyGOUsCi2sfaUso63UODXqcFfw= 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=kRfUjzff; arc=none smtp.client-ip=209.85.216.50 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="kRfUjzff" Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-38dc69c74b8so3900045a91.0 for ; Mon, 24 Aug 2026 07:42:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787582528; x=1788187328; darn=vger.kernel.org; h=in-reply-to:content-disposition:content-type:mime-version :references:subject:cc:to:from:date:message-id:from:to:cc:subject :date:message-id:reply-to:content-type; bh=DrGOfNzbzyg2Ng3Zf5oeNisggqc5WFaWkkGNciHOYrk=; b=kRfUjzfffNcs+jECHF9oSvlYyakQtcF85IMl3ElyipiOmODvF5wqurMi8vjRslhjFd +U+EcMByYuZ1XNYkH2LR91O+GJE63dP7INC0jekzclrYlXwMwcWSx/ZcfHi3bwxcs4p1 +AFwcd+v/vgOLPRwzDQmBZSl7Z1CXn9F3rKyzAO5WBQ1Sz9FeIAH88vkp0BnAAXxwyVV q9DTzkjUwXm814grdsIDl/dPVknZxA3SG6aU0EtvMChtO1Z4+6LercxGhD1hoGHAgVot tBH9juIWWYqcEti6q45Li3kySGolcTcNtyjGKVMAAyqJ9HG6FPJS/pMD10Vjcl1rjjlx hWJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787582528; x=1788187328; h=in-reply-to:content-disposition:content-type:mime-version :references:subject:cc:to:from:date:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=DrGOfNzbzyg2Ng3Zf5oeNisggqc5WFaWkkGNciHOYrk=; b=F+f/dQ+xsRn1tjFwyhlgHrdXATX/v8KcGYyqyXowOBr3MWT1s4u9J9F/r9/dw34h/T 60ycLV4VTKW7sOqQ8ex7P5/xbP2aENz+8JZo+rG9sY1KjB+y6wfXpcI8HJTTXlYb9EF4 pKwDhm5COPLxZGVzdUewS6deAhhuZmSEd1uyA/u4vnTwXOI0Vjpo3w48xgOBJn/TEoKR IjoIyB3M58lvO8+Fi8/M5XXsrrpRJsiNjRc/MnuQH74d1S8eoEEZsW2HeG+Uu+WvpjUY ZgOSx7tS7o4V8dx3+3A8jiRo5oSfkfKf8gsa3ObmvPiz4j5ZGyHIxVZAzF53W0CQbvb7 zmYQ== X-Forwarded-Encrypted: i=1; AHgh+RpBjQh07qJfUcTmTk7RwHpx3IvicqjRZLCSpIevbs5PA9qZo+9f/gFxRfkBXJFiCjKz+O/CsHQZDo0He1o=@vger.kernel.org X-Gm-Message-State: AFuF++kt6QxrsBBS2eVoWIxBZAJxpz1wviKQZbckObvrN2U1xMQEh+fF gO+teFhO19f8C3eA20TnagflQFzrYDGtrQAcH3P0JEdEfSRCc14LVShn X-Gm-Gg: AR+sD13SBtUdcNvu44VBN0xSKSHhkYU96K6Fd2wSWFFeKNKoDdZPwEwfvCl4E8XttGk UpeQU6hVFBrragiIvNLsTHbIck8QXRaIZWXRZdgz3GoFhQi7ItV8puZK/zc5+qYSKDJmKbW2yTd zk97tG5TlPcXH9ARCMiHsUayf1nb8lqzJKFpyQNaAZrKrLdD5WemsZgdGdF362lMMTCvTpZdjou kp0VCjFiwUnV4Kbpq0/h7d5Ik30BOjxRoYQdMscI8FNI20Xx6WG6uHblqiNVgvVu6ay8jz595Mt 8GuZfce2c8xUs4RIKbcrP/s8oZKNceSerVEOeDXdnMz3N9Zj0Fy9vS3LCAK4wKfCKefR5/g37yn ueY95Tq5vbultJpdqYXbrOm2qtXOAuBj+fjhIw1k70/n01Rq8THm+36q2jJ3Vnbl84Prcyy6SEZ HLULtefY5pJu+dZwRAow5urd4JTxVlRd+FLc4d3mIkt461YBeKGBOPAD9GjWgOm2aFE1S6AkeXz tH+TuwrFbHt8x9k5g/oRhTRBUnhGzCQNmQP73D4OxUZmKvYbNyhzROG X-Received: by 2002:a17:90b:28c5:b0:38e:75f3:ad4d with SMTP id 98e67ed59e1d1-395df11a0damr36710107a91.7.1787582528197; Mon, 24 Aug 2026 07:42:08 -0700 (PDT) Received: from localhost (75-172-73-38.tukw.qwest.net. [75.172.73.38]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-327f91d36f9sm39999434eec.16.2026.08.24.07.42.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2026 07:42:07 -0700 (PDT) Message-ID: <6a8c583f.a4ccd6f3.2488d7.bd37@mx.google.com> X-Google-Original-Message-ID: Date: Mon, 24 Aug 2026 07:42:00 -0700 From: Dennis Tighe To: Hyunchul Lee , Namjae Jeon Cc: ntfs@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2] ntfs: mount read-only when mft records are smaller than the device block References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: An mft record is written with a single bio of exactly mft_record_size bytes. bio_unaligned() rejects a bio whose size is not a multiple of the device's logical block size, so on a volume whose mft records are smaller than that block no mft record can be written at all. On 512n and 512e drives this is a non-issue, since both report a 512-byte logical block and a 1k record is a clean multiple of it. On 4Kn drives the mft record (1k) is smaller than the 4k logical block, so every mft write fails. At the same time, other writes (like directory index entries) that are 4k will succeed leading references to unwritten mft records and a corruption situation. Reads are unaffected, so mount read-only rather than refusing outright, and refuse a later remount read-write for the same reason. This is a stopgap. Writing these volumes needs read-modify-write at the device's block size, which this does not implement. Assisted-by: Claude:claude-opus-5 Signed-off-by: Dennis Tighe --- Changes in v2: * Add the same check to ntfs_reconfigure(), so a later "mount -o remount,rw" is refused rather than silently re-enabling the writes. Thanks to Hyunchul Lee for catching this. fs/ntfs/super.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 30481e5d5dd4..5de07fab101c 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -304,6 +304,12 @@ static int ntfs_reconfigure(struct fs_context *fc) le16_to_cpu(vol->vol_flags), es); return -EROFS; } + if (vol->mft_record_size < bdev_logical_block_size(sb->s_bdev)) { + ntfs_error(sb, "mft record size (%i) is below the device block size (%u)%s", + vol->mft_record_size, + bdev_logical_block_size(sb->s_bdev), es); + return -EROFS; + } if (vol->logfile_ino && !ntfs_empty_logfile(vol->logfile_ino)) { ntfs_error(sb, "Failed to empty journal LogFile%s", es); @@ -2298,6 +2304,22 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) ntfs_debug("Changed device block size to %i bytes (block size bits %i) to match volume sector size.", blocksize, sb->s_blocksize_bits); } + + /* + * If the device's logical block size is larger than the mft record (1k) + * writes to it will currently fail. Reads are unaffected, so we can still + * mount the volume as read-only. + */ + if (vol->mft_record_size < bdev_logical_block_size(sb->s_bdev)) { + if (!sb_rdonly(sb)) { + ntfs_error(sb, + "mft record size (%i) is smaller than the device logical block size (%u). Mft records cannot be written. Mounting read-only.", + vol->mft_record_size, + bdev_logical_block_size(sb->s_bdev)); + sb->s_flags |= SB_RDONLY; + } + } + /* Initialize the cluster and mft allocators. */ ntfs_setup_allocators(vol); /* Setup remaining fields in the super block. */ -- 2.43.0