]> err.no Git - linux-2.6/blobdiff - kernel/futex.c
[PATCH] FUSE: pass file handle in setattr
[linux-2.6] / kernel / futex.c
index 07ba87de965874982e34df4700af381c4f08a886..aca8d10704f675cbdf35267d49bb984669c49f44 100644 (file)
@@ -205,15 +205,13 @@ static int get_futex_key(unsigned long uaddr, union futex_key *key)
        /*
         * Do a quick atomic lookup first - this is the fastpath.
         */
-       spin_lock(&current->mm->page_table_lock);
-       page = follow_page(mm, uaddr, 0);
+       page = follow_page(mm, uaddr, FOLL_TOUCH|FOLL_GET);
        if (likely(page != NULL)) {
                key->shared.pgoff =
                        page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
-               spin_unlock(&current->mm->page_table_lock);
+               put_page(page);
                return 0;
        }
-       spin_unlock(&current->mm->page_table_lock);
 
        /*
         * Do it the general way.
@@ -367,6 +365,11 @@ retry:
                if (bh1 != bh2)
                        spin_unlock(&bh2->lock);
 
+               if (unlikely(op_ret != -EFAULT)) {
+                       ret = op_ret;
+                       goto out;
+               }
+
                /* futex_atomic_op_inuser needs to both read and write
                 * *(int __user *)uaddr2, but we can't modify it
                 * non-atomically.  Therefore, if get_user below is not
@@ -786,23 +789,17 @@ static int futex_fd(unsigned long uaddr, int signal)
        filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
 
        if (signal) {
-               int err;
                err = f_setown(filp, current->pid, 1);
                if (err < 0) {
-                       put_unused_fd(ret);
-                       put_filp(filp);
-                       ret = err;
-                       goto out;
+                       goto error;
                }
                filp->f_owner.signum = signal;
        }
 
        q = kmalloc(sizeof(*q), GFP_KERNEL);
        if (!q) {
-               put_unused_fd(ret);
-               put_filp(filp);
-               ret = -ENOMEM;
-               goto out;
+               err = -ENOMEM;
+               goto error;
        }
 
        down_read(&current->mm->mmap_sem);
@@ -810,10 +807,8 @@ static int futex_fd(unsigned long uaddr, int signal)
 
        if (unlikely(err != 0)) {
                up_read(&current->mm->mmap_sem);
-               put_unused_fd(ret);
-               put_filp(filp);
                kfree(q);
-               return err;
+               goto error;
        }
 
        /*
@@ -829,6 +824,11 @@ static int futex_fd(unsigned long uaddr, int signal)
        fd_install(ret, filp);
 out:
        return ret;
+error:
+       put_unused_fd(ret);
+       put_filp(filp);
+       ret = err;
+       goto out;
 }
 
 long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout,