1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2022, Alibaba Cloud 4 */ 5 #include <linux/fscache.h> 6 #include "internal.h" 7 8 static const struct address_space_operations erofs_fscache_meta_aops = { 9 }; 10 11 int erofs_fscache_register_cookie(struct super_block *sb, 12 struct erofs_fscache **fscache, 13 char *name, bool need_inode) 14 { 15 struct fscache_volume *volume = EROFS_SB(sb)->volume; 16 struct erofs_fscache *ctx; 17 struct fscache_cookie *cookie; 18 int ret; 19 20 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 21 if (!ctx) 22 return -ENOMEM; 23 24 cookie = fscache_acquire_cookie(volume, FSCACHE_ADV_WANT_CACHE_SIZE, 25 name, strlen(name), NULL, 0, 0); 26 if (!cookie) { 27 erofs_err(sb, "failed to get cookie for %s", name); 28 ret = -EINVAL; 29 goto err; 30 } 31 32 fscache_use_cookie(cookie, false); 33 ctx->cookie = cookie; 34 35 if (need_inode) { 36 struct inode *const inode = new_inode(sb); 37 38 if (!inode) { 39 erofs_err(sb, "failed to get anon inode for %s", name); 40 ret = -ENOMEM; 41 goto err_cookie; 42 } 43 44 set_nlink(inode, 1); 45 inode->i_size = OFFSET_MAX; 46 inode->i_mapping->a_ops = &erofs_fscache_meta_aops; 47 mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 48 49 ctx->inode = inode; 50 } 51 52 *fscache = ctx; 53 return 0; 54 55 err_cookie: 56 fscache_unuse_cookie(ctx->cookie, NULL, NULL); 57 fscache_relinquish_cookie(ctx->cookie, false); 58 ctx->cookie = NULL; 59 err: 60 kfree(ctx); 61 return ret; 62 } 63 64 void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache) 65 { 66 struct erofs_fscache *ctx = *fscache; 67 68 if (!ctx) 69 return; 70 71 fscache_unuse_cookie(ctx->cookie, NULL, NULL); 72 fscache_relinquish_cookie(ctx->cookie, false); 73 ctx->cookie = NULL; 74 75 iput(ctx->inode); 76 ctx->inode = NULL; 77 78 kfree(ctx); 79 *fscache = NULL; 80 } 81 82 int erofs_fscache_register_fs(struct super_block *sb) 83 { 84 struct erofs_sb_info *sbi = EROFS_SB(sb); 85 struct fscache_volume *volume; 86 char *name; 87 int ret = 0; 88 89 name = kasprintf(GFP_KERNEL, "erofs,%s", sbi->opt.fsid); 90 if (!name) 91 return -ENOMEM; 92 93 volume = fscache_acquire_volume(name, NULL, NULL, 0); 94 if (IS_ERR_OR_NULL(volume)) { 95 erofs_err(sb, "failed to register volume for %s", name); 96 ret = volume ? PTR_ERR(volume) : -EOPNOTSUPP; 97 volume = NULL; 98 } 99 100 sbi->volume = volume; 101 kfree(name); 102 return ret; 103 } 104 105 void erofs_fscache_unregister_fs(struct super_block *sb) 106 { 107 struct erofs_sb_info *sbi = EROFS_SB(sb); 108 109 fscache_relinquish_volume(sbi->volume, NULL, false); 110 sbi->volume = NULL; 111 } 112