xref: /openbmc/linux/fs/erofs/fscache.c (revision 3c265d7dcefab21a58ca5454c0f778412bde0870)
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