| // SPDX-License-Identifier: GPL-2.0-or-later |
| /* |
| * Copyright (C) 2022, Alibaba Cloud |
| */ |
| #include <linux/fscache.h> |
| #include "internal.h" |
| |
| int erofs_fscache_register_cookie(struct super_block *sb, |
| struct erofs_fscache **fscache, char *name) |
| { |
| struct fscache_volume *volume = EROFS_SB(sb)->volume; |
| struct erofs_fscache *ctx; |
| struct fscache_cookie *cookie; |
| |
| ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
| if (!ctx) |
| return -ENOMEM; |
| |
| cookie = fscache_acquire_cookie(volume, FSCACHE_ADV_WANT_CACHE_SIZE, |
| name, strlen(name), NULL, 0, 0); |
| if (!cookie) { |
| erofs_err(sb, "failed to get cookie for %s", name); |
| kfree(name); |
| return -EINVAL; |
| } |
| |
| fscache_use_cookie(cookie, false); |
| ctx->cookie = cookie; |
| |
| *fscache = ctx; |
| return 0; |
| } |
| |
| void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache) |
| { |
| struct erofs_fscache *ctx = *fscache; |
| |
| if (!ctx) |
| return; |
| |
| fscache_unuse_cookie(ctx->cookie, NULL, NULL); |
| fscache_relinquish_cookie(ctx->cookie, false); |
| ctx->cookie = NULL; |
| |
| kfree(ctx); |
| *fscache = NULL; |
| } |
| |
| int erofs_fscache_register_fs(struct super_block *sb) |
| { |
| struct erofs_sb_info *sbi = EROFS_SB(sb); |
| struct fscache_volume *volume; |
| char *name; |
| int ret = 0; |
| |
| name = kasprintf(GFP_KERNEL, "erofs,%s", sbi->opt.fsid); |
| if (!name) |
| return -ENOMEM; |
| |
| volume = fscache_acquire_volume(name, NULL, NULL, 0); |
| if (IS_ERR_OR_NULL(volume)) { |
| erofs_err(sb, "failed to register volume for %s", name); |
| ret = volume ? PTR_ERR(volume) : -EOPNOTSUPP; |
| volume = NULL; |
| } |
| |
| sbi->volume = volume; |
| kfree(name); |
| return ret; |
| } |
| |
| void erofs_fscache_unregister_fs(struct super_block *sb) |
| { |
| struct erofs_sb_info *sbi = EROFS_SB(sb); |
| |
| fscache_relinquish_volume(sbi->volume, NULL, false); |
| sbi->volume = NULL; |
| } |