]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 20:54:01 +0000 (12:54 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 20:54:01 +0000 (12:54 -0800)
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

16 files changed:
Documentation/filesystems/porting
fs/binfmt_elf_fdpic.c
fs/coda/upcall.c
fs/compat_ioctl.c
fs/fhandle.c
fs/file.c
fs/namei.c
fs/pstore/platform.c
fs/statfs.c
fs/super.c
include/linux/acct.h
include/linux/fs.h
ipc/msg.c
ipc/sem.c
ipc/shm.c
ipc/syscall.c

index 93e0a24045322b3e2417e024821520c9996eb6fc..17bb4dc28fae03371c328cc2135b576c4235ab03 100644 (file)
@@ -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
index 5429b035e249bfb6eb0d7887ccca0353535af952..429326b6e2e7088dc1c67c770122beb7b004152b 100644 (file)
@@ -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;
index a37f003530d7353ca1ae4b37ea8c7f8c2c3a9261..1175a1722411d353624c8b1548f054c5b13fc520 100644 (file)
@@ -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;
index f95aa0b2e9c03f83152c8c74c71a6a8d474ba343..5fc5dc66060052af88730f3608b1930a397a412d 100644 (file)
@@ -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:
index 474adc8d2a3aa5bb7c34913f38e347c604ede26f..0ace128f5d238c6b3a97cc628f14a21548dafaeb 100644 (file)
@@ -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;
index 4eecbf4244a5242df38816c7c9bfedbcf3e75313..3b080834b8704d6f931fe73cdd3c18c1a8d95d67 100644 (file)
--- a/fs/file.c
+++ b/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);
index 287781363763bb8c132ba147ce721e08db68b795..f0c7a7b9b6ca7562217746369cd8d5d82d43a99f 100644 (file)
@@ -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;
index 086e491faf04b655e4fdf2903b105a984e788f04..423159abd50182812656c6f73e421da272187670 100644 (file)
@@ -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;
        }
index c25dd9a26cc1c7c3810c398c1b4bc70e27a6d1d8..b072a8bab71a1464d3d06d9017a2a33d441e0ef9 100644 (file)
@@ -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;
index 994db21f59bf58d3f83d750f8524d1c35849706b..d4e33e8f1e6fee3172e0e07e9d358587eea34bc4 100644 (file)
@@ -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;
index 18e1955f81f59eaefdff0dad9ac19726426c6201..bc70e81895c097839871ec6e3e36337972c01875 100644 (file)
@@ -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);
index a2b5d64ea50378dab29938f96315bfc399cb3967..e9379e258d6464587bd25b31edaf62856c44b96d 100644 (file)
@@ -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);
index bce7ac1c809998762aab36fc84cf8c431184403c..1bbc029d2b17db2a039e1bd5ac1701720251f010 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -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))
index b2698ebdcb31e65ea2f3e94f64cc567607b8ca2a..a5cff0e109ab5a56fbbd3286cf96e625e99c1b53 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -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);
        }
 }
index bd652755d32cc6fee7598b7a8dc257bd65e0c807..7733d768666d557ca08e66ca28986f348b8d6b8b 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -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);
        }
 }
index 26b45db2e007325a4303e6edcebf75afe3991d58..3763b4293b74f7bb7f20e385da70b6168f0bd163 100644 (file)
@@ -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));