On 9/15/22 8:42 PM, Jia Zhu wrote: > +static > +struct erofs_fscache *erofs_fscache_domain_init_cookie(struct super_block *sb, > + char *name, bool need_inode) > +{ > + int err; > + struct inode *inode; > + struct erofs_fscache *ctx; > + struct erofs_domain *domain = EROFS_SB(sb)->domain; > + > + ctx = erofs_fscache_acquire_cookie(sb, name, need_inode); > + if (IS_ERR(ctx)) > + return ctx; > + > + ctx->name = kstrdup(name, GFP_KERNEL); > + if (!ctx->name) { > + err = -ENOMEM; > + goto out; > + } > + > + inode = new_inode(erofs_pseudo_mnt->mnt_sb); > + if (!inode) { > + kfree(ctx->name); > + err = -ENOMEM; > + goto out; > + } > + > + ctx->domain = domain; > + ctx->anon_inode = inode; > + inode->i_private = ctx; > + refcount_inc(&domain->ref); > + return ctx; > +out: > + fscache_unuse_cookie(ctx->cookie, NULL, NULL); > + fscache_relinquish_cookie(ctx->cookie, false); > + if (need_inode) > + iput(ctx->inode); > + kfree(ctx); > + return ERR_PTR(err); Could you please abstract the cleanup logic into one helper? like: erofs_fscache_relinquish_cookie() { fscache_unuse_cookie(ctx->cookie, NULL, NULL); fscache_relinquish_cookie(ctx->cookie, false); iput(ctx->inode); kfree(ctx->name); kfree(ctx); } which could also be called in erofs_fscache_unregister_cookie(). > void erofs_fscache_unregister_cookie(struct erofs_fscache *ctx) > { > + bool drop; > + struct erofs_domain *domain; > + > 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; > + } > > fscache_unuse_cookie(ctx->cookie, NULL, NULL); > fscache_relinquish_cookie(ctx->cookie, false); > + erofs_fscache_domain_put(domain); > iput(ctx->inode); > + kfree(ctx->name); > kfree(ctx); > } -- Thanks, Jingbo