Skip to content

Commit

Permalink
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/viro/vfs

Pull vfs fixes from Al Viro:
 "Assorted fixes all over the place"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  aio: fix io_destroy(2) vs. lookup_ioctx() race
  ext2: fix a block leak
  nfsd: vfs_mkdir() might succeed leaving dentry negative unhashed
  cachefiles: vfs_mkdir() might succeed leaving dentry negative unhashed
  unfuck sysfs_mount()
  kernfs: deal with kernfs_fill_super() failures
  cramfs: Fix IS_ENABLED typo
  befs_lookup(): use d_splice_alias()
  affs_lookup: switch to d_splice_alias()
  affs_lookup(): close a race with affs_remove_link()
  fix breakage caused by d_find_alias() semantics change
  fs: don't scan the inode cache before SB_BORN is set
  do d_instantiate/unlock_new_inode combinations safely
  iov_iter: fix memory leak in pipe_get_pages_alloc()
  iov_iter: fix return type of __pipe_get_pages()
  • Loading branch information
torvalds committed May 21, 2018
2 parents 3b78ce4 + baf1056 commit 5997aab
Show file tree
Hide file tree
Showing 26 changed files with 152 additions and 118 deletions.
15 changes: 9 additions & 6 deletions fs/affs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,16 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
struct super_block *sb = dir->i_sb;
struct buffer_head *bh;
struct inode *inode = NULL;
struct dentry *res;

pr_debug("%s(\"%pd\")\n", __func__, dentry);

affs_lock_dir(dir);
bh = affs_find_entry(dir, dentry);
affs_unlock_dir(dir);
if (IS_ERR(bh))
if (IS_ERR(bh)) {
affs_unlock_dir(dir);
return ERR_CAST(bh);
}
if (bh) {
u32 ino = bh->b_blocknr;

Expand All @@ -222,11 +224,12 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
}
affs_brelse(bh);
inode = affs_iget(sb, ino);
if (IS_ERR(inode))
return ERR_CAST(inode);
}
d_add(dentry, inode);
return NULL;
res = d_splice_alias(inode, dentry);
if (!IS_ERR_OR_NULL(res))
res->d_fsdata = dentry->d_fsdata;
affs_unlock_dir(dir);
return res;
}

int
Expand Down
4 changes: 2 additions & 2 deletions fs/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,8 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id)

ctx = rcu_dereference(table->table[id]);
if (ctx && ctx->user_id == ctx_id) {
percpu_ref_get(&ctx->users);
ret = ctx;
if (percpu_ref_tryget_live(&ctx->users))
ret = ctx;
}
out:
rcu_read_unlock();
Expand Down
17 changes: 5 additions & 12 deletions fs/befs/linuxvfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,23 +198,16 @@ befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)

if (ret == BEFS_BT_NOT_FOUND) {
befs_debug(sb, "<--- %s %pd not found", __func__, dentry);
d_add(dentry, NULL);
return ERR_PTR(-ENOENT);

inode = NULL;
} else if (ret != BEFS_OK || offset == 0) {
befs_error(sb, "<--- %s Error", __func__);
return ERR_PTR(-ENODATA);
inode = ERR_PTR(-ENODATA);
} else {
inode = befs_iget(dir->i_sb, (ino_t) offset);
}

inode = befs_iget(dir->i_sb, (ino_t) offset);
if (IS_ERR(inode))
return ERR_CAST(inode);

d_add(dentry, inode);

befs_debug(sb, "<--- %s", __func__);

return NULL;
return d_splice_alias(inode, dentry);
}

static int
Expand Down
16 changes: 4 additions & 12 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -6586,8 +6586,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
goto out_unlock_inode;
} else {
btrfs_update_inode(trans, root, inode);
unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
}

out_unlock:
Expand Down Expand Up @@ -6663,8 +6662,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
goto out_unlock_inode;

BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);

out_unlock:
btrfs_end_transaction(trans);
Expand Down Expand Up @@ -6809,12 +6807,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
if (err)
goto out_fail_inode;

d_instantiate(dentry, inode);
/*
* mkdir is special. We're unlocking after we call d_instantiate
* to avoid a race with nfsd calling d_instantiate.
*/
unlock_new_inode(inode);
d_instantiate_new(dentry, inode);
drop_on_err = 0;

out_fail:
Expand Down Expand Up @@ -10257,8 +10250,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
goto out_unlock_inode;
}

unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);

out_unlock:
btrfs_end_transaction(trans);
Expand Down
10 changes: 10 additions & 0 deletions fs/cachefiles/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,11 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
if (ret < 0)
goto create_error;

if (unlikely(d_unhashed(next))) {
dput(next);
inode_unlock(d_inode(dir));
goto lookup_again;
}
ASSERT(d_backing_inode(next));

_debug("mkdir -> %p{%p{ino=%lu}}",
Expand Down Expand Up @@ -764,6 +769,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
/* search the current directory for the element name */
inode_lock(d_inode(dir));

retry:
start = jiffies;
subdir = lookup_one_len(dirname, dir, strlen(dirname));
cachefiles_hist(cachefiles_lookup_histogram, start);
Expand Down Expand Up @@ -793,6 +799,10 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
if (ret < 0)
goto mkdir_error;

if (unlikely(d_unhashed(subdir))) {
dput(subdir);
goto retry;
}
ASSERT(d_backing_inode(subdir));

_debug("mkdir -> %p{%p{ino=%lu}}",
Expand Down
2 changes: 1 addition & 1 deletion fs/cramfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ static void cramfs_kill_sb(struct super_block *sb)
{
struct cramfs_sb_info *sbi = CRAMFS_SB(sb);

if (IS_ENABLED(CCONFIG_CRAMFS_MTD) && sb->s_mtd) {
if (IS_ENABLED(CONFIG_CRAMFS_MTD) && sb->s_mtd) {
if (sbi && sbi->mtd_point_size)
mtd_unpoint(sb->s_mtd, 0, sbi->mtd_point_size);
kill_mtd_super(sb);
Expand Down
22 changes: 22 additions & 0 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,28 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
}
EXPORT_SYMBOL(d_instantiate);

/*
* This should be equivalent to d_instantiate() + unlock_new_inode(),
* with lockdep-related part of unlock_new_inode() done before
* anything else. Use that instead of open-coding d_instantiate()/
* unlock_new_inode() combinations.
*/
void d_instantiate_new(struct dentry *entry, struct inode *inode)
{
BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
BUG_ON(!inode);
lockdep_annotate_inode_mutex_key(inode);
security_d_instantiate(entry, inode);
spin_lock(&inode->i_lock);
__d_instantiate(entry, inode);
WARN_ON(!(inode->i_state & I_NEW));
inode->i_state &= ~I_NEW;
smp_mb();
wake_up_bit(&inode->i_state, __I_NEW);
spin_unlock(&inode->i_lock);
}
EXPORT_SYMBOL(d_instantiate_new);

/**
* d_instantiate_no_diralias - instantiate a non-aliased dentry
* @entry: dentry to complete
Expand Down
3 changes: 1 addition & 2 deletions fs/ecryptfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,7 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
iget_failed(ecryptfs_inode);
goto out;
}
unlock_new_inode(ecryptfs_inode);
d_instantiate(ecryptfs_dentry, ecryptfs_inode);
d_instantiate_new(ecryptfs_dentry, ecryptfs_inode);
out:
return rc;
}
Expand Down
10 changes: 0 additions & 10 deletions fs/ext2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1264,21 +1264,11 @@ static void __ext2_truncate_blocks(struct inode *inode, loff_t offset)

static void ext2_truncate_blocks(struct inode *inode, loff_t offset)
{
/*
* XXX: it seems like a bug here that we don't allow
* IS_APPEND inode to have blocks-past-i_size trimmed off.
* review and fix this.
*
* Also would be nice to be able to handle IO errors and such,
* but that's probably too much to ask.
*/
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return;
if (ext2_inode_is_fast_symlink(inode))
return;
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;

dax_sem_down_write(EXT2_I(inode));
__ext2_truncate_blocks(inode, offset);
Expand Down
6 changes: 2 additions & 4 deletions fs/ext2/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
{
int err = ext2_add_link(dentry, inode);
if (!err) {
unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
return 0;
}
inode_dec_link_count(inode);
Expand Down Expand Up @@ -255,8 +254,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
if (err)
goto out_fail;

unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
out:
return err;

Expand Down
6 changes: 2 additions & 4 deletions fs/ext4/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -2411,8 +2411,7 @@ static int ext4_add_nondir(handle_t *handle,
int err = ext4_add_entry(handle, dentry, inode);
if (!err) {
ext4_mark_inode_dirty(handle, inode);
unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
return 0;
}
drop_nlink(inode);
Expand Down Expand Up @@ -2651,8 +2650,7 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
err = ext4_mark_inode_dirty(handle, dir);
if (err)
goto out_clear_inode;
unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
if (IS_DIRSYNC(dir))
ext4_handle_sync(handle);

Expand Down
12 changes: 4 additions & 8 deletions fs/f2fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,

alloc_nid_done(sbi, ino);

d_instantiate(dentry, inode);
unlock_new_inode(inode);
d_instantiate_new(dentry, inode);

if (IS_DIRSYNC(dir))
f2fs_sync_fs(sbi->sb, 1);
Expand Down Expand Up @@ -597,8 +596,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
err = page_symlink(inode, disk_link.name, disk_link.len);

err_out:
d_instantiate(dentry, inode);
unlock_new_inode(inode);
d_instantiate_new(dentry, inode);

/*
* Let's flush symlink data in order to avoid broken symlink as much as
Expand Down Expand Up @@ -661,8 +659,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)

alloc_nid_done(sbi, inode->i_ino);

d_instantiate(dentry, inode);
unlock_new_inode(inode);
d_instantiate_new(dentry, inode);

if (IS_DIRSYNC(dir))
f2fs_sync_fs(sbi->sb, 1);
Expand Down Expand Up @@ -713,8 +710,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,

alloc_nid_done(sbi, inode->i_ino);

d_instantiate(dentry, inode);
unlock_new_inode(inode);
d_instantiate_new(dentry, inode);

if (IS_DIRSYNC(dir))
f2fs_sync_fs(sbi->sb, 1);
Expand Down
12 changes: 4 additions & 8 deletions fs/jffs2/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry,
__func__, inode->i_ino, inode->i_mode, inode->i_nlink,
f->inocache->pino_nlink, inode->i_mapping->nrpages);

unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
return 0;

fail:
Expand Down Expand Up @@ -430,8 +429,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);

unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
return 0;

fail:
Expand Down Expand Up @@ -575,8 +573,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t mode
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);

unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
return 0;

fail:
Expand Down Expand Up @@ -747,8 +744,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);

unlock_new_inode(inode);
d_instantiate(dentry, inode);
d_instantiate_new(dentry, inode);
return 0;

fail:
Expand Down
12 changes: 4 additions & 8 deletions fs/jfs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode,
unlock_new_inode(ip);
iput(ip);
} else {
unlock_new_inode(ip);
d_instantiate(dentry, ip);
d_instantiate_new(dentry, ip);
}

out2:
Expand Down Expand Up @@ -313,8 +312,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
unlock_new_inode(ip);
iput(ip);
} else {
unlock_new_inode(ip);
d_instantiate(dentry, ip);
d_instantiate_new(dentry, ip);
}

out2:
Expand Down Expand Up @@ -1059,8 +1057,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
unlock_new_inode(ip);
iput(ip);
} else {
unlock_new_inode(ip);
d_instantiate(dentry, ip);
d_instantiate_new(dentry, ip);
}

out2:
Expand Down Expand Up @@ -1447,8 +1444,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
unlock_new_inode(ip);
iput(ip);
} else {
unlock_new_inode(ip);
d_instantiate(dentry, ip);
d_instantiate_new(dentry, ip);
}

out1:
Expand Down
1 change: 1 addition & 0 deletions fs/kernfs/mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,

info->root = root;
info->ns = ns;
INIT_LIST_HEAD(&info->node);

sb = sget_userns(fs_type, kernfs_test_super, kernfs_set_super, flags,
&init_user_ns, info);
Expand Down
Loading

0 comments on commit 5997aab

Please sign in to comment.