mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
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:
commit
27787ba3fa
@ -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;
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
10
fs/d_path.c
10
fs/d_path.c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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.. */
|
||||
|
||||
|
@ -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 = { };
|
||||
|
Loading…
Reference in New Issue
Block a user