mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 00:34:10 +08:00
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/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()
This commit is contained in:
commit
5997aab0a1
@ -201,14 +201,16 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
|||||||
struct super_block *sb = dir->i_sb;
|
struct super_block *sb = dir->i_sb;
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
|
struct dentry *res;
|
||||||
|
|
||||||
pr_debug("%s(\"%pd\")\n", __func__, dentry);
|
pr_debug("%s(\"%pd\")\n", __func__, dentry);
|
||||||
|
|
||||||
affs_lock_dir(dir);
|
affs_lock_dir(dir);
|
||||||
bh = affs_find_entry(dir, dentry);
|
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);
|
return ERR_CAST(bh);
|
||||||
|
}
|
||||||
if (bh) {
|
if (bh) {
|
||||||
u32 ino = bh->b_blocknr;
|
u32 ino = bh->b_blocknr;
|
||||||
|
|
||||||
@ -222,11 +224,12 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
|||||||
}
|
}
|
||||||
affs_brelse(bh);
|
affs_brelse(bh);
|
||||||
inode = affs_iget(sb, ino);
|
inode = affs_iget(sb, ino);
|
||||||
if (IS_ERR(inode))
|
|
||||||
return ERR_CAST(inode);
|
|
||||||
}
|
}
|
||||||
d_add(dentry, inode);
|
res = d_splice_alias(inode, dentry);
|
||||||
return NULL;
|
if (!IS_ERR_OR_NULL(res))
|
||||||
|
res->d_fsdata = dentry->d_fsdata;
|
||||||
|
affs_unlock_dir(dir);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
4
fs/aio.c
4
fs/aio.c
@ -1078,8 +1078,8 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id)
|
|||||||
|
|
||||||
ctx = rcu_dereference(table->table[id]);
|
ctx = rcu_dereference(table->table[id]);
|
||||||
if (ctx && ctx->user_id == ctx_id) {
|
if (ctx && ctx->user_id == ctx_id) {
|
||||||
percpu_ref_get(&ctx->users);
|
if (percpu_ref_tryget_live(&ctx->users))
|
||||||
ret = ctx;
|
ret = ctx;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
@ -198,23 +198,16 @@ befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
|||||||
|
|
||||||
if (ret == BEFS_BT_NOT_FOUND) {
|
if (ret == BEFS_BT_NOT_FOUND) {
|
||||||
befs_debug(sb, "<--- %s %pd not found", __func__, dentry);
|
befs_debug(sb, "<--- %s %pd not found", __func__, dentry);
|
||||||
d_add(dentry, NULL);
|
inode = NULL;
|
||||||
return ERR_PTR(-ENOENT);
|
|
||||||
|
|
||||||
} else if (ret != BEFS_OK || offset == 0) {
|
} else if (ret != BEFS_OK || offset == 0) {
|
||||||
befs_error(sb, "<--- %s Error", __func__);
|
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__);
|
befs_debug(sb, "<--- %s", __func__);
|
||||||
|
|
||||||
return NULL;
|
return d_splice_alias(inode, dentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -6586,8 +6586,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
goto out_unlock_inode;
|
goto out_unlock_inode;
|
||||||
} else {
|
} else {
|
||||||
btrfs_update_inode(trans, root, inode);
|
btrfs_update_inode(trans, root, inode);
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
@ -6663,8 +6662,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
|||||||
goto out_unlock_inode;
|
goto out_unlock_inode;
|
||||||
|
|
||||||
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
|
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
@ -6809,12 +6807,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_fail_inode;
|
goto out_fail_inode;
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(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);
|
|
||||||
drop_on_err = 0;
|
drop_on_err = 0;
|
||||||
|
|
||||||
out_fail:
|
out_fail:
|
||||||
@ -10257,8 +10250,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|||||||
goto out_unlock_inode;
|
goto out_unlock_inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
|
@ -572,6 +572,11 @@ lookup_again:
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto create_error;
|
goto create_error;
|
||||||
|
|
||||||
|
if (unlikely(d_unhashed(next))) {
|
||||||
|
dput(next);
|
||||||
|
inode_unlock(d_inode(dir));
|
||||||
|
goto lookup_again;
|
||||||
|
}
|
||||||
ASSERT(d_backing_inode(next));
|
ASSERT(d_backing_inode(next));
|
||||||
|
|
||||||
_debug("mkdir -> %p{%p{ino=%lu}}",
|
_debug("mkdir -> %p{%p{ino=%lu}}",
|
||||||
@ -764,6 +769,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
|||||||
/* search the current directory for the element name */
|
/* search the current directory for the element name */
|
||||||
inode_lock(d_inode(dir));
|
inode_lock(d_inode(dir));
|
||||||
|
|
||||||
|
retry:
|
||||||
start = jiffies;
|
start = jiffies;
|
||||||
subdir = lookup_one_len(dirname, dir, strlen(dirname));
|
subdir = lookup_one_len(dirname, dir, strlen(dirname));
|
||||||
cachefiles_hist(cachefiles_lookup_histogram, start);
|
cachefiles_hist(cachefiles_lookup_histogram, start);
|
||||||
@ -793,6 +799,10 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto mkdir_error;
|
goto mkdir_error;
|
||||||
|
|
||||||
|
if (unlikely(d_unhashed(subdir))) {
|
||||||
|
dput(subdir);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
ASSERT(d_backing_inode(subdir));
|
ASSERT(d_backing_inode(subdir));
|
||||||
|
|
||||||
_debug("mkdir -> %p{%p{ino=%lu}}",
|
_debug("mkdir -> %p{%p{ino=%lu}}",
|
||||||
|
@ -492,7 +492,7 @@ static void cramfs_kill_sb(struct super_block *sb)
|
|||||||
{
|
{
|
||||||
struct cramfs_sb_info *sbi = CRAMFS_SB(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)
|
if (sbi && sbi->mtd_point_size)
|
||||||
mtd_unpoint(sb->s_mtd, 0, sbi->mtd_point_size);
|
mtd_unpoint(sb->s_mtd, 0, sbi->mtd_point_size);
|
||||||
kill_mtd_super(sb);
|
kill_mtd_super(sb);
|
||||||
|
22
fs/dcache.c
22
fs/dcache.c
@ -1899,6 +1899,28 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(d_instantiate);
|
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
|
* d_instantiate_no_diralias - instantiate a non-aliased dentry
|
||||||
* @entry: dentry to complete
|
* @entry: dentry to complete
|
||||||
|
@ -283,8 +283,7 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
|
|||||||
iget_failed(ecryptfs_inode);
|
iget_failed(ecryptfs_inode);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
unlock_new_inode(ecryptfs_inode);
|
d_instantiate_new(ecryptfs_dentry, ecryptfs_inode);
|
||||||
d_instantiate(ecryptfs_dentry, ecryptfs_inode);
|
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -1264,21 +1264,11 @@ do_indirects:
|
|||||||
|
|
||||||
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) ||
|
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
|
||||||
S_ISLNK(inode->i_mode)))
|
S_ISLNK(inode->i_mode)))
|
||||||
return;
|
return;
|
||||||
if (ext2_inode_is_fast_symlink(inode))
|
if (ext2_inode_is_fast_symlink(inode))
|
||||||
return;
|
return;
|
||||||
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
|
|
||||||
return;
|
|
||||||
|
|
||||||
dax_sem_down_write(EXT2_I(inode));
|
dax_sem_down_write(EXT2_I(inode));
|
||||||
__ext2_truncate_blocks(inode, offset);
|
__ext2_truncate_blocks(inode, offset);
|
||||||
|
@ -41,8 +41,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||||||
{
|
{
|
||||||
int err = ext2_add_link(dentry, inode);
|
int err = ext2_add_link(dentry, inode);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
@ -255,8 +254,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -2411,8 +2411,7 @@ static int ext4_add_nondir(handle_t *handle,
|
|||||||
int err = ext4_add_entry(handle, dentry, inode);
|
int err = ext4_add_entry(handle, dentry, inode);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
ext4_mark_inode_dirty(handle, inode);
|
ext4_mark_inode_dirty(handle, inode);
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
drop_nlink(inode);
|
drop_nlink(inode);
|
||||||
@ -2651,8 +2650,7 @@ out_clear_inode:
|
|||||||
err = ext4_mark_inode_dirty(handle, dir);
|
err = ext4_mark_inode_dirty(handle, dir);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_clear_inode;
|
goto out_clear_inode;
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
ext4_handle_sync(handle);
|
ext4_handle_sync(handle);
|
||||||
|
|
||||||
|
@ -294,8 +294,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
|||||||
|
|
||||||
alloc_nid_done(sbi, ino);
|
alloc_nid_done(sbi, ino);
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
|
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
f2fs_sync_fs(sbi->sb, 1);
|
f2fs_sync_fs(sbi->sb, 1);
|
||||||
@ -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 = page_symlink(inode, disk_link.name, disk_link.len);
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let's flush symlink data in order to avoid broken symlink as much as
|
* Let's flush symlink data in order to avoid broken symlink as much as
|
||||||
@ -661,8 +659,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
|
|
||||||
alloc_nid_done(sbi, inode->i_ino);
|
alloc_nid_done(sbi, inode->i_ino);
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
|
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
f2fs_sync_fs(sbi->sb, 1);
|
f2fs_sync_fs(sbi->sb, 1);
|
||||||
@ -713,8 +710,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
|
|
||||||
alloc_nid_done(sbi, inode->i_ino);
|
alloc_nid_done(sbi, inode->i_ino);
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
|
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
f2fs_sync_fs(sbi->sb, 1);
|
f2fs_sync_fs(sbi->sb, 1);
|
||||||
|
@ -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,
|
__func__, inode->i_ino, inode->i_mode, inode->i_nlink,
|
||||||
f->inocache->pino_nlink, inode->i_mapping->nrpages);
|
f->inocache->pino_nlink, inode->i_mapping->nrpages);
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -430,8 +429,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
|
|||||||
mutex_unlock(&dir_f->sem);
|
mutex_unlock(&dir_f->sem);
|
||||||
jffs2_complete_reservation(c);
|
jffs2_complete_reservation(c);
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -575,8 +573,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t mode
|
|||||||
mutex_unlock(&dir_f->sem);
|
mutex_unlock(&dir_f->sem);
|
||||||
jffs2_complete_reservation(c);
|
jffs2_complete_reservation(c);
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -747,8 +744,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode
|
|||||||
mutex_unlock(&dir_f->sem);
|
mutex_unlock(&dir_f->sem);
|
||||||
jffs2_complete_reservation(c);
|
jffs2_complete_reservation(c);
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -178,8 +178,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode,
|
|||||||
unlock_new_inode(ip);
|
unlock_new_inode(ip);
|
||||||
iput(ip);
|
iput(ip);
|
||||||
} else {
|
} else {
|
||||||
unlock_new_inode(ip);
|
d_instantiate_new(dentry, ip);
|
||||||
d_instantiate(dentry, ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out2:
|
out2:
|
||||||
@ -313,8 +312,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
|||||||
unlock_new_inode(ip);
|
unlock_new_inode(ip);
|
||||||
iput(ip);
|
iput(ip);
|
||||||
} else {
|
} else {
|
||||||
unlock_new_inode(ip);
|
d_instantiate_new(dentry, ip);
|
||||||
d_instantiate(dentry, ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out2:
|
out2:
|
||||||
@ -1059,8 +1057,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
|
|||||||
unlock_new_inode(ip);
|
unlock_new_inode(ip);
|
||||||
iput(ip);
|
iput(ip);
|
||||||
} else {
|
} else {
|
||||||
unlock_new_inode(ip);
|
d_instantiate_new(dentry, ip);
|
||||||
d_instantiate(dentry, ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out2:
|
out2:
|
||||||
@ -1447,8 +1444,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
unlock_new_inode(ip);
|
unlock_new_inode(ip);
|
||||||
iput(ip);
|
iput(ip);
|
||||||
} else {
|
} else {
|
||||||
unlock_new_inode(ip);
|
d_instantiate_new(dentry, ip);
|
||||||
d_instantiate(dentry, ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out1:
|
out1:
|
||||||
|
@ -316,6 +316,7 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,
|
|||||||
|
|
||||||
info->root = root;
|
info->root = root;
|
||||||
info->ns = ns;
|
info->ns = ns;
|
||||||
|
INIT_LIST_HEAD(&info->node);
|
||||||
|
|
||||||
sb = sget_userns(fs_type, kernfs_test_super, kernfs_set_super, flags,
|
sb = sget_userns(fs_type, kernfs_test_super, kernfs_set_super, flags,
|
||||||
&init_user_ns, info);
|
&init_user_ns, info);
|
||||||
|
@ -1201,6 +1201,28 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||||||
break;
|
break;
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
|
host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
|
||||||
|
if (!host_err && unlikely(d_unhashed(dchild))) {
|
||||||
|
struct dentry *d;
|
||||||
|
d = lookup_one_len(dchild->d_name.name,
|
||||||
|
dchild->d_parent,
|
||||||
|
dchild->d_name.len);
|
||||||
|
if (IS_ERR(d)) {
|
||||||
|
host_err = PTR_ERR(d);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (unlikely(d_is_negative(d))) {
|
||||||
|
dput(d);
|
||||||
|
err = nfserr_serverfault;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
dput(resfhp->fh_dentry);
|
||||||
|
resfhp->fh_dentry = dget(d);
|
||||||
|
err = fh_update(resfhp);
|
||||||
|
dput(dchild);
|
||||||
|
dchild = d;
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case S_IFCHR:
|
case S_IFCHR:
|
||||||
case S_IFBLK:
|
case S_IFBLK:
|
||||||
|
@ -46,8 +46,7 @@ static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||||||
int err = nilfs_add_link(dentry, inode);
|
int err = nilfs_add_link(dentry, inode);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
@ -243,8 +242,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
goto out_fail;
|
goto out_fail;
|
||||||
|
|
||||||
nilfs_mark_inode_dirty(inode);
|
nilfs_mark_inode_dirty(inode);
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
out:
|
out:
|
||||||
if (!err)
|
if (!err)
|
||||||
err = nilfs_transaction_commit(dir->i_sb);
|
err = nilfs_transaction_commit(dir->i_sb);
|
||||||
|
@ -75,8 +75,7 @@ static int orangefs_create(struct inode *dir,
|
|||||||
get_khandle_from_ino(inode),
|
get_khandle_from_ino(inode),
|
||||||
dentry);
|
dentry);
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
orangefs_set_timeout(dentry);
|
orangefs_set_timeout(dentry);
|
||||||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||||
ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS;
|
ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS;
|
||||||
@ -332,8 +331,7 @@ static int orangefs_symlink(struct inode *dir,
|
|||||||
"Assigned symlink inode new number of %pU\n",
|
"Assigned symlink inode new number of %pU\n",
|
||||||
get_khandle_from_ino(inode));
|
get_khandle_from_ino(inode));
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
orangefs_set_timeout(dentry);
|
orangefs_set_timeout(dentry);
|
||||||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||||
ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS;
|
ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS;
|
||||||
@ -402,8 +400,7 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
|
|||||||
"Assigned dir inode new number of %pU\n",
|
"Assigned dir inode new number of %pU\n",
|
||||||
get_khandle_from_ino(inode));
|
get_khandle_from_ino(inode));
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
unlock_new_inode(inode);
|
|
||||||
orangefs_set_timeout(dentry);
|
orangefs_set_timeout(dentry);
|
||||||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||||
ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS;
|
ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS;
|
||||||
|
@ -687,8 +687,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, umode_t mod
|
|||||||
reiserfs_update_inode_transaction(inode);
|
reiserfs_update_inode_transaction(inode);
|
||||||
reiserfs_update_inode_transaction(dir);
|
reiserfs_update_inode_transaction(dir);
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
retval = journal_end(&th);
|
retval = journal_end(&th);
|
||||||
|
|
||||||
out_failed:
|
out_failed:
|
||||||
@ -771,8 +770,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode
|
|||||||
goto out_failed;
|
goto out_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
retval = journal_end(&th);
|
retval = journal_end(&th);
|
||||||
|
|
||||||
out_failed:
|
out_failed:
|
||||||
@ -871,8 +869,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
|
|||||||
/* the above add_entry did not update dir's stat data */
|
/* the above add_entry did not update dir's stat data */
|
||||||
reiserfs_update_sd(&th, dir);
|
reiserfs_update_sd(&th, dir);
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
retval = journal_end(&th);
|
retval = journal_end(&th);
|
||||||
out_failed:
|
out_failed:
|
||||||
reiserfs_write_unlock(dir->i_sb);
|
reiserfs_write_unlock(dir->i_sb);
|
||||||
@ -1187,8 +1184,7 @@ static int reiserfs_symlink(struct inode *parent_dir,
|
|||||||
goto out_failed;
|
goto out_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
retval = journal_end(&th);
|
retval = journal_end(&th);
|
||||||
out_failed:
|
out_failed:
|
||||||
reiserfs_write_unlock(parent_dir->i_sb);
|
reiserfs_write_unlock(parent_dir->i_sb);
|
||||||
|
30
fs/super.c
30
fs/super.c
@ -121,13 +121,23 @@ static unsigned long super_cache_count(struct shrinker *shrink,
|
|||||||
sb = container_of(shrink, struct super_block, s_shrink);
|
sb = container_of(shrink, struct super_block, s_shrink);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't call trylock_super as it is a potential
|
* We don't call trylock_super() here as it is a scalability bottleneck,
|
||||||
* scalability bottleneck. The counts could get updated
|
* so we're exposed to partial setup state. The shrinker rwsem does not
|
||||||
* between super_cache_count and super_cache_scan anyway.
|
* protect filesystem operations backing list_lru_shrink_count() or
|
||||||
* Call to super_cache_count with shrinker_rwsem held
|
* s_op->nr_cached_objects(). Counts can change between
|
||||||
* ensures the safety of call to list_lru_shrink_count() and
|
* super_cache_count and super_cache_scan, so we really don't need locks
|
||||||
* s_op->nr_cached_objects().
|
* here.
|
||||||
|
*
|
||||||
|
* However, if we are currently mounting the superblock, the underlying
|
||||||
|
* filesystem might be in a state of partial construction and hence it
|
||||||
|
* is dangerous to access it. trylock_super() uses a SB_BORN check to
|
||||||
|
* avoid this situation, so do the same here. The memory barrier is
|
||||||
|
* matched with the one in mount_fs() as we don't hold locks here.
|
||||||
*/
|
*/
|
||||||
|
if (!(sb->s_flags & SB_BORN))
|
||||||
|
return 0;
|
||||||
|
smp_rmb();
|
||||||
|
|
||||||
if (sb->s_op && sb->s_op->nr_cached_objects)
|
if (sb->s_op && sb->s_op->nr_cached_objects)
|
||||||
total_objects = sb->s_op->nr_cached_objects(sb, sc);
|
total_objects = sb->s_op->nr_cached_objects(sb, sc);
|
||||||
|
|
||||||
@ -1272,6 +1282,14 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
|
|||||||
sb = root->d_sb;
|
sb = root->d_sb;
|
||||||
BUG_ON(!sb);
|
BUG_ON(!sb);
|
||||||
WARN_ON(!sb->s_bdi);
|
WARN_ON(!sb->s_bdi);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write barrier is for super_cache_count(). We place it before setting
|
||||||
|
* SB_BORN as the data dependency between the two functions is the
|
||||||
|
* superblock structure contents that we just set up, not the SB_BORN
|
||||||
|
* flag.
|
||||||
|
*/
|
||||||
|
smp_wmb();
|
||||||
sb->s_flags |= SB_BORN;
|
sb->s_flags |= SB_BORN;
|
||||||
|
|
||||||
error = security_sb_kern_mount(sb, flags, secdata);
|
error = security_sb_kern_mount(sb, flags, secdata);
|
||||||
|
@ -25,7 +25,7 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
|
|||||||
{
|
{
|
||||||
struct dentry *root;
|
struct dentry *root;
|
||||||
void *ns;
|
void *ns;
|
||||||
bool new_sb;
|
bool new_sb = false;
|
||||||
|
|
||||||
if (!(flags & SB_KERNMOUNT)) {
|
if (!(flags & SB_KERNMOUNT)) {
|
||||||
if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET))
|
if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET))
|
||||||
@ -35,9 +35,9 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
|
|||||||
ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET);
|
ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET);
|
||||||
root = kernfs_mount_ns(fs_type, flags, sysfs_root,
|
root = kernfs_mount_ns(fs_type, flags, sysfs_root,
|
||||||
SYSFS_MAGIC, &new_sb, ns);
|
SYSFS_MAGIC, &new_sb, ns);
|
||||||
if (IS_ERR(root) || !new_sb)
|
if (!new_sb)
|
||||||
kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
|
kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
|
||||||
else if (new_sb)
|
else if (!IS_ERR(root))
|
||||||
root->d_sb->s_iflags |= SB_I_USERNS_VISIBLE;
|
root->d_sb->s_iflags |= SB_I_USERNS_VISIBLE;
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
|
@ -622,8 +622,7 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||||||
if (fibh.sbh != fibh.ebh)
|
if (fibh.sbh != fibh.ebh)
|
||||||
brelse(fibh.ebh);
|
brelse(fibh.ebh);
|
||||||
brelse(fibh.sbh);
|
brelse(fibh.sbh);
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -733,8 +732,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
inc_nlink(dir);
|
inc_nlink(dir);
|
||||||
dir->i_ctime = dir->i_mtime = current_time(dir);
|
dir->i_ctime = dir->i_mtime = current_time(dir);
|
||||||
mark_inode_dirty(dir);
|
mark_inode_dirty(dir);
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
if (fibh.sbh != fibh.ebh)
|
if (fibh.sbh != fibh.ebh)
|
||||||
brelse(fibh.ebh);
|
brelse(fibh.ebh);
|
||||||
brelse(fibh.sbh);
|
brelse(fibh.sbh);
|
||||||
|
@ -39,8 +39,7 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||||||
{
|
{
|
||||||
int err = ufs_add_link(dentry, inode);
|
int err = ufs_add_link(dentry, inode);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
@ -193,8 +192,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
d_instantiate_new(dentry, inode);
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_fail:
|
out_fail:
|
||||||
|
@ -224,6 +224,7 @@ extern seqlock_t rename_lock;
|
|||||||
* These are the low-level FS interfaces to the dcache..
|
* These are the low-level FS interfaces to the dcache..
|
||||||
*/
|
*/
|
||||||
extern void d_instantiate(struct dentry *, struct inode *);
|
extern void d_instantiate(struct dentry *, struct inode *);
|
||||||
|
extern void d_instantiate_new(struct dentry *, struct inode *);
|
||||||
extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
|
extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
|
||||||
extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *);
|
extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *);
|
||||||
extern int d_instantiate_no_diralias(struct dentry *, struct inode *);
|
extern int d_instantiate_no_diralias(struct dentry *, struct inode *);
|
||||||
|
@ -1012,7 +1012,7 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iov_iter_gap_alignment);
|
EXPORT_SYMBOL(iov_iter_gap_alignment);
|
||||||
|
|
||||||
static inline size_t __pipe_get_pages(struct iov_iter *i,
|
static inline ssize_t __pipe_get_pages(struct iov_iter *i,
|
||||||
size_t maxsize,
|
size_t maxsize,
|
||||||
struct page **pages,
|
struct page **pages,
|
||||||
int idx,
|
int idx,
|
||||||
@ -1102,7 +1102,7 @@ static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
|
|||||||
size_t *start)
|
size_t *start)
|
||||||
{
|
{
|
||||||
struct page **p;
|
struct page **p;
|
||||||
size_t n;
|
ssize_t n;
|
||||||
int idx;
|
int idx;
|
||||||
int npages;
|
int npages;
|
||||||
|
|
||||||
|
@ -1568,8 +1568,15 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
|
|||||||
/* Called from d_instantiate or d_splice_alias. */
|
/* Called from d_instantiate or d_splice_alias. */
|
||||||
dentry = dget(opt_dentry);
|
dentry = dget(opt_dentry);
|
||||||
} else {
|
} else {
|
||||||
/* Called from selinux_complete_init, try to find a dentry. */
|
/*
|
||||||
|
* Called from selinux_complete_init, try to find a dentry.
|
||||||
|
* Some filesystems really want a connected one, so try
|
||||||
|
* that first. We could split SECURITY_FS_USE_XATTR in
|
||||||
|
* two, depending upon that...
|
||||||
|
*/
|
||||||
dentry = d_find_alias(inode);
|
dentry = d_find_alias(inode);
|
||||||
|
if (!dentry)
|
||||||
|
dentry = d_find_any_alias(inode);
|
||||||
}
|
}
|
||||||
if (!dentry) {
|
if (!dentry) {
|
||||||
/*
|
/*
|
||||||
@ -1674,14 +1681,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
|
|||||||
if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
|
if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
|
||||||
/* We must have a dentry to determine the label on
|
/* We must have a dentry to determine the label on
|
||||||
* procfs inodes */
|
* procfs inodes */
|
||||||
if (opt_dentry)
|
if (opt_dentry) {
|
||||||
/* Called from d_instantiate or
|
/* Called from d_instantiate or
|
||||||
* d_splice_alias. */
|
* d_splice_alias. */
|
||||||
dentry = dget(opt_dentry);
|
dentry = dget(opt_dentry);
|
||||||
else
|
} else {
|
||||||
/* Called from selinux_complete_init, try to
|
/* Called from selinux_complete_init, try to
|
||||||
* find a dentry. */
|
* find a dentry. Some filesystems really want
|
||||||
|
* a connected one, so try that first.
|
||||||
|
*/
|
||||||
dentry = d_find_alias(inode);
|
dentry = d_find_alias(inode);
|
||||||
|
if (!dentry)
|
||||||
|
dentry = d_find_any_alias(inode);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* This can be hit on boot when a file is accessed
|
* This can be hit on boot when a file is accessed
|
||||||
* before the policy is loaded. When we load policy we
|
* before the policy is loaded. When we load policy we
|
||||||
|
Loading…
Reference in New Issue
Block a user