All of lore.kernel.org
 help / color / mirror / Atom feed
From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
To: Hui Peng <benquike@gmail.com>
Cc: Jan Kara <jack@suse.cz>,
	 linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] fat: avoid freeing clusters on failed directory validation or read-only mounts
Date: Wed, 23 Sep 2026 02:56:48 +0900	[thread overview]
Message-ID: <877bkdcgpr.fsf@mail.parknet.co.jp> (raw)
In-Reply-To: <20260919204810.2813594-1-benquike@gmail.com>

Hui Peng <benquike@gmail.com> writes:

> In fat_fill_inode(), set_nlink(inode, fat_subdirs(inode)) is called
> before fat_validate_dir(inode). If a directory has zero valid
> subdirectories (so fat_subdirs(inode) returns 0) and fat_validate_dir()
> subsequently returns -EIO (due to a missing or malformed '.'/'..'
> entry), fat_build_inode() calls iput(inode) with inode->i_nlink == 0 and
> inode->i_start still populated.
>
> fat_evict_inode() then checks !inode->i_nlink without checking
> is_bad_inode(inode) or sb_rdonly(inode->i_sb) and calls
> fat_truncate_blocks(inode, 0), freeing the cluster chain on disk even on
> a read-only (MS_RDONLY) mount.
>
> Validate the directory before setting i_nlink in fat_fill_inode(), mark
> the inode bad on error in fat_build_inode(), and guard cluster
> truncation and metadata writeback in fat_evict_inode() with
> !is_bad_inode(inode) && !sb_rdonly(inode->i_sb).
>
> Fixes: a3082d526f2d ("fat: add simple validation for directory inode")
> Assisted-by: LLM
> Signed-off-by: Hui Peng <benquike@gmail.com>
> ---
>
> diff --git a/fs/fat/inode.c b/fs/fat/inode.c
> --- a/fs/fat/inode.c
> +++ b/fs/fat/inode.c
> @@ -535,11 +535,11 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
>  			return error;
>  		MSDOS_I(inode)->mmu_private = inode->i_size;
>  
> -		set_nlink(inode, fat_subdirs(inode));
> -
>  		error = fat_validate_dir(inode);

Without set_nlink(), fat_validate_dir() will always return the error,
isn't it? If so, this patch is not tested?

>  		if (error < 0)
>  			return error;
> +
> +		set_nlink(inode, fat_subdirs(inode));
>  	} else { /* not a directory */
>  		inode->i_generation |= 1;
>  		inode->i_mode = fat_make_mode(sbi, de->attr,
> @@ -610,6 +610,7 @@ struct inode *fat_build_inode(struct super_block *sb,
>  	inode_set_iversion(inode, 1);
>  	err = fat_fill_inode(inode, de);
>  	if (err) {
> +		make_bad_inode(inode);
>  		iput(inode);
>  		inode = ERR_PTR(err);
>  		goto out;
> @@ -688,12 +689,14 @@ static void fat_free_eofblocks(struct inode *inode)
>  static void fat_evict_inode(struct inode *inode)
>  {
>  	truncate_inode_pages_final(&inode->i_data);
> -	if (!inode->i_nlink) {
> -		inode->i_size = 0;
> -		fat_truncate_blocks(inode, 0);
> -	} else {
> -		mmb_sync(&MSDOS_I(inode)->i_metadata_bhs);
> -		fat_free_eofblocks(inode);
> +	if (!is_bad_inode(inode) && !sb_rdonly(inode->i_sb)) {
> +		if (!inode->i_nlink) {
> +			inode->i_size = 0;
> +			fat_truncate_blocks(inode, 0);
> +		} else {
> +			mmb_sync(&MSDOS_I(inode)->i_metadata_bhs);
> +			fat_free_eofblocks(inode);
> +		}
>  	}
>  
>  	mmb_invalidate(&MSDOS_I(inode)->i_metadata_bhs);

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

      reply	other threads:[~2026-09-22 18:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-19 20:48 [PATCH] fat: avoid freeing clusters on failed directory validation or read-only mounts Hui Peng
2026-09-22 17:56 ` OGAWA Hirofumi [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=877bkdcgpr.fsf@mail.parknet.co.jp \
    --to=hirofumi@mail.parknet.co.jp \
    --cc=benquike@gmail.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.