// SPDX-License-Identifier: GPL-2.0-only /* * Ceph cache definitions. * * Copyright (C) 2013 by Adfin Solutions, Inc. All Rights Reserved. * Written by Milosz Tanski (milosz@adfin.com) */ #include #include #include "super.h" #include "cache.h" void ceph_fscache_register_inode_cookie(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode); /* No caching for filesystem? */ if (!fsc->fscache) return; /* Regular files only */ if (!S_ISREG(inode->i_mode)) return; /* Only new inodes! */ if (!(inode->i_state & I_NEW)) return; WARN_ON_ONCE(ci->netfs.cache); ci->netfs.cache = fscache_acquire_cookie(fsc->fscache, 0, &ci->i_vino, sizeof(ci->i_vino), &ci->i_version, sizeof(ci->i_version), i_size_read(inode)); if (ci->netfs.cache) mapping_set_release_always(inode->i_mapping); } void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info *ci) { fscache_relinquish_cookie(ceph_fscache_cookie(ci), false); } void ceph_fscache_use_cookie(struct inode *inode, bool will_modify) { struct ceph_inode_info *ci = ceph_inode(inode); fscache_use_cookie(ceph_fscache_cookie(ci), will_modify); } void ceph_fscache_unuse_cookie(struct inode *inode, bool update) { struct ceph_inode_info *ci = ceph_inode(inode); if (update) { loff_t i_size = i_size_read(inode); fscache_unuse_cookie(ceph_fscache_cookie(ci), &ci->i_version, &i_size); } else { fscache_unuse_cookie(ceph_fscache_cookie(ci), NULL, NULL); } } void ceph_fscache_update(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); loff_t i_size = i_size_read(inode); fscache_update_cookie(ceph_fscache_cookie(ci), &ci->i_version, &i_size); } void ceph_fscache_invalidate(struct inode *inode, bool dio_write) { struct ceph_inode_info *ci = ceph_inode(inode); fscache_invalidate(ceph_fscache_cookie(ci), &ci->i_version, i_size_read(inode), dio_write ? FSCACHE_INVAL_DIO_WRITE : 0); } int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc) { const struct ceph_fsid *fsid = &fsc->client->fsid; const char *fscache_uniq = fsc->mount_options->fscache_uniq; size_t uniq_len = fscache_uniq ? strlen(fscache_uniq) : 0; char *name; int err = 0; name = kasprintf(GFP_KERNEL, "ceph,%pU%s%s", fsid, uniq_len ? "," : "", uniq_len ? fscache_uniq : ""); if (!name) return -ENOMEM; fsc->fscache = fscache_acquire_volume(name, NULL, NULL, 0); if (IS_ERR_OR_NULL(fsc->fscache)) { errorfc(fc, "Unable to register fscache cookie for %s", name); err = fsc->fscache ? PTR_ERR(fsc->fscache) : -EOPNOTSUPP; fsc->fscache = NULL; } kfree(name); return err; } void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc) { fscache_relinquish_volume(fsc->fscache, NULL, false); }