mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
fuse: don't increment nlink in link()
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>
This commit is contained in:
parent
cefd1b8327
commit
97f044f690
@ -745,9 +745,8 @@ void fuse_flush_time_update(struct inode *inode)
|
|||||||
mapping_set_error(inode->i_mapping, err);
|
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)) {
|
if (!IS_NOCMTIME(inode)) {
|
||||||
inode->i_ctime = current_time(inode);
|
inode->i_ctime = current_time(inode);
|
||||||
mark_inode_dirty_sync(inode);
|
mark_inode_dirty_sync(inode);
|
||||||
@ -755,6 +754,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 void fuse_entry_unlinked(struct dentry *entry)
|
static void fuse_entry_unlinked(struct dentry *entry)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(entry);
|
struct inode *inode = d_inode(entry);
|
||||||
@ -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].size = newent->d_name.len + 1;
|
||||||
args.in_args[1].value = newent->d_name.name;
|
args.in_args[1].value = newent->d_name.name;
|
||||||
err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
|
err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
|
||||||
/* Contrary to "normal" filesystems it can happen that link
|
if (!err)
|
||||||
makes two "logical" inodes point to the same "physical"
|
fuse_update_ctime_in_cache(inode);
|
||||||
inode. We invalidate the attributes of the old one, so it
|
else if (err == -EINTR)
|
||||||
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) {
|
|
||||||
fuse_invalidate_attr(inode);
|
fuse_invalidate_attr(inode);
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user