These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / ipc / util.c
index ff3323e..0f401d9 100644 (file)
@@ -237,6 +237,10 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size)
        rcu_read_lock();
        spin_lock(&new->lock);
 
+       current_euid_egid(&euid, &egid);
+       new->cuid = new->uid = euid;
+       new->gid = new->cgid = egid;
+
        id = idr_alloc(&ids->ipcs_idr, new,
                       (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0,
                       GFP_NOWAIT);
@@ -249,10 +253,6 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size)
 
        ids->in_use++;
 
-       current_euid_egid(&euid, &egid);
-       new->cuid = new->uid = euid;
-       new->gid = new->cgid = egid;
-
        if (next_id < 0) {
                new->seq = ids->seq++;
                if (ids->seq > IPCID_SEQ_MAX)
@@ -467,10 +467,7 @@ void ipc_rcu_free(struct rcu_head *head)
 {
        struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu);
 
-       if (is_vmalloc_addr(p))
-               vfree(p);
-       else
-               kfree(p);
+       kvfree(p);
 }
 
 /**
@@ -558,7 +555,7 @@ void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out)
  * Call inside the RCU critical section.
  * The ipc object is *not* locked on exit.
  */
-struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id)
+struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id)
 {
        struct kern_ipc_perm *out;
        int lid = ipcid_to_idx(id);
@@ -584,21 +581,24 @@ struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
        struct kern_ipc_perm *out;
 
        rcu_read_lock();
-       out = ipc_obtain_object(ids, id);
+       out = ipc_obtain_object_idr(ids, id);
        if (IS_ERR(out))
-               goto err1;
+               goto err;
 
        spin_lock(&out->lock);
 
-       /* ipc_rmid() may have already freed the ID while ipc_lock
-        * was spinning: here verify that the structure is still valid
+       /*
+        * ipc_rmid() may have already freed the ID while ipc_lock()
+        * was spinning: here verify that the structure is still valid.
+        * Upon races with RMID, return -EIDRM, thus indicating that
+        * the ID points to a removed identifier.
         */
        if (ipc_valid_object(out))
                return out;
 
        spin_unlock(&out->lock);
-       out = ERR_PTR(-EINVAL);
-err1:
+       out = ERR_PTR(-EIDRM);
+err:
        rcu_read_unlock();
        return out;
 }
@@ -608,7 +608,7 @@ err1:
  * @ids: ipc identifier set
  * @id: ipc id to look for
  *
- * Similar to ipc_obtain_object() but also checks
+ * Similar to ipc_obtain_object_idr() but also checks
  * the ipc object reference counter.
  *
  * Call inside the RCU critical section.
@@ -616,13 +616,13 @@ err1:
  */
 struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id)
 {
-       struct kern_ipc_perm *out = ipc_obtain_object(ids, id);
+       struct kern_ipc_perm *out = ipc_obtain_object_idr(ids, id);
 
        if (IS_ERR(out))
                goto out;
 
        if (ipc_checkid(out, id))
-               return ERR_PTR(-EIDRM);
+               return ERR_PTR(-EINVAL);
 out:
        return out;
 }