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, really no common topic here" * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: grab the lock instead of blocking in __fd_install during resizing vfs: stop clearing close on exec when closing a fd include/linux/fs.h: fix comment about struct address_space fs: make fiemap work from compat_ioctl coda: fix 'kernel memory exposure attempt' in fsync pstore: remove unneeded unlikely() vfs: remove unneeded unlikely() stubs for mount_bdev() and kill_block_super() in !CONFIG_BLOCK case make vfs_ustat() static do_handle_open() should be static elf_fdpic: fix unused variable warning fold destroy_super() into __put_super() new helper: destroy_unused_super() fix address space warnings in ipc/ acct.h: get rid of detritus
This commit is contained in:
Коммит
ca5b857cb0
|
@ -501,10 +501,6 @@ in your dentry operations instead.
|
|||
is non-NULL. Note that link body isn't available anymore, so if you need it,
|
||||
store it as cookie.
|
||||
--
|
||||
[mandatory]
|
||||
__fd_install() & fd_install() can now sleep. Callers should not
|
||||
hold a spinlock or other resources that do not allow a schedule.
|
||||
--
|
||||
[mandatory]
|
||||
any symlink that might use page_follow_link_light/page_put_link() must
|
||||
have inode_nohighmem(inode) called before anything might start playing with
|
||||
|
|
|
@ -1498,7 +1498,9 @@ static bool elf_fdpic_dump_segments(struct coredump_params *cprm)
|
|||
struct vm_area_struct *vma;
|
||||
|
||||
for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
|
||||
#ifdef CONFIG_MMU
|
||||
unsigned long addr;
|
||||
#endif
|
||||
|
||||
if (!maydump(vma, cprm->mm_flags))
|
||||
continue;
|
||||
|
|
|
@ -447,8 +447,7 @@ int venus_fsync(struct super_block *sb, struct CodaFid *fid)
|
|||
UPARG(CODA_FSYNC);
|
||||
|
||||
inp->coda_fsync.VFid = *fid;
|
||||
error = coda_upcall(coda_vcp(sb), sizeof(union inputArgs),
|
||||
&outsize, inp);
|
||||
error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
|
||||
|
||||
CODA_FREE(inp, insize);
|
||||
return error;
|
||||
|
|
|
@ -1458,6 +1458,7 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
|
|||
case FICLONE:
|
||||
case FICLONERANGE:
|
||||
case FIDEDUPERANGE:
|
||||
case FS_IOC_FIEMAP:
|
||||
goto do_ioctl;
|
||||
|
||||
case FIBMAP:
|
||||
|
|
|
@ -213,8 +213,8 @@ out_err:
|
|||
return retval;
|
||||
}
|
||||
|
||||
long do_handle_open(int mountdirfd,
|
||||
struct file_handle __user *ufh, int open_flag)
|
||||
static long do_handle_open(int mountdirfd, struct file_handle __user *ufh,
|
||||
int open_flag)
|
||||
{
|
||||
long retval = 0;
|
||||
struct path path;
|
||||
|
|
12
fs/file.c
12
fs/file.c
|
@ -593,13 +593,16 @@ void __fd_install(struct files_struct *files, unsigned int fd,
|
|||
{
|
||||
struct fdtable *fdt;
|
||||
|
||||
might_sleep();
|
||||
rcu_read_lock_sched();
|
||||
|
||||
while (unlikely(files->resize_in_progress)) {
|
||||
if (unlikely(files->resize_in_progress)) {
|
||||
rcu_read_unlock_sched();
|
||||
wait_event(files->resize_wait, !files->resize_in_progress);
|
||||
rcu_read_lock_sched();
|
||||
spin_lock(&files->file_lock);
|
||||
fdt = files_fdtable(files);
|
||||
BUG_ON(fdt->fd[fd] != NULL);
|
||||
rcu_assign_pointer(fdt->fd[fd], file);
|
||||
spin_unlock(&files->file_lock);
|
||||
return;
|
||||
}
|
||||
/* coupled with smp_wmb() in expand_fdtable() */
|
||||
smp_rmb();
|
||||
|
@ -632,7 +635,6 @@ int __close_fd(struct files_struct *files, unsigned fd)
|
|||
if (!file)
|
||||
goto out_unlock;
|
||||
rcu_assign_pointer(fdt->fd[fd], NULL);
|
||||
__clear_close_on_exec(fd, fdt);
|
||||
__put_unused_fd(files, fd);
|
||||
spin_unlock(&files->file_lock);
|
||||
return filp_close(file, files);
|
||||
|
|
|
@ -3459,7 +3459,7 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
|
|||
goto out;
|
||||
child = vfs_tmpfile(path.dentry, op->mode, op->open_flag);
|
||||
error = PTR_ERR(child);
|
||||
if (unlikely(IS_ERR(child)))
|
||||
if (IS_ERR(child))
|
||||
goto out2;
|
||||
dput(path.dentry);
|
||||
path.dentry = child;
|
||||
|
|
|
@ -651,7 +651,7 @@ static int pstore_write_user_compat(struct pstore_record *record,
|
|||
return -EINVAL;
|
||||
|
||||
record->buf = memdup_user(buf, record->size);
|
||||
if (unlikely(IS_ERR(record->buf))) {
|
||||
if (IS_ERR(record->buf)) {
|
||||
ret = PTR_ERR(record->buf);
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user
|
|||
return error;
|
||||
}
|
||||
|
||||
int vfs_ustat(dev_t dev, struct kstatfs *sbuf)
|
||||
static int vfs_ustat(dev_t dev, struct kstatfs *sbuf)
|
||||
{
|
||||
struct super_block *s = user_get_super(dev);
|
||||
int err;
|
||||
|
|
46
fs/super.c
46
fs/super.c
|
@ -155,21 +155,19 @@ static void destroy_super_rcu(struct rcu_head *head)
|
|||
schedule_work(&s->destroy_work);
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy_super - frees a superblock
|
||||
* @s: superblock to free
|
||||
*
|
||||
* Frees a superblock.
|
||||
*/
|
||||
static void destroy_super(struct super_block *s)
|
||||
/* Free a superblock that has never been seen by anyone */
|
||||
static void destroy_unused_super(struct super_block *s)
|
||||
{
|
||||
if (!s)
|
||||
return;
|
||||
up_write(&s->s_umount);
|
||||
list_lru_destroy(&s->s_dentry_lru);
|
||||
list_lru_destroy(&s->s_inode_lru);
|
||||
security_sb_free(s);
|
||||
WARN_ON(!list_empty(&s->s_mounts));
|
||||
put_user_ns(s->s_user_ns);
|
||||
kfree(s->s_subtype);
|
||||
call_rcu(&s->rcu, destroy_super_rcu);
|
||||
/* no delays needed */
|
||||
destroy_super_work(&s->destroy_work);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,7 +255,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
|
|||
return s;
|
||||
|
||||
fail:
|
||||
destroy_super(s);
|
||||
destroy_unused_super(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -266,11 +264,17 @@ fail:
|
|||
/*
|
||||
* Drop a superblock's refcount. The caller must hold sb_lock.
|
||||
*/
|
||||
static void __put_super(struct super_block *sb)
|
||||
static void __put_super(struct super_block *s)
|
||||
{
|
||||
if (!--sb->s_count) {
|
||||
list_del_init(&sb->s_list);
|
||||
destroy_super(sb);
|
||||
if (!--s->s_count) {
|
||||
list_del_init(&s->s_list);
|
||||
WARN_ON(s->s_dentry_lru.node);
|
||||
WARN_ON(s->s_inode_lru.node);
|
||||
WARN_ON(!list_empty(&s->s_mounts));
|
||||
security_sb_free(s);
|
||||
put_user_ns(s->s_user_ns);
|
||||
kfree(s->s_subtype);
|
||||
call_rcu(&s->rcu, destroy_super_rcu);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,19 +489,12 @@ retry:
|
|||
continue;
|
||||
if (user_ns != old->s_user_ns) {
|
||||
spin_unlock(&sb_lock);
|
||||
if (s) {
|
||||
up_write(&s->s_umount);
|
||||
destroy_super(s);
|
||||
}
|
||||
destroy_unused_super(s);
|
||||
return ERR_PTR(-EBUSY);
|
||||
}
|
||||
if (!grab_super(old))
|
||||
goto retry;
|
||||
if (s) {
|
||||
up_write(&s->s_umount);
|
||||
destroy_super(s);
|
||||
s = NULL;
|
||||
}
|
||||
destroy_unused_super(s);
|
||||
return old;
|
||||
}
|
||||
}
|
||||
|
@ -512,8 +509,7 @@ retry:
|
|||
err = set(s, data);
|
||||
if (err) {
|
||||
spin_unlock(&sb_lock);
|
||||
up_write(&s->s_umount);
|
||||
destroy_super(s);
|
||||
destroy_unused_super(s);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
s->s_type = type;
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
|
||||
|
||||
#ifdef CONFIG_BSD_PROCESS_ACCT
|
||||
struct vfsmount;
|
||||
struct super_block;
|
||||
struct pacct_struct;
|
||||
struct pid_namespace;
|
||||
extern int acct_parm[]; /* for sysctl */
|
||||
extern void acct_collect(long exitcode, int group_dead);
|
||||
|
|
|
@ -2098,9 +2098,18 @@ struct file_system_type {
|
|||
extern struct dentry *mount_ns(struct file_system_type *fs_type,
|
||||
int flags, void *data, void *ns, struct user_namespace *user_ns,
|
||||
int (*fill_super)(struct super_block *, void *, int));
|
||||
#ifdef CONFIG_BLOCK
|
||||
extern struct dentry *mount_bdev(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *data,
|
||||
int (*fill_super)(struct super_block *, void *, int));
|
||||
#else
|
||||
static inline struct dentry *mount_bdev(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *data,
|
||||
int (*fill_super)(struct super_block *, void *, int))
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
#endif
|
||||
extern struct dentry *mount_single(struct file_system_type *fs_type,
|
||||
int flags, void *data,
|
||||
int (*fill_super)(struct super_block *, void *, int));
|
||||
|
@ -2109,7 +2118,14 @@ extern struct dentry *mount_nodev(struct file_system_type *fs_type,
|
|||
int (*fill_super)(struct super_block *, void *, int));
|
||||
extern struct dentry *mount_subtree(struct vfsmount *mnt, const char *path);
|
||||
void generic_shutdown_super(struct super_block *sb);
|
||||
#ifdef CONFIG_BLOCK
|
||||
void kill_block_super(struct super_block *sb);
|
||||
#else
|
||||
static inline void kill_block_super(struct super_block *sb)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
#endif
|
||||
void kill_anon_super(struct super_block *sb);
|
||||
void kill_litter_super(struct super_block *sb);
|
||||
void deactivate_super(struct super_block *sb);
|
||||
|
@ -2173,7 +2189,6 @@ extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
|
|||
extern int vfs_statfs(const struct path *, struct kstatfs *);
|
||||
extern int user_statfs(const char __user *, struct kstatfs *);
|
||||
extern int fd_statfs(int, struct kstatfs *);
|
||||
extern int vfs_ustat(dev_t, struct kstatfs *);
|
||||
extern int freeze_super(struct super_block *super);
|
||||
extern int thaw_super(struct super_block *super);
|
||||
extern bool our_mnt(struct vfsmount *mnt);
|
||||
|
|
|
@ -591,13 +591,13 @@ static int copy_compat_msqid_from_user(struct msqid64_ds *out, void __user *buf,
|
|||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
if (version == IPC_64) {
|
||||
struct compat_msqid64_ds *p = buf;
|
||||
struct compat_msqid64_ds __user *p = buf;
|
||||
if (get_compat_ipc64_perm(&out->msg_perm, &p->msg_perm))
|
||||
return -EFAULT;
|
||||
if (get_user(out->msg_qbytes, &p->msg_qbytes))
|
||||
return -EFAULT;
|
||||
} else {
|
||||
struct compat_msqid_ds *p = buf;
|
||||
struct compat_msqid_ds __user *p = buf;
|
||||
if (get_compat_ipc_perm(&out->msg_perm, &p->msg_perm))
|
||||
return -EFAULT;
|
||||
if (get_user(out->msg_qbytes, &p->msg_qbytes))
|
||||
|
|
|
@ -1637,10 +1637,10 @@ static int copy_compat_semid_from_user(struct semid64_ds *out, void __user *buf,
|
|||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
if (version == IPC_64) {
|
||||
struct compat_semid64_ds *p = buf;
|
||||
struct compat_semid64_ds __user *p = buf;
|
||||
return get_compat_ipc64_perm(&out->sem_perm, &p->sem_perm);
|
||||
} else {
|
||||
struct compat_semid_ds *p = buf;
|
||||
struct compat_semid_ds __user *p = buf;
|
||||
return get_compat_ipc_perm(&out->sem_perm, &p->sem_perm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1194,10 +1194,10 @@ static int copy_compat_shmid_from_user(struct shmid64_ds *out, void __user *buf,
|
|||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
if (version == IPC_64) {
|
||||
struct compat_shmid64_ds *p = buf;
|
||||
struct compat_shmid64_ds __user *p = buf;
|
||||
return get_compat_ipc64_perm(&out->shm_perm, &p->shm_perm);
|
||||
} else {
|
||||
struct compat_shmid_ds *p = buf;
|
||||
struct compat_shmid_ds __user *p = buf;
|
||||
return get_compat_ipc_perm(&out->shm_perm, &p->shm_perm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
|
|||
COMPAT_SHMLBA);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return put_user(raddr, (compat_ulong_t *)compat_ptr(third));
|
||||
return put_user(raddr, (compat_ulong_t __user *)compat_ptr(third));
|
||||
}
|
||||
case SHMDT:
|
||||
return sys_shmdt(compat_ptr(ptr));
|
||||
|
|
Загрузка…
Ссылка в новой задаче