2
0
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:
Linus Torvalds 2018-05-21 11:54:57 -07:00
commit 5997aab0a1
26 changed files with 152 additions and 118 deletions

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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}}",

View File

@ -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);

View File

@ -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

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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:

View File

@ -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:

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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:

View File

@ -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 *);

View File

@ -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;

View File

@ -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