Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull misc vfs updates from Al Viro:
 "Assorted stuff all over the place"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  useful constants: struct qstr for ".."
  hostfs_open(): don't open-code file_dentry()
  whack-a-mole: kill strlen_user() (again)
  autofs: should_expire() argument is guaranteed to be positive
  apparmor:match_mn() - constify devpath argument
  buffer: a small optimization in grow_buffers
  get rid of autofs_getpath()
  constify dentry argument of dentry_path()/dentry_path_raw()
This commit is contained in:
Linus Torvalds 2021-05-02 09:14:01 -07:00
commit 27787ba3fa
22 changed files with 41 additions and 95 deletions

View File

@ -397,8 +397,6 @@ long __strncpy_from_user(char *dst, const char *src, long count);
*/
long strnlen_user(const char *src, long n);
#define strlen_user(str) strnlen_user(str, 32767)
struct exception_table_entry {
unsigned long insn;
unsigned long nextinsn;

View File

@ -116,7 +116,7 @@ long strncpy_from_user(char *dst, const char *src, long count)
EXPORT_SYMBOL(strncpy_from_user);
/*
* strlen_user: - Get the size of a string in user space.
* strnlen_user: - Get the size of a string in user space.
* @str: The string to measure.
* @n: The maximum valid length
*

View File

@ -260,7 +260,6 @@ do { \
extern unsigned long __arch_clear_user(void __user * addr, unsigned long n);
extern long strncpy_from_user(char *dest, const char __user * src, long count);
extern __must_check long strlen_user(const char __user * str);
extern __must_check long strnlen_user(const char __user * str, long n);
extern unsigned long __arch_copy_from_user(void *to, const void __user * from,
unsigned long n);

View File

@ -83,7 +83,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n);
extern long strncpy_from_user(char *__to, const char __user *__from,
long __len);
extern __must_check long strlen_user(const char __user *str);
extern __must_check long strnlen_user(const char __user *s, long n);
/* Optimized macros */

View File

@ -375,7 +375,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
extern long strncpy_from_user(char *dest, const char __user *src, long count);
extern long __must_check strlen_user(const char __user *str);
extern long __must_check strnlen_user(const char __user *str, long n);
extern

View File

@ -87,6 +87,7 @@ struct autofs_wait_queue {
autofs_wqt_t wait_queue_token;
/* We use the following to see what we are waiting for */
struct qstr name;
u32 offset;
u32 dev;
u64 ino;
kuid_t uid;

View File

@ -355,7 +355,7 @@ static struct dentry *should_expire(struct dentry *dentry,
return NULL;
}
if (d_really_is_positive(dentry) && d_is_symlink(dentry)) {
if (d_is_symlink(dentry)) {
pr_debug("checking symlink %p %pd\n", dentry, dentry);
/* Forced expire, user space handles busy mounts */

View File

@ -30,7 +30,7 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi)
while (wq) {
nwq = wq->next;
wq->status = -ENOENT; /* Magic is gone - report failure */
kfree(wq->name.name);
kfree(wq->name.name - wq->offset);
wq->name.name = NULL;
wq->wait_ctr--;
wake_up_interruptible(&wq->queue);
@ -175,51 +175,6 @@ static void autofs_notify_daemon(struct autofs_sb_info *sbi,
fput(pipe);
}
static int autofs_getpath(struct autofs_sb_info *sbi,
struct dentry *dentry, char *name)
{
struct dentry *root = sbi->sb->s_root;
struct dentry *tmp;
char *buf;
char *p;
int len;
unsigned seq;
rename_retry:
buf = name;
len = 0;
seq = read_seqbegin(&rename_lock);
rcu_read_lock();
spin_lock(&sbi->fs_lock);
for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
len += tmp->d_name.len + 1;
if (!len || --len > NAME_MAX) {
spin_unlock(&sbi->fs_lock);
rcu_read_unlock();
if (read_seqretry(&rename_lock, seq))
goto rename_retry;
return 0;
}
*(buf + len) = '\0';
p = buf + len - dentry->d_name.len;
strncpy(p, dentry->d_name.name, dentry->d_name.len);
for (tmp = dentry->d_parent; tmp != root ; tmp = tmp->d_parent) {
*(--p) = '/';
p -= tmp->d_name.len;
strncpy(p, tmp->d_name.name, tmp->d_name.len);
}
spin_unlock(&sbi->fs_lock);
rcu_read_unlock();
if (read_seqretry(&rename_lock, seq))
goto rename_retry;
return len;
}
static struct autofs_wait_queue *
autofs_find_wait(struct autofs_sb_info *sbi, const struct qstr *qstr)
{
@ -352,6 +307,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
struct qstr qstr;
char *name;
int status, ret, type;
unsigned int offset = 0;
pid_t pid;
pid_t tgid;
@ -389,20 +345,23 @@ int autofs_wait(struct autofs_sb_info *sbi,
return -ENOMEM;
/* If this is a direct mount request create a dummy name */
if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type))
if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type)) {
qstr.name = name;
qstr.len = sprintf(name, "%p", dentry);
else {
qstr.len = autofs_getpath(sbi, dentry, name);
if (!qstr.len) {
} else {
char *p = dentry_path_raw(dentry, name, NAME_MAX);
if (IS_ERR(p)) {
kfree(name);
return -ENOENT;
}
qstr.name = ++p; // skip the leading slash
qstr.len = strlen(p);
offset = p - name;
}
qstr.name = name;
qstr.hash = full_name_hash(dentry, name, qstr.len);
if (mutex_lock_interruptible(&sbi->wq_mutex)) {
kfree(qstr.name);
kfree(name);
return -EINTR;
}
@ -410,7 +369,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
if (ret <= 0) {
if (ret != -EINTR)
mutex_unlock(&sbi->wq_mutex);
kfree(qstr.name);
kfree(name);
return ret;
}
@ -418,7 +377,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
/* Create a new wait queue */
wq = kmalloc(sizeof(struct autofs_wait_queue), GFP_KERNEL);
if (!wq) {
kfree(qstr.name);
kfree(name);
mutex_unlock(&sbi->wq_mutex);
return -ENOMEM;
}
@ -430,6 +389,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
sbi->queues = wq;
init_waitqueue_head(&wq->queue);
memcpy(&wq->name, &qstr, sizeof(struct qstr));
wq->offset = offset;
wq->dev = autofs_get_dev(sbi);
wq->ino = autofs_get_ino(sbi);
wq->uid = current_uid();
@ -469,7 +429,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
(unsigned long) wq->wait_queue_token, wq->name.len,
wq->name.name, notify);
mutex_unlock(&sbi->wq_mutex);
kfree(qstr.name);
kfree(name);
}
/*
@ -540,7 +500,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi,
}
*wql = wq->next; /* Unlink from chain */
kfree(wq->name.name);
kfree(wq->name.name - wq->offset);
wq->name.name = NULL; /* Do not wait on this queue */
wq->status = status;
wake_up(&wq->queue);

View File

@ -1020,11 +1020,7 @@ grow_buffers(struct block_device *bdev, sector_t block, int size, gfp_t gfp)
pgoff_t index;
int sizebits;
sizebits = -1;
do {
sizebits++;
} while ((size << sizebits) < PAGE_SIZE);
sizebits = PAGE_SHIFT - __ffs(size);
index = block >> sizebits;
/*

View File

@ -326,9 +326,9 @@ char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
/*
* Write full pathname from the root of the filesystem into the buffer.
*/
static char *__dentry_path(struct dentry *d, char *buf, int buflen)
static char *__dentry_path(const struct dentry *d, char *buf, int buflen)
{
struct dentry *dentry;
const struct dentry *dentry;
char *end, *retval;
int len, seq = 0;
int error = 0;
@ -347,7 +347,7 @@ restart:
*retval = '/';
read_seqbegin_or_lock(&rename_lock, &seq);
while (!IS_ROOT(dentry)) {
struct dentry *parent = dentry->d_parent;
const struct dentry *parent = dentry->d_parent;
prefetch(parent);
error = prepend_name(&end, &len, &dentry->d_name);
@ -371,13 +371,13 @@ Elong:
return ERR_PTR(-ENAMETOOLONG);
}
char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
char *dentry_path_raw(const struct dentry *dentry, char *buf, int buflen)
{
return __dentry_path(dentry, buf, buflen);
}
EXPORT_SYMBOL(dentry_path_raw);
char *dentry_path(struct dentry *dentry, char *buf, int buflen)
char *dentry_path(const struct dentry *dentry, char *buf, int buflen)
{
char *p = NULL;
char *retval;

View File

@ -84,6 +84,8 @@ const struct qstr empty_name = QSTR_INIT("", 0);
EXPORT_SYMBOL(empty_name);
const struct qstr slash_name = QSTR_INIT("/", 1);
EXPORT_SYMBOL(slash_name);
const struct qstr dotdot_name = QSTR_INIT("..", 2);
EXPORT_SYMBOL(dotdot_name);
/*
* This is the single most critical data structure when it comes

View File

@ -81,11 +81,10 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, uns
struct dentry *ext2_get_parent(struct dentry *child)
{
struct qstr dotdot = QSTR_INIT("..", 2);
ino_t ino;
int res;
res = ext2_inode_by_name(d_inode(child), &dotdot, &ino);
res = ext2_inode_by_name(d_inode(child), &dotdot_name, &ino);
if (res)
return ERR_PTR(res);

View File

@ -1814,11 +1814,10 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
struct dentry *ext4_get_parent(struct dentry *child)
{
__u32 ino;
static const struct qstr dotdot = QSTR_INIT("..", 2);
struct ext4_dir_entry_2 * de;
struct buffer_head *bh;
bh = ext4_find_entry(d_inode(child), &dotdot, &de, NULL);
bh = ext4_find_entry(d_inode(child), &dotdot_name, &de, NULL);
if (IS_ERR(bh))
return ERR_CAST(bh);
if (!bh)

View File

@ -449,9 +449,7 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p)
{
struct qstr dotdot = QSTR_INIT("..", 2);
return f2fs_find_entry(dir, &dotdot, p);
return f2fs_find_entry(dir, &dotdot_name, p);
}
ino_t f2fs_inode_by_name(struct inode *dir, const struct qstr *qstr,

View File

@ -416,9 +416,8 @@ out:
struct dentry *f2fs_get_parent(struct dentry *child)
{
struct qstr dotdot = QSTR_INIT("..", 2);
struct page *page;
unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot, &page);
unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot_name, &page);
if (!ino) {
if (IS_ERR(page))
return ERR_CAST(page);

View File

@ -873,14 +873,13 @@ static struct dentry *fuse_get_parent(struct dentry *child)
struct inode *inode;
struct dentry *parent;
struct fuse_entry_out outarg;
const struct qstr name = QSTR_INIT("..", 2);
int err;
if (!fc->export_support)
return ERR_PTR(-ESTALE);
err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode),
&name, &outarg, &inode);
&dotdot_name, &outarg, &inode);
if (err) {
if (err == -ENOENT)
return ERR_PTR(-ESTALE);

View File

@ -316,7 +316,7 @@ retry:
if (mode & FMODE_WRITE)
r = w = 1;
name = dentry_name(d_real(file->f_path.dentry, file->f_inode));
name = dentry_name(file_dentry(file));
if (name == NULL)
return -ENOMEM;

View File

@ -440,10 +440,9 @@ static struct dentry *nilfs_get_parent(struct dentry *child)
{
unsigned long ino;
struct inode *inode;
struct qstr dotdot = QSTR_INIT("..", 2);
struct nilfs_root *root;
ino = nilfs_inode_by_name(d_inode(child), &dotdot);
ino = nilfs_inode_by_name(d_inode(child), &dotdot_name);
if (!ino)
return ERR_PTR(-ENOENT);

View File

@ -1215,11 +1215,10 @@ static struct dentry *udf_get_parent(struct dentry *child)
{
struct kernel_lb_addr tloc;
struct inode *inode = NULL;
struct qstr dotdot = QSTR_INIT("..", 2);
struct fileIdentDesc cfi;
struct udf_fileident_bh fibh;
if (!udf_find_entry(d_inode(child), &dotdot, &fibh, &cfi))
if (!udf_find_entry(d_inode(child), &dotdot_name, &fibh, &cfi))
return ERR_PTR(-EACCES);
if (fibh.sbh != fibh.ebh)

View File

@ -128,10 +128,9 @@ static struct dentry *ufs_fh_to_parent(struct super_block *sb, struct fid *fid,
static struct dentry *ufs_get_parent(struct dentry *child)
{
struct qstr dot_dot = QSTR_INIT("..", 2);
ino_t ino;
ino = ufs_inode_by_name(d_inode(child), &dot_dot);
ino = ufs_inode_by_name(d_inode(child), &dotdot_name);
if (!ino)
return ERR_PTR(-ENOENT);
return d_obtain_alias(ufs_iget(child->d_sb, ino));

View File

@ -59,6 +59,7 @@ struct qstr {
extern const struct qstr empty_name;
extern const struct qstr slash_name;
extern const struct qstr dotdot_name;
struct dentry_stat_t {
long nr_dentry;
@ -300,8 +301,8 @@ char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
extern char *__d_path(const struct path *, const struct path *, char *, int);
extern char *d_absolute_path(const struct path *, char *, int);
extern char *d_path(const struct path *, char *, int);
extern char *dentry_path_raw(struct dentry *, char *, int);
extern char *dentry_path(struct dentry *, char *, int);
extern char *dentry_path_raw(const struct dentry *, char *, int);
extern char *dentry_path(const struct dentry *, char *, int);
/* Allocation counts.. */

View File

@ -370,7 +370,7 @@ audit:
* Returns: 0 on success else error
*/
static int match_mnt(struct aa_profile *profile, const struct path *path,
char *buffer, struct path *devpath, char *devbuffer,
char *buffer, const struct path *devpath, char *devbuffer,
const char *type, unsigned long flags, void *data,
bool binary)
{
@ -579,7 +579,7 @@ out:
return error;
}
static int profile_umount(struct aa_profile *profile, struct path *path,
static int profile_umount(struct aa_profile *profile, const struct path *path,
char *buffer)
{
struct aa_perms perms = { };