Skip to content

Commit

Permalink
fuse: don't increment nlink in link()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Miklos Szeredi committed Oct 28, 2021
1 parent cefd1b8 commit 97f044f
Showing 1 changed file with 11 additions and 19 deletions.
30 changes: 11 additions & 19 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,16 +745,21 @@ 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)
{
fuse_invalidate_attr(inode);
if (!IS_NOCMTIME(inode)) {
inode->i_ctime = current_time(inode);
mark_inode_dirty_sync(inode);
fuse_flush_time_update(inode);
}
}

void fuse_update_ctime(struct inode *inode)
{
fuse_invalidate_attr(inode);
fuse_update_ctime_in_cache(inode);
}

static void fuse_entry_unlinked(struct dentry *entry)
{
struct inode *inode = d_inode(entry);
Expand Down Expand Up @@ -925,24 +930,11 @@ 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_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;
}

Expand Down

0 comments on commit 97f044f

Please sign in to comment.