1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Ceph cache definitions. 4 * 5 * Copyright (C) 2013 by Adfin Solutions, Inc. All Rights Reserved. 6 * Written by Milosz Tanski (milosz@adfin.com) 7 */ 8 9 #include "super.h" 10 #include "cache.h" 11 12 struct ceph_aux_inode { 13 u64 version; 14 u64 mtime_sec; 15 u64 mtime_nsec; 16 }; 17 18 struct fscache_netfs ceph_cache_netfs = { 19 .name = "ceph", 20 .version = 0, 21 }; 22 23 static DEFINE_MUTEX(ceph_fscache_lock); 24 static LIST_HEAD(ceph_fscache_list); 25 26 struct ceph_fscache_entry { 27 struct list_head list; 28 struct fscache_cookie *fscache; 29 size_t uniq_len; 30 /* The following members must be last */ 31 struct ceph_fsid fsid; 32 char uniquifier[0]; 33 }; 34 35 static const struct fscache_cookie_def ceph_fscache_fsid_object_def = { 36 .name = "CEPH.fsid", 37 .type = FSCACHE_COOKIE_TYPE_INDEX, 38 }; 39 40 int __init ceph_fscache_register(void) 41 { 42 return fscache_register_netfs(&ceph_cache_netfs); 43 } 44 45 void ceph_fscache_unregister(void) 46 { 47 fscache_unregister_netfs(&ceph_cache_netfs); 48 } 49 50 int ceph_fscache_register_fs(struct ceph_fs_client* fsc) 51 { 52 const struct ceph_fsid *fsid = &fsc->client->fsid; 53 const char *fscache_uniq = fsc->mount_options->fscache_uniq; 54 size_t uniq_len = fscache_uniq ? strlen(fscache_uniq) : 0; 55 struct ceph_fscache_entry *ent; 56 int err = 0; 57 58 mutex_lock(&ceph_fscache_lock); 59 list_for_each_entry(ent, &ceph_fscache_list, list) { 60 if (memcmp(&ent->fsid, fsid, sizeof(*fsid))) 61 continue; 62 if (ent->uniq_len != uniq_len) 63 continue; 64 if (uniq_len && memcmp(ent->uniquifier, fscache_uniq, uniq_len)) 65 continue; 66 67 pr_err("fscache cookie already registered for fsid %pU\n", fsid); 68 pr_err(" use fsc=%%s mount option to specify a uniquifier\n"); 69 err = -EBUSY; 70 goto out_unlock; 71 } 72 73 ent = kzalloc(sizeof(*ent) + uniq_len, GFP_KERNEL); 74 if (!ent) { 75 err = -ENOMEM; 76 goto out_unlock; 77 } 78 79 memcpy(&ent->fsid, fsid, sizeof(*fsid)); 80 if (uniq_len > 0) { 81 memcpy(&ent->uniquifier, fscache_uniq, uniq_len); 82 ent->uniq_len = uniq_len; 83 } 84 85 fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index, 86 &ceph_fscache_fsid_object_def, 87 &ent->fsid, sizeof(ent->fsid) + uniq_len, 88 NULL, 0, 89 fsc, 0, true); 90 91 if (fsc->fscache) { 92 ent->fscache = fsc->fscache; 93 list_add_tail(&ent->list, &ceph_fscache_list); 94 } else { 95 kfree(ent); 96 pr_err("unable to register fscache cookie for fsid %pU\n", 97 fsid); 98 /* all other fs ignore this error */ 99 } 100 out_unlock: 101 mutex_unlock(&ceph_fscache_lock); 102 return err; 103 } 104 105 static enum fscache_checkaux ceph_fscache_inode_check_aux( 106 void *cookie_netfs_data, const void *data, uint16_t dlen, 107 loff_t object_size) 108 { 109 struct ceph_aux_inode aux; 110 struct ceph_inode_info* ci = cookie_netfs_data; 111 struct inode* inode = &ci->vfs_inode; 112 113 if (dlen != sizeof(aux) || 114 i_size_read(inode) != object_size) 115 return FSCACHE_CHECKAUX_OBSOLETE; 116 117 memset(&aux, 0, sizeof(aux)); 118 aux.version = ci->i_version; 119 aux.mtime_sec = inode->i_mtime.tv_sec; 120 aux.mtime_nsec = inode->i_mtime.tv_nsec; 121 122 if (memcmp(data, &aux, sizeof(aux)) != 0) 123 return FSCACHE_CHECKAUX_OBSOLETE; 124 125 dout("ceph inode 0x%p cached okay\n", ci); 126 return FSCACHE_CHECKAUX_OKAY; 127 } 128 129 static const struct fscache_cookie_def ceph_fscache_inode_object_def = { 130 .name = "CEPH.inode", 131 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 132 .check_aux = ceph_fscache_inode_check_aux, 133 }; 134 135 void ceph_fscache_register_inode_cookie(struct inode *inode) 136 { 137 struct ceph_inode_info *ci = ceph_inode(inode); 138 struct ceph_fs_client *fsc = ceph_inode_to_client(inode); 139 struct ceph_aux_inode aux; 140 141 /* No caching for filesystem */ 142 if (!fsc->fscache) 143 return; 144 145 /* Only cache for regular files that are read only */ 146 if (!S_ISREG(inode->i_mode)) 147 return; 148 149 inode_lock_nested(inode, I_MUTEX_CHILD); 150 if (!ci->fscache) { 151 memset(&aux, 0, sizeof(aux)); 152 aux.version = ci->i_version; 153 aux.mtime_sec = inode->i_mtime.tv_sec; 154 aux.mtime_nsec = inode->i_mtime.tv_nsec; 155 ci->fscache = fscache_acquire_cookie(fsc->fscache, 156 &ceph_fscache_inode_object_def, 157 &ci->i_vino, sizeof(ci->i_vino), 158 &aux, sizeof(aux), 159 ci, i_size_read(inode), false); 160 } 161 inode_unlock(inode); 162 } 163 164 void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci) 165 { 166 struct fscache_cookie* cookie; 167 168 if ((cookie = ci->fscache) == NULL) 169 return; 170 171 ci->fscache = NULL; 172 173 fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode); 174 fscache_relinquish_cookie(cookie, &ci->i_vino, false); 175 } 176 177 static bool ceph_fscache_can_enable(void *data) 178 { 179 struct inode *inode = data; 180 return !inode_is_open_for_write(inode); 181 } 182 183 void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp) 184 { 185 struct ceph_inode_info *ci = ceph_inode(inode); 186 187 if (!fscache_cookie_valid(ci->fscache)) 188 return; 189 190 if (inode_is_open_for_write(inode)) { 191 dout("fscache_file_set_cookie %p %p disabling cache\n", 192 inode, filp); 193 fscache_disable_cookie(ci->fscache, &ci->i_vino, false); 194 fscache_uncache_all_inode_pages(ci->fscache, inode); 195 } else { 196 fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode), 197 ceph_fscache_can_enable, inode); 198 if (fscache_cookie_enabled(ci->fscache)) { 199 dout("fscache_file_set_cookie %p %p enabling cache\n", 200 inode, filp); 201 } 202 } 203 } 204 205 static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error) 206 { 207 if (!error) 208 SetPageUptodate(page); 209 210 unlock_page(page); 211 } 212 213 static inline bool cache_valid(struct ceph_inode_info *ci) 214 { 215 return ci->i_fscache_gen == ci->i_rdcache_gen; 216 } 217 218 219 /* Atempt to read from the fscache, 220 * 221 * This function is called from the readpage_nounlock context. DO NOT attempt to 222 * unlock the page here (or in the callback). 223 */ 224 int ceph_readpage_from_fscache(struct inode *inode, struct page *page) 225 { 226 struct ceph_inode_info *ci = ceph_inode(inode); 227 int ret; 228 229 if (!cache_valid(ci)) 230 return -ENOBUFS; 231 232 ret = fscache_read_or_alloc_page(ci->fscache, page, 233 ceph_readpage_from_fscache_complete, NULL, 234 GFP_KERNEL); 235 236 switch (ret) { 237 case 0: /* Page found */ 238 dout("page read submitted\n"); 239 return 0; 240 case -ENOBUFS: /* Pages were not found, and can't be */ 241 case -ENODATA: /* Pages were not found */ 242 dout("page/inode not in cache\n"); 243 return ret; 244 default: 245 dout("%s: unknown error ret = %i\n", __func__, ret); 246 return ret; 247 } 248 } 249 250 int ceph_readpages_from_fscache(struct inode *inode, 251 struct address_space *mapping, 252 struct list_head *pages, 253 unsigned *nr_pages) 254 { 255 struct ceph_inode_info *ci = ceph_inode(inode); 256 int ret; 257 258 if (!cache_valid(ci)) 259 return -ENOBUFS; 260 261 ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages, 262 ceph_readpage_from_fscache_complete, 263 NULL, mapping_gfp_mask(mapping)); 264 265 switch (ret) { 266 case 0: /* All pages found */ 267 dout("all-page read submitted\n"); 268 return 0; 269 case -ENOBUFS: /* Some pages were not found, and can't be */ 270 case -ENODATA: /* some pages were not found */ 271 dout("page/inode not in cache\n"); 272 return ret; 273 default: 274 dout("%s: unknown error ret = %i\n", __func__, ret); 275 return ret; 276 } 277 } 278 279 void ceph_readpage_to_fscache(struct inode *inode, struct page *page) 280 { 281 struct ceph_inode_info *ci = ceph_inode(inode); 282 int ret; 283 284 if (!PageFsCache(page)) 285 return; 286 287 if (!cache_valid(ci)) 288 return; 289 290 ret = fscache_write_page(ci->fscache, page, i_size_read(inode), 291 GFP_KERNEL); 292 if (ret) 293 fscache_uncache_page(ci->fscache, page); 294 } 295 296 void ceph_invalidate_fscache_page(struct inode* inode, struct page *page) 297 { 298 struct ceph_inode_info *ci = ceph_inode(inode); 299 300 if (!PageFsCache(page)) 301 return; 302 303 fscache_wait_on_page_write(ci->fscache, page); 304 fscache_uncache_page(ci->fscache, page); 305 } 306 307 void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc) 308 { 309 if (fscache_cookie_valid(fsc->fscache)) { 310 struct ceph_fscache_entry *ent; 311 bool found = false; 312 313 mutex_lock(&ceph_fscache_lock); 314 list_for_each_entry(ent, &ceph_fscache_list, list) { 315 if (ent->fscache == fsc->fscache) { 316 list_del(&ent->list); 317 kfree(ent); 318 found = true; 319 break; 320 } 321 } 322 WARN_ON_ONCE(!found); 323 mutex_unlock(&ceph_fscache_lock); 324 325 __fscache_relinquish_cookie(fsc->fscache, NULL, false); 326 } 327 fsc->fscache = NULL; 328 } 329 330 /* 331 * caller should hold CEPH_CAP_FILE_{RD,CACHE} 332 */ 333 void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci) 334 { 335 if (cache_valid(ci)) 336 return; 337 338 /* resue i_truncate_mutex. There should be no pending 339 * truncate while the caller holds CEPH_CAP_FILE_RD */ 340 mutex_lock(&ci->i_truncate_mutex); 341 if (!cache_valid(ci)) { 342 if (fscache_check_consistency(ci->fscache, &ci->i_vino)) 343 fscache_invalidate(ci->fscache); 344 spin_lock(&ci->i_ceph_lock); 345 ci->i_fscache_gen = ci->i_rdcache_gen; 346 spin_unlock(&ci->i_ceph_lock); 347 } 348 mutex_unlock(&ci->i_truncate_mutex); 349 } 350