static DEFINE_MUTEX(erofs_domain_list_lock);
 static DEFINE_MUTEX(erofs_domain_cookies_lock);
 static LIST_HEAD(erofs_domain_list);
+static LIST_HEAD(erofs_domain_cookies_list);
 static struct vfsmount *erofs_pseudo_mnt;
 
 struct erofs_fscache_request {
 
 static void erofs_fscache_domain_put(struct erofs_domain *domain)
 {
-       if (!domain)
-               return;
        mutex_lock(&erofs_domain_list_lock);
        if (refcount_dec_and_test(&domain->ref)) {
                list_del(&domain->list);
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
                return ERR_PTR(-ENOMEM);
+       INIT_LIST_HEAD(&ctx->node);
+       refcount_set(&ctx->ref, 1);
 
        cookie = fscache_acquire_cookie(volume, FSCACHE_ADV_WANT_CACHE_SIZE,
                                        name, strlen(name), NULL, 0, 0);
        fscache_unuse_cookie(ctx->cookie, NULL, NULL);
        fscache_relinquish_cookie(ctx->cookie, false);
        iput(ctx->inode);
+       iput(ctx->anon_inode);
        kfree(ctx->name);
        kfree(ctx);
 }
 
        ctx->domain = domain;
        ctx->anon_inode = inode;
+       list_add(&ctx->node, &erofs_domain_cookies_list);
        inode->i_private = ctx;
        refcount_inc(&domain->ref);
        return ctx;
                                                   char *name,
                                                   unsigned int flags)
 {
-       struct inode *inode;
        struct erofs_fscache *ctx;
        struct erofs_domain *domain = EROFS_SB(sb)->domain;
-       struct super_block *psb = erofs_pseudo_mnt->mnt_sb;
 
        mutex_lock(&erofs_domain_cookies_lock);
-       spin_lock(&psb->s_inode_list_lock);
-       list_for_each_entry(inode, &psb->s_inodes, i_sb_list) {
-               ctx = inode->i_private;
-               if (!ctx || ctx->domain != domain || strcmp(ctx->name, name))
+       list_for_each_entry(ctx, &erofs_domain_cookies_list, node) {
+               if (ctx->domain != domain || strcmp(ctx->name, name))
                        continue;
                if (!(flags & EROFS_REG_COOKIE_NEED_NOEXIST)) {
-                       igrab(inode);
+                       refcount_inc(&ctx->ref);
                } else {
                        erofs_err(sb, "%s already exists in domain %s", name,
                                  domain->domain_id);
                        ctx = ERR_PTR(-EEXIST);
                }
-               spin_unlock(&psb->s_inode_list_lock);
                mutex_unlock(&erofs_domain_cookies_lock);
                return ctx;
        }
-       spin_unlock(&psb->s_inode_list_lock);
        ctx = erofs_fscache_domain_init_cookie(sb, name, flags);
        mutex_unlock(&erofs_domain_cookies_lock);
        return ctx;
 
 void erofs_fscache_unregister_cookie(struct erofs_fscache *ctx)
 {
-       bool drop;
-       struct erofs_domain *domain;
+       struct erofs_domain *domain = NULL;
 
        if (!ctx)
                return;
-       domain = ctx->domain;
-       if (domain) {
-               mutex_lock(&erofs_domain_cookies_lock);
-               drop = atomic_read(&ctx->anon_inode->i_count) == 1;
-               iput(ctx->anon_inode);
-               mutex_unlock(&erofs_domain_cookies_lock);
-               if (!drop)
-                       return;
-       }
+       if (!ctx->domain)
+               return erofs_fscache_relinquish_cookie(ctx);
 
-       erofs_fscache_relinquish_cookie(ctx);
-       erofs_fscache_domain_put(domain);
+       mutex_lock(&erofs_domain_cookies_lock);
+       if (refcount_dec_and_test(&ctx->ref)) {
+               domain = ctx->domain;
+               list_del(&ctx->node);
+               erofs_fscache_relinquish_cookie(ctx);
+       }
+       mutex_unlock(&erofs_domain_cookies_lock);
+       if (domain)
+               erofs_fscache_domain_put(domain);
 }
 
 int erofs_fscache_register_fs(struct super_block *sb)