mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
vfs-6.16-rc3.fixes
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCaE/PTwAKCRCRxhvAZXjc oo7dAQDCEgd22Of2ibYK0wza1RE17Qjm1Qljt0tHUxki/3Gr/QD9EAJyIhEjplMj ntEQrlByWVw8aOVWwtSjFVq55mMLrgI= =SNXv -----END PGP SIGNATURE----- Merge tag 'vfs-6.16-rc3.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs fixes from Christian Brauner: - Fix a regression in overlayfs caused by reworking the lookup_one*() set of helpers - Make sure that the name of the dentry is printed in overlayfs' mkdir() helper - Add missing iocb values to TRACE_IOCB_STRINGS define - Unlock the superblock during iterate_supers_type(). This was an accidental internal api change - Drop a misleading assert in file_seek_cur_needs_f_lock() helper - Never refuse to return PIDFD_GET_INGO when parent pid is zero That can trivially happen in container scenarios where the parent process might be located in an ancestor pid namespace - Don't revalidate in try_lookup_noperm() as that causes regression for filesystems such as cifs - Fix simple_xattr_list() and reset the err variable after security_inode_listsecurity() got called so as not to confuse userspace about the length of the xattr * tag 'vfs-6.16-rc3.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs: drop assert in file_seek_cur_needs_f_lock fs: unlock the superblock during iterate_supers_type ovl: fix debug print in case of mkdir error VFS: change try_lookup_noperm() to skip revalidation fs: add missing values to TRACE_IOCB_STRINGS fs/xattr.c: fix simple_xattr_list() ovl: fix regression caused by lookup helpers API changes pidfs: never refuse ppid == 0 in PIDFD_GET_INFO
This commit is contained in:
commit
fe78e02600
8 changed files with 40 additions and 14 deletions
|
@ -1198,8 +1198,12 @@ bool file_seek_cur_needs_f_lock(struct file *file)
|
||||||
if (!(file->f_mode & FMODE_ATOMIC_POS) && !file->f_op->iterate_shared)
|
if (!(file->f_mode & FMODE_ATOMIC_POS) && !file->f_op->iterate_shared)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
VFS_WARN_ON_ONCE((file_count(file) > 1) &&
|
/*
|
||||||
!mutex_is_locked(&file->f_pos_lock));
|
* Note that we are not guaranteed to be called after fdget_pos() on
|
||||||
|
* this file obj, in which case the caller is expected to provide the
|
||||||
|
* appropriate locking.
|
||||||
|
*/
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
fs/namei.c
17
fs/namei.c
|
@ -2917,7 +2917,8 @@ static int lookup_one_common(struct mnt_idmap *idmap,
|
||||||
* @base: base directory to lookup from
|
* @base: base directory to lookup from
|
||||||
*
|
*
|
||||||
* Look up a dentry by name in the dcache, returning NULL if it does not
|
* Look up a dentry by name in the dcache, returning NULL if it does not
|
||||||
* currently exist. The function does not try to create a dentry.
|
* currently exist. The function does not try to create a dentry and if one
|
||||||
|
* is found it doesn't try to revalidate it.
|
||||||
*
|
*
|
||||||
* Note that this routine is purely a helper for filesystem usage and should
|
* Note that this routine is purely a helper for filesystem usage and should
|
||||||
* not be called by generic code. It does no permission checking.
|
* not be called by generic code. It does no permission checking.
|
||||||
|
@ -2933,7 +2934,7 @@ struct dentry *try_lookup_noperm(struct qstr *name, struct dentry *base)
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
||||||
return lookup_dcache(name, base, 0);
|
return d_lookup(base, name);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(try_lookup_noperm);
|
EXPORT_SYMBOL(try_lookup_noperm);
|
||||||
|
|
||||||
|
@ -3057,14 +3058,22 @@ EXPORT_SYMBOL(lookup_one_positive_unlocked);
|
||||||
* Note that this routine is purely a helper for filesystem usage and should
|
* Note that this routine is purely a helper for filesystem usage and should
|
||||||
* not be called by generic code. It does no permission checking.
|
* not be called by generic code. It does no permission checking.
|
||||||
*
|
*
|
||||||
* Unlike lookup_noperm, it should be called without the parent
|
* Unlike lookup_noperm(), it should be called without the parent
|
||||||
* i_rwsem held, and will take the i_rwsem itself if necessary.
|
* i_rwsem held, and will take the i_rwsem itself if necessary.
|
||||||
|
*
|
||||||
|
* Unlike try_lookup_noperm() it *does* revalidate the dentry if it already
|
||||||
|
* existed.
|
||||||
*/
|
*/
|
||||||
struct dentry *lookup_noperm_unlocked(struct qstr *name, struct dentry *base)
|
struct dentry *lookup_noperm_unlocked(struct qstr *name, struct dentry *base)
|
||||||
{
|
{
|
||||||
struct dentry *ret;
|
struct dentry *ret;
|
||||||
|
int err;
|
||||||
|
|
||||||
ret = try_lookup_noperm(name, base);
|
err = lookup_noperm_common(name, base);
|
||||||
|
if (err)
|
||||||
|
return ERR_PTR(err);
|
||||||
|
|
||||||
|
ret = lookup_dcache(name, base, 0);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = lookup_slow(name, base, 0);
|
ret = lookup_slow(name, base, 0);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1393,7 +1393,7 @@ out:
|
||||||
bool ovl_lower_positive(struct dentry *dentry)
|
bool ovl_lower_positive(struct dentry *dentry)
|
||||||
{
|
{
|
||||||
struct ovl_entry *poe = OVL_E(dentry->d_parent);
|
struct ovl_entry *poe = OVL_E(dentry->d_parent);
|
||||||
struct qstr *name = &dentry->d_name;
|
const struct qstr *name = &dentry->d_name;
|
||||||
const struct cred *old_cred;
|
const struct cred *old_cred;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
bool positive = false;
|
bool positive = false;
|
||||||
|
@ -1416,9 +1416,15 @@ bool ovl_lower_positive(struct dentry *dentry)
|
||||||
struct dentry *this;
|
struct dentry *this;
|
||||||
struct ovl_path *parentpath = &ovl_lowerstack(poe)[i];
|
struct ovl_path *parentpath = &ovl_lowerstack(poe)[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to make a non-const copy of dentry->d_name,
|
||||||
|
* because lookup_one_positive_unlocked() will hash name
|
||||||
|
* with parentpath base, which is on another (lower fs).
|
||||||
|
*/
|
||||||
this = lookup_one_positive_unlocked(
|
this = lookup_one_positive_unlocked(
|
||||||
mnt_idmap(parentpath->layer->mnt),
|
mnt_idmap(parentpath->layer->mnt),
|
||||||
name, parentpath->dentry);
|
&QSTR_LEN(name->name, name->len),
|
||||||
|
parentpath->dentry);
|
||||||
if (IS_ERR(this)) {
|
if (IS_ERR(this)) {
|
||||||
switch (PTR_ERR(this)) {
|
switch (PTR_ERR(this)) {
|
||||||
case -ENOENT:
|
case -ENOENT:
|
||||||
|
|
|
@ -246,9 +246,11 @@ static inline struct dentry *ovl_do_mkdir(struct ovl_fs *ofs,
|
||||||
struct dentry *dentry,
|
struct dentry *dentry,
|
||||||
umode_t mode)
|
umode_t mode)
|
||||||
{
|
{
|
||||||
dentry = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode);
|
struct dentry *ret;
|
||||||
pr_debug("mkdir(%pd2, 0%o) = %i\n", dentry, mode, PTR_ERR_OR_ZERO(dentry));
|
|
||||||
return dentry;
|
ret = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode);
|
||||||
|
pr_debug("mkdir(%pd2, 0%o) = %i\n", dentry, mode, PTR_ERR_OR_ZERO(ret));
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ovl_do_mknod(struct ovl_fs *ofs,
|
static inline int ovl_do_mknod(struct ovl_fs *ofs,
|
||||||
|
|
|
@ -366,7 +366,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
kinfo.pid = task_pid_vnr(task);
|
kinfo.pid = task_pid_vnr(task);
|
||||||
kinfo.mask |= PIDFD_INFO_PID;
|
kinfo.mask |= PIDFD_INFO_PID;
|
||||||
|
|
||||||
if (kinfo.pid == 0 || kinfo.tgid == 0 || (kinfo.ppid == 0 && kinfo.pid != 1))
|
if (kinfo.pid == 0 || kinfo.tgid == 0)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
copy_out:
|
copy_out:
|
||||||
|
|
|
@ -964,8 +964,10 @@ void iterate_supers_type(struct file_system_type *type,
|
||||||
spin_unlock(&sb_lock);
|
spin_unlock(&sb_lock);
|
||||||
|
|
||||||
locked = super_lock_shared(sb);
|
locked = super_lock_shared(sb);
|
||||||
if (locked)
|
if (locked) {
|
||||||
f(sb, arg);
|
f(sb, arg);
|
||||||
|
super_unlock_shared(sb);
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock(&sb_lock);
|
spin_lock(&sb_lock);
|
||||||
if (p)
|
if (p)
|
||||||
|
|
|
@ -1479,6 +1479,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
|
||||||
buffer += err;
|
buffer += err;
|
||||||
}
|
}
|
||||||
remaining_size -= err;
|
remaining_size -= err;
|
||||||
|
err = 0;
|
||||||
|
|
||||||
read_lock(&xattrs->lock);
|
read_lock(&xattrs->lock);
|
||||||
for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) {
|
for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) {
|
||||||
|
|
|
@ -399,7 +399,9 @@ struct readahead_control;
|
||||||
{ IOCB_WAITQ, "WAITQ" }, \
|
{ IOCB_WAITQ, "WAITQ" }, \
|
||||||
{ IOCB_NOIO, "NOIO" }, \
|
{ IOCB_NOIO, "NOIO" }, \
|
||||||
{ IOCB_ALLOC_CACHE, "ALLOC_CACHE" }, \
|
{ IOCB_ALLOC_CACHE, "ALLOC_CACHE" }, \
|
||||||
{ IOCB_DIO_CALLER_COMP, "CALLER_COMP" }
|
{ IOCB_DIO_CALLER_COMP, "CALLER_COMP" }, \
|
||||||
|
{ IOCB_AIO_RW, "AIO_RW" }, \
|
||||||
|
{ IOCB_HAS_METADATA, "AIO_HAS_METADATA" }
|
||||||
|
|
||||||
struct kiocb {
|
struct kiocb {
|
||||||
struct file *ki_filp;
|
struct file *ki_filp;
|
||||||
|
|
Loading…
Add table
Reference in a new issue