OSDN Git Service

nvme-multipath: relax ANA state check
[uclinux-h8/linux.git] / fs / userfaultfd.c
index 7a85e60..89800fc 100644 (file)
@@ -53,7 +53,7 @@ struct userfaultfd_ctx {
        /* a refile sequence protected by fault_pending_wqh lock */
        struct seqcount refile_seq;
        /* pseudo fd refcounting */
-       atomic_t refcount;
+       refcount_t refcount;
        /* userfaultfd syscall flags */
        unsigned int flags;
        /* features requested from the userspace */
@@ -140,8 +140,7 @@ out:
  */
 static void userfaultfd_ctx_get(struct userfaultfd_ctx *ctx)
 {
-       if (!atomic_inc_not_zero(&ctx->refcount))
-               BUG();
+       refcount_inc(&ctx->refcount);
 }
 
 /**
@@ -154,7 +153,7 @@ static void userfaultfd_ctx_get(struct userfaultfd_ctx *ctx)
  */
 static void userfaultfd_ctx_put(struct userfaultfd_ctx *ctx)
 {
-       if (atomic_dec_and_test(&ctx->refcount)) {
+       if (refcount_dec_and_test(&ctx->refcount)) {
                VM_BUG_ON(spin_is_locked(&ctx->fault_pending_wqh.lock));
                VM_BUG_ON(waitqueue_active(&ctx->fault_pending_wqh));
                VM_BUG_ON(spin_is_locked(&ctx->fault_wqh.lock));
@@ -686,7 +685,7 @@ int dup_userfaultfd(struct vm_area_struct *vma, struct list_head *fcs)
                        return -ENOMEM;
                }
 
-               atomic_set(&ctx->refcount, 1);
+               refcount_set(&ctx->refcount, 1);
                ctx->flags = octx->flags;
                ctx->state = UFFD_STATE_RUNNING;
                ctx->features = octx->features;
@@ -736,10 +735,18 @@ void mremap_userfaultfd_prep(struct vm_area_struct *vma,
        struct userfaultfd_ctx *ctx;
 
        ctx = vma->vm_userfaultfd_ctx.ctx;
-       if (ctx && (ctx->features & UFFD_FEATURE_EVENT_REMAP)) {
+
+       if (!ctx)
+               return;
+
+       if (ctx->features & UFFD_FEATURE_EVENT_REMAP) {
                vm_ctx->ctx = ctx;
                userfaultfd_ctx_get(ctx);
                WRITE_ONCE(ctx->mmap_changing, true);
+       } else {
+               /* Drop uffd context if remap feature not enabled */
+               vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
+               vma->vm_flags &= ~(VM_UFFD_WP | VM_UFFD_MISSING);
        }
 }
 
@@ -926,7 +933,7 @@ static inline struct userfaultfd_wait_queue *find_userfault_in(
        wait_queue_entry_t *wq;
        struct userfaultfd_wait_queue *uwq;
 
-       VM_BUG_ON(!spin_is_locked(&wqh->lock));
+       lockdep_assert_held(&wqh->lock);
 
        uwq = NULL;
        if (!waitqueue_active(wqh))
@@ -1927,7 +1934,7 @@ SYSCALL_DEFINE1(userfaultfd, int, flags)
        if (!ctx)
                return -ENOMEM;
 
-       atomic_set(&ctx->refcount, 1);
+       refcount_set(&ctx->refcount, 1);
        ctx->flags = flags;
        ctx->features = 0;
        ctx->state = UFFD_STATE_WAIT_API;