]> Pileus Git - ~andy/linux/commitdiff
Merge tag 'stable/for-linus-3.14-rc8-tag' of git://git.kernel.org/pub/scm/linux/kerne...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Mar 2014 17:52:05 +0000 (10:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Mar 2014 17:52:05 +0000 (10:52 -0700)
Pull Xen bugfixes from David Vrabel:
 "Fix two bugs that cause x86 PV guest crashes.

  1. Ballooning a 32-bit guest would eventually crash it.

  2. Revert a broken fix for a regression with NUMA_BALACING.  The bad
     fix caused PV guests to crash after migration.  This is not ideal
     but unpicking the madness that is _PAGE_NUMA == _PAGE_PROTNONE will
     take a while longer"

* tag 'stable/for-linus-3.14-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  Revert "xen: properly account for _PAGE_NUMA during xen pte translations"
  xen/balloon: flush persistent kmaps in correct position

fs/anon_inodes.c
fs/dcache.c
fs/file.c
fs/namei.c
fs/nfsd/vfs.c
fs/read_write.c
kernel/trace/trace.c

index 24084732b1d0b264b5c3262796f1ec3dd5fc505f..80ef38c73e5a16af0f9443d94bec3aae700370df 100644 (file)
@@ -41,19 +41,8 @@ static const struct dentry_operations anon_inodefs_dentry_operations = {
 static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
                                int flags, const char *dev_name, void *data)
 {
-       struct dentry *root;
-       root = mount_pseudo(fs_type, "anon_inode:", NULL,
+       return mount_pseudo(fs_type, "anon_inode:", NULL,
                        &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
-       if (!IS_ERR(root)) {
-               struct super_block *s = root->d_sb;
-               anon_inode_inode = alloc_anon_inode(s);
-               if (IS_ERR(anon_inode_inode)) {
-                       dput(root);
-                       deactivate_locked_super(s);
-                       root = ERR_CAST(anon_inode_inode);
-               }
-       }
-       return root;
 }
 
 static struct file_system_type anon_inode_fs_type = {
@@ -175,22 +164,15 @@ EXPORT_SYMBOL_GPL(anon_inode_getfd);
 
 static int __init anon_inode_init(void)
 {
-       int error;
-
-       error = register_filesystem(&anon_inode_fs_type);
-       if (error)
-               goto err_exit;
        anon_inode_mnt = kern_mount(&anon_inode_fs_type);
-       if (IS_ERR(anon_inode_mnt)) {
-               error = PTR_ERR(anon_inode_mnt);
-               goto err_unregister_filesystem;
-       }
-       return 0;
+       if (IS_ERR(anon_inode_mnt))
+               panic("anon_inode_init() kernel mount failed (%ld)\n", PTR_ERR(anon_inode_mnt));
 
-err_unregister_filesystem:
-       unregister_filesystem(&anon_inode_fs_type);
-err_exit:
-       panic(KERN_ERR "anon_inode_init() failed (%d)\n", error);
+       anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
+       if (IS_ERR(anon_inode_inode))
+               panic("anon_inode_init() inode allocation failed (%ld)\n", PTR_ERR(anon_inode_inode));
+
+       return 0;
 }
 
 fs_initcall(anon_inode_init);
index 265e0ce9769c70db65d5f9df11c4365f44c6dd29..ca02c13a84aa24d55b18bbced577ece923605665 100644 (file)
@@ -2833,9 +2833,9 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
        u32 dlen = ACCESS_ONCE(name->len);
        char *p;
 
-       if (*buflen < dlen + 1)
-               return -ENAMETOOLONG;
        *buflen -= dlen + 1;
+       if (*buflen < 0)
+               return -ENAMETOOLONG;
        p = *buffer -= dlen + 1;
        *p++ = '/';
        while (dlen--) {
index 60a45e9f53231379c87b9ee75cb64eb8d6d71979..eb56a13dab3ed5561a9521b2b2d1a6000a7158a3 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -713,27 +713,16 @@ unsigned long __fdget_raw(unsigned int fd)
 
 unsigned long __fdget_pos(unsigned int fd)
 {
-       struct files_struct *files = current->files;
-       struct file *file;
-       unsigned long v;
-
-       if (atomic_read(&files->count) == 1) {
-               file = __fcheck_files(files, fd);
-               v = 0;
-       } else {
-               file = __fget(fd, 0);
-               v = FDPUT_FPUT;
-       }
-       if (!file)
-               return 0;
+       unsigned long v = __fdget(fd);
+       struct file *file = (struct file *)(v & ~3);
 
-       if (file->f_mode & FMODE_ATOMIC_POS) {
+       if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
                if (file_count(file) > 1) {
                        v |= FDPUT_POS_UNLOCK;
                        mutex_lock(&file->f_pos_lock);
                }
        }
-       return v | (unsigned long)file;
+       return v;
 }
 
 /*
index 2f730ef9b4b3da78afd6a830c13c7ba13c706ffe..4b491b4319905b2dd6698d3f58aae1d0d0141499 100644 (file)
@@ -1109,7 +1109,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
                        return false;
 
                if (!d_mountpoint(path->dentry))
-                       break;
+                       return true;
 
                mounted = __lookup_mnt(path->mnt, path->dentry);
                if (!mounted)
@@ -1125,20 +1125,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
                 */
                *inode = path->dentry->d_inode;
        }
-       return true;
-}
-
-static void follow_mount_rcu(struct nameidata *nd)
-{
-       while (d_mountpoint(nd->path.dentry)) {
-               struct mount *mounted;
-               mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
-               if (!mounted)
-                       break;
-               nd->path.mnt = &mounted->mnt;
-               nd->path.dentry = mounted->mnt.mnt_root;
-               nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
-       }
+       return read_seqretry(&mount_lock, nd->m_seq);
 }
 
 static int follow_dotdot_rcu(struct nameidata *nd)
@@ -1166,7 +1153,17 @@ static int follow_dotdot_rcu(struct nameidata *nd)
                        break;
                nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
        }
-       follow_mount_rcu(nd);
+       while (d_mountpoint(nd->path.dentry)) {
+               struct mount *mounted;
+               mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
+               if (!mounted)
+                       break;
+               nd->path.mnt = &mounted->mnt;
+               nd->path.dentry = mounted->mnt.mnt_root;
+               nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
+               if (!read_seqretry(&mount_lock, nd->m_seq))
+                       goto failed;
+       }
        nd->inode = nd->path.dentry->d_inode;
        return 0;
 
index 017d3cb5e99b4391027fe37b7c56c23966754e2d..6d7be3f8035631cb207a5733c71dbfc2f800fa4c 100644 (file)
@@ -449,6 +449,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
        fh_lock(fhp);
        host_err = notify_change(dentry, iap, NULL);
        fh_unlock(fhp);
+       err = nfserrno(host_err);
 
 out_put_write_access:
        if (size_change)
index 54e19b9392dc74381fec154fe3f0ceab32ce9bd8..28cc9c810744a748d3a071b536c36547be87aa14 100644 (file)
@@ -307,7 +307,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
                unsigned int, whence)
 {
        int retval;
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        loff_t offset;
 
        if (!f.file)
@@ -327,7 +327,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
                        retval = 0;
        }
 out_putf:
-       fdput(f);
+       fdput_pos(f);
        return retval;
 }
 #endif
index 815c878f409bd94e08777d1b9f83b1553f4a2e24..24c1f23825579df4f2bf46e2dca98e6af8fb4abd 100644 (file)
@@ -1600,15 +1600,31 @@ void trace_buffer_unlock_commit(struct ring_buffer *buffer,
 }
 EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit);
 
+static struct ring_buffer *temp_buffer;
+
 struct ring_buffer_event *
 trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
                          struct ftrace_event_file *ftrace_file,
                          int type, unsigned long len,
                          unsigned long flags, int pc)
 {
+       struct ring_buffer_event *entry;
+
        *current_rb = ftrace_file->tr->trace_buffer.buffer;
-       return trace_buffer_lock_reserve(*current_rb,
+       entry = trace_buffer_lock_reserve(*current_rb,
                                         type, len, flags, pc);
+       /*
+        * If tracing is off, but we have triggers enabled
+        * we still need to look at the event data. Use the temp_buffer
+        * to store the trace event for the tigger to use. It's recusive
+        * safe and will not be recorded anywhere.
+        */
+       if (!entry && ftrace_file->flags & FTRACE_EVENT_FL_TRIGGER_COND) {
+               *current_rb = temp_buffer;
+               entry = trace_buffer_lock_reserve(*current_rb,
+                                                 type, len, flags, pc);
+       }
+       return entry;
 }
 EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve);
 
@@ -6494,11 +6510,16 @@ __init static int tracer_alloc_buffers(void)
 
        raw_spin_lock_init(&global_trace.start_lock);
 
+       /* Used for event triggers */
+       temp_buffer = ring_buffer_alloc(PAGE_SIZE, RB_FL_OVERWRITE);
+       if (!temp_buffer)
+               goto out_free_cpumask;
+
        /* TODO: make the number of buffers hot pluggable with CPUS */
        if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
                printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
                WARN_ON(1);
-               goto out_free_cpumask;
+               goto out_free_temp_buffer;
        }
 
        if (global_trace.buffer_disabled)
@@ -6540,6 +6561,8 @@ __init static int tracer_alloc_buffers(void)
 
        return 0;
 
+out_free_temp_buffer:
+       ring_buffer_free(temp_buffer);
 out_free_cpumask:
        free_percpu(global_trace.trace_buffer.data);
 #ifdef CONFIG_TRACER_MAX_TRACE