if (!entry)
                return -ENOMEM;
 
-       down_read(&sess->rpc_lock);
        entry->method = method;
        entry->id = id = ksmbd_ipc_id_alloc();
        if (id < 0)
                goto free_entry;
+
+       down_write(&sess->rpc_lock);
        old = xa_store(&sess->rpc_handle_list, id, entry, KSMBD_DEFAULT_GFP);
-       if (xa_is_err(old))
+       if (xa_is_err(old)) {
+               up_write(&sess->rpc_lock);
                goto free_id;
+       }
 
        resp = ksmbd_rpc_open(sess, id);
-       if (!resp)
-               goto erase_xa;
+       if (!resp) {
+               xa_erase(&sess->rpc_handle_list, entry->id);
+               up_write(&sess->rpc_lock);
+               goto free_id;
+       }
 
-       up_read(&sess->rpc_lock);
+       up_write(&sess->rpc_lock);
        kvfree(resp);
        return id;
-erase_xa:
-       xa_erase(&sess->rpc_handle_list, entry->id);
 free_id:
        ksmbd_rpc_id_free(entry->id);
 free_entry:
        kfree(entry);
-       up_read(&sess->rpc_lock);
        return -EINVAL;
 }
 
 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
 {
        struct ksmbd_session_rpc *entry;
+       int method;
 
+       down_read(&sess->rpc_lock);
        entry = xa_load(&sess->rpc_handle_list, id);
-       return entry ? entry->method : 0;
+       method = entry ? entry->method : 0;
+       up_read(&sess->rpc_lock);
+
+       return method;
 }
 
 void ksmbd_session_destroy(struct ksmbd_session *sess)