mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 5.10/5.15 1/1] fuse: don't increment nlink in link()
@ 2025-06-18 11:44 d.privalov
  2025-06-23 10:21 ` Miklos Szeredi
  0 siblings, 1 reply; 2+ messages in thread
From: d.privalov @ 2025-06-18 11:44 UTC (permalink / raw)
  To: stable, Greg Kroah-Hartman
  Cc: Marcel Holtmann, Johan Hedberg, David S. Miller, Jakub Kicinski,
	linux-bluetooth, netdev, linux-kernel, lvc-project,
	Miklos Szeredi, Dmitriy Privalov

From: Miklos Szeredi <mszeredi@redhat.com>

commit 97f044f690bac2b094bfb7fb2d177ef946c85880 upstream.

The fuse_iget() call in create_new_entry() already updated the inode with
all the new attributes and incremented the attribute version.

Incrementing the nlink will result in the wrong count.  This wasn't noticed
because the attributes were invalidated right after this.

Updating ctime is still needed for the writeback case when the ctime is not
refreshed.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Dmitriy Privalov <d.privalov@omp.ru>
---
 fs/fuse/dir.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 4488a53a192d..7055fdc1b8ce 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -807,7 +807,7 @@ void fuse_flush_time_update(struct inode *inode)
 	mapping_set_error(inode->i_mapping, err);
 }
 
-void fuse_update_ctime(struct inode *inode)
+static void fuse_update_ctime_in_cache(struct inode *inode)
 {
 	if (!IS_NOCMTIME(inode)) {
 		inode->i_ctime = current_time(inode);
@@ -816,6 +816,12 @@ void fuse_update_ctime(struct inode *inode)
 	}
 }
 
+void fuse_update_ctime(struct inode *inode)
+{
+	fuse_invalidate_attr(inode);
+	fuse_update_ctime_in_cache(inode);
+}
+
 static int fuse_unlink(struct inode *dir, struct dentry *entry)
 {
 	int err;
@@ -986,25 +992,10 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
 	args.in_args[1].size = newent->d_name.len + 1;
 	args.in_args[1].value = newent->d_name.name;
 	err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
-	/* Contrary to "normal" filesystems it can happen that link
-	   makes two "logical" inodes point to the same "physical"
-	   inode.  We invalidate the attributes of the old one, so it
-	   will reflect changes in the backing inode (link count,
-	   etc.)
-	*/
-	if (!err) {
-		struct fuse_inode *fi = get_fuse_inode(inode);
-
-		spin_lock(&fi->lock);
-		fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
-		if (likely(inode->i_nlink < UINT_MAX))
-			inc_nlink(inode);
-		spin_unlock(&fi->lock);
-		fuse_invalidate_attr(inode);
-		fuse_update_ctime(inode);
-	} else if (err == -EINTR) {
+	if (!err)
+		fuse_update_ctime_in_cache(inode);
+	else if (err == -EINTR)
 		fuse_invalidate_attr(inode);
-	}
 	return err;
 }
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 5.10/5.15 1/1] fuse: don't increment nlink in link()
  2025-06-18 11:44 [PATCH 5.10/5.15 1/1] fuse: don't increment nlink in link() d.privalov
@ 2025-06-23 10:21 ` Miklos Szeredi
  0 siblings, 0 replies; 2+ messages in thread
From: Miklos Szeredi @ 2025-06-23 10:21 UTC (permalink / raw)
  To: d.privalov
  Cc: stable, Greg Kroah-Hartman, Marcel Holtmann, Johan Hedberg,
	David S. Miller, Jakub Kicinski, linux-bluetooth, netdev,
	linux-kernel, lvc-project

On Wed, Jun 18, 2025 at 2:00 PM d.privalov <d.privalov@omp.ru> wrote:
>
> From: Miklos Szeredi <mszeredi@redhat.com>
>
> commit 97f044f690bac2b094bfb7fb2d177ef946c85880 upstream.
>
> The fuse_iget() call in create_new_entry() already updated the inode with
> all the new attributes and incremented the attribute version.
>
> Incrementing the nlink will result in the wrong count.  This wasn't noticed
> because the attributes were invalidated right after this.
>
> Updating ctime is still needed for the writeback case when the ctime is not
> refreshed.
>
> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> Signed-off-by: Dmitriy Privalov <d.privalov@omp.ru>
> ---
>  fs/fuse/dir.c | 29 ++++++++++-------------------
>  1 file changed, 10 insertions(+), 19 deletions(-)
>
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index 4488a53a192d..7055fdc1b8ce 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -807,7 +807,7 @@ void fuse_flush_time_update(struct inode *inode)
>         mapping_set_error(inode->i_mapping, err);
>  }
>
> -void fuse_update_ctime(struct inode *inode)
> +static void fuse_update_ctime_in_cache(struct inode *inode)
>  {

Backport is wrong.  In the original patch we have

-       fuse_invalidate_attr(inode);

And that line comes from 371e8fd02969 ("fuse: move
fuse_invalidate_attr() into fuse_update_ctime()") in v5.16.

The fix is to not introduce fuse_update_ctime_in_cache(), because
fuse_update_ctime() is already doing that.

Thanks,
Miklos


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-06-23 10:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-18 11:44 [PATCH 5.10/5.15 1/1] fuse: don't increment nlink in link() d.privalov
2025-06-23 10:21 ` Miklos Szeredi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®