]> err.no Git - linux-2.6/blobdiff - kernel/futex.c
[PATCH] proc: Rewrite the proc dentry flush on exit optimization
[linux-2.6] / kernel / futex.c
index feb724b2554efe19a9d9b830c7b957162203e890..e1a380c77a5a2ac947f4fceee190fa7518488f41 100644 (file)
@@ -913,15 +913,15 @@ err_unlock:
  * Process a futex-list entry, check whether it's owned by the
  * dying task, and do notification if so:
  */
-int handle_futex_death(unsigned int *uaddr, struct task_struct *curr)
+int handle_futex_death(u32 __user *uaddr, struct task_struct *curr)
 {
-       unsigned int futex_val;
+       u32 uval;
 
-repeat:
-       if (get_user(futex_val, uaddr))
+retry:
+       if (get_user(uval, uaddr))
                return -1;
 
-       if ((futex_val & FUTEX_TID_MASK) == curr->pid) {
+       if ((uval & FUTEX_TID_MASK) == curr->pid) {
                /*
                 * Ok, this dying thread is truly holding a futex
                 * of interest. Set the OWNER_DIED bit atomically
@@ -932,12 +932,11 @@ repeat:
                 * thread-death.) The rest of the cleanup is done in
                 * userspace.
                 */
-               if (futex_atomic_cmpxchg_inuser(uaddr, futex_val,
-                                        futex_val | FUTEX_OWNER_DIED) !=
-                                                                  futex_val)
-                       goto repeat;
+               if (futex_atomic_cmpxchg_inatomic(uaddr, uval,
+                                        uval | FUTEX_OWNER_DIED) != uval)
+                       goto retry;
 
-               if (futex_val & FUTEX_WAITERS)
+               if (uval & FUTEX_WAITERS)
                        futex_wake((unsigned long)uaddr, 1);
        }
        return 0;
@@ -985,7 +984,6 @@ void exit_robust_list(struct task_struct *curr)
                        if (handle_futex_death((void *)entry + futex_offset,
                                                curr))
                                return;
-
                /*
                 * Fetch the next entry in the list:
                 */
@@ -1041,9 +1039,11 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
        unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
        int val2 = 0;
 
-       if ((op == FUTEX_WAIT) && utime) {
+       if (utime && (op == FUTEX_WAIT)) {
                if (copy_from_user(&t, utime, sizeof(t)) != 0)
                        return -EFAULT;
+               if (!timespec_valid(&t))
+                       return -EINVAL;
                timeout = timespec_to_jiffies(&t) + 1;
        }
        /*
@@ -1056,11 +1056,11 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
                        (unsigned long)uaddr2, val2, val3);
 }
 
-static struct super_block *
-futexfs_get_sb(struct file_system_type *fs_type,
-              int flags, const char *dev_name, void *data)
+static int futexfs_get_sb(struct file_system_type *fs_type,
+                         int flags, const char *dev_name, void *data,
+                         struct vfsmount *mnt)
 {
-       return get_sb_pseudo(fs_type, "futex", NULL, 0xBAD1DEA);
+       return get_sb_pseudo(fs_type, "futex", NULL, 0xBAD1DEA, mnt);
 }
 
 static struct file_system_type futex_fs_type = {