forked from Minki/linux
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 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;
|
||||
|
||||
@ -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
|
||||
|
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]);
|
||||
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();
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
@ -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);
|
||||
@ -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:
|
||||
@ -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);
|
||||
|
@ -572,6 +572,11 @@ lookup_again:
|
||||
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}}",
|
||||
@ -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);
|
||||
@ -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}}",
|
||||
|
@ -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);
|
||||
|
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);
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1264,21 +1264,11 @@ do_indirects:
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
@ -2651,8 +2650,7 @@ out_clear_inode:
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
@ -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
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
@ -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:
|
||||
@ -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:
|
||||
@ -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:
|
||||
@ -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:
|
||||
|
@ -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:
|
||||
@ -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:
|
||||
@ -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:
|
||||
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -1201,6 +1201,28 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||
break;
|
||||
case S_IFDIR:
|
||||
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;
|
||||
case S_IFCHR:
|
||||
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);
|
||||
|
||||
if (!err) {
|
||||
d_instantiate(dentry, inode);
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
|
||||
nilfs_mark_inode_dirty(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
out:
|
||||
if (!err)
|
||||
err = nilfs_transaction_commit(dir->i_sb);
|
||||
|
@ -75,8 +75,7 @@ static int orangefs_create(struct inode *dir,
|
||||
get_khandle_from_ino(inode),
|
||||
dentry);
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
orangefs_set_timeout(dentry);
|
||||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||
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",
|
||||
get_khandle_from_ino(inode));
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
orangefs_set_timeout(dentry);
|
||||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||
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",
|
||||
get_khandle_from_ino(inode));
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
orangefs_set_timeout(dentry);
|
||||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||
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(dir);
|
||||
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
retval = journal_end(&th);
|
||||
|
||||
out_failed:
|
||||
@ -771,8 +770,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode
|
||||
goto out_failed;
|
||||
}
|
||||
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
retval = journal_end(&th);
|
||||
|
||||
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 */
|
||||
reiserfs_update_sd(&th, dir);
|
||||
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
retval = journal_end(&th);
|
||||
out_failed:
|
||||
reiserfs_write_unlock(dir->i_sb);
|
||||
@ -1187,8 +1184,7 @@ static int reiserfs_symlink(struct inode *parent_dir,
|
||||
goto out_failed;
|
||||
}
|
||||
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
retval = journal_end(&th);
|
||||
out_failed:
|
||||
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);
|
||||
|
||||
/*
|
||||
* Don't call trylock_super as it is a potential
|
||||
* scalability bottleneck. The counts could get updated
|
||||
* between super_cache_count and super_cache_scan anyway.
|
||||
* Call to super_cache_count with shrinker_rwsem held
|
||||
* ensures the safety of call to list_lru_shrink_count() and
|
||||
* s_op->nr_cached_objects().
|
||||
* We don't call trylock_super() here as it is a scalability bottleneck,
|
||||
* so we're exposed to partial setup state. The shrinker rwsem does not
|
||||
* protect filesystem operations backing list_lru_shrink_count() or
|
||||
* s_op->nr_cached_objects(). Counts can change between
|
||||
* super_cache_count and super_cache_scan, so we really don't need locks
|
||||
* 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)
|
||||
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;
|
||||
BUG_ON(!sb);
|
||||
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;
|
||||
|
||||
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;
|
||||
void *ns;
|
||||
bool new_sb;
|
||||
bool new_sb = false;
|
||||
|
||||
if (!(flags & SB_KERNMOUNT)) {
|
||||
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);
|
||||
root = kernfs_mount_ns(fs_type, flags, sysfs_root,
|
||||
SYSFS_MAGIC, &new_sb, ns);
|
||||
if (IS_ERR(root) || !new_sb)
|
||||
if (!new_sb)
|
||||
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;
|
||||
|
||||
return root;
|
||||
|
@ -622,8 +622,7 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode)
|
||||
if (fibh.sbh != fibh.ebh)
|
||||
brelse(fibh.ebh);
|
||||
brelse(fibh.sbh);
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -733,8 +732,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
inc_nlink(dir);
|
||||
dir->i_ctime = dir->i_mtime = current_time(dir);
|
||||
mark_inode_dirty(dir);
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
if (fibh.sbh != fibh.ebh)
|
||||
brelse(fibh.ebh);
|
||||
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);
|
||||
if (!err) {
|
||||
unlock_new_inode(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
d_instantiate_new(dentry, inode);
|
||||
return 0;
|
||||
}
|
||||
inode_dec_link_count(inode);
|
||||
@ -193,8 +192,7 @@ static int ufs_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);
|
||||
return 0;
|
||||
|
||||
out_fail:
|
||||
|
@ -224,6 +224,7 @@ extern seqlock_t rename_lock;
|
||||
* These are the low-level FS interfaces to the dcache..
|
||||
*/
|
||||
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_anon(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);
|
||||
|
||||
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,
|
||||
struct page **pages,
|
||||
int idx,
|
||||
@ -1102,7 +1102,7 @@ static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
|
||||
size_t *start)
|
||||
{
|
||||
struct page **p;
|
||||
size_t n;
|
||||
ssize_t n;
|
||||
int idx;
|
||||
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. */
|
||||
dentry = dget(opt_dentry);
|
||||
} 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);
|
||||
if (!dentry)
|
||||
dentry = d_find_any_alias(inode);
|
||||
}
|
||||
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)) {
|
||||
/* We must have a dentry to determine the label on
|
||||
* procfs inodes */
|
||||
if (opt_dentry)
|
||||
if (opt_dentry) {
|
||||
/* Called from d_instantiate or
|
||||
* d_splice_alias. */
|
||||
dentry = dget(opt_dentry);
|
||||
else
|
||||
} else {
|
||||
/* 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);
|
||||
if (!dentry)
|
||||
dentry = d_find_any_alias(inode);
|
||||
}
|
||||
/*
|
||||
* This can be hit on boot when a file is accessed
|
||||
* before the policy is loaded. When we load policy we
|
||||
|
Loading…
Reference in New Issue
Block a user