Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.git] / fs / namespace.c
index 725d6935fab9f8fb7d80d225b9af52331c702b34..d86830c86ce8199ab0772f146f0a85377a441f92 100644 (file)
@@ -61,9 +61,6 @@ __setup("mphash_entries=", set_mphash_entries);
 static u64 event;
 static DEFINE_IDA(mnt_id_ida);
 static DEFINE_IDA(mnt_group_ida);
-static DEFINE_SPINLOCK(mnt_id_lock);
-static int mnt_id_start = 0;
-static int mnt_group_start = 1;
 
 static struct hlist_head *mount_hashtable __read_mostly;
 static struct hlist_head *mountpoint_hashtable __read_mostly;
@@ -101,50 +98,30 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry)
 
 static int mnt_alloc_id(struct mount *mnt)
 {
-       int res;
+       int res = ida_alloc(&mnt_id_ida, GFP_KERNEL);
 
-retry:
-       ida_pre_get(&mnt_id_ida, GFP_KERNEL);
-       spin_lock(&mnt_id_lock);
-       res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
-       if (!res)
-               mnt_id_start = mnt->mnt_id + 1;
-       spin_unlock(&mnt_id_lock);
-       if (res == -EAGAIN)
-               goto retry;
-
-       return res;
+       if (res < 0)
+               return res;
+       mnt->mnt_id = res;
+       return 0;
 }
 
 static void mnt_free_id(struct mount *mnt)
 {
-       int id = mnt->mnt_id;
-       spin_lock(&mnt_id_lock);
-       ida_remove(&mnt_id_ida, id);
-       if (mnt_id_start > id)
-               mnt_id_start = id;
-       spin_unlock(&mnt_id_lock);
+       ida_free(&mnt_id_ida, mnt->mnt_id);
 }
 
 /*
  * Allocate a new peer group ID
- *
- * mnt_group_ida is protected by namespace_sem
  */
 static int mnt_alloc_group_id(struct mount *mnt)
 {
-       int res;
+       int res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL);
 
-       if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL))
-               return -ENOMEM;
-
-       res = ida_get_new_above(&mnt_group_ida,
-                               mnt_group_start,
-                               &mnt->mnt_group_id);
-       if (!res)
-               mnt_group_start = mnt->mnt_group_id + 1;
-
-       return res;
+       if (res < 0)
+               return res;
+       mnt->mnt_group_id = res;
+       return 0;
 }
 
 /*
@@ -152,10 +129,7 @@ static int mnt_alloc_group_id(struct mount *mnt)
  */
 void mnt_release_group_id(struct mount *mnt)
 {
-       int id = mnt->mnt_group_id;
-       ida_remove(&mnt_group_ida, id);
-       if (mnt_group_start > id)
-               mnt_group_start = id;
+       ida_free(&mnt_group_ida, mnt->mnt_group_id);
        mnt->mnt_group_id = 0;
 }
 
@@ -2668,6 +2642,7 @@ static long exact_copy_from_user(void *to, const void __user * from,
        if (!access_ok(VERIFY_READ, from, n))
                return n;
 
+       current->kernel_uaccess_faults_ok++;
        while (n) {
                if (__get_user(c, f)) {
                        memset(t, 0, n);
@@ -2677,6 +2652,7 @@ static long exact_copy_from_user(void *to, const void __user * from,
                f++;
                n--;
        }
+       current->kernel_uaccess_faults_ok--;
        return n;
 }