Merge tag 'ceph-for-4.17-rc1' of git://github.com/ceph/ceph-client
[sfrench/cifs-2.6.git] / fs / ceph / cache.c
index 797cc816019903a75fa6eb57e510070761b1ca37..bb524c880b1eadf2915a0a551eb01730871dee9a 100644 (file)
@@ -27,7 +27,6 @@
 struct ceph_aux_inode {
        u64             version;
        struct timespec mtime;
-       loff_t          size;
 };
 
 struct fscache_netfs ceph_cache_netfs = {
@@ -41,34 +40,15 @@ static LIST_HEAD(ceph_fscache_list);
 struct ceph_fscache_entry {
        struct list_head list;
        struct fscache_cookie *fscache;
-       struct ceph_fsid fsid;
        size_t uniq_len;
+       /* The following members must be last */
+       struct ceph_fsid fsid;
        char uniquifier[0];
 };
 
-static uint16_t ceph_fscache_session_get_key(const void *cookie_netfs_data,
-                                            void *buffer, uint16_t maxbuf)
-{
-       const struct ceph_fs_client* fsc = cookie_netfs_data;
-       const char *fscache_uniq = fsc->mount_options->fscache_uniq;
-       uint16_t fsid_len, uniq_len;
-
-       fsid_len = sizeof(fsc->client->fsid);
-       uniq_len = fscache_uniq ? strlen(fscache_uniq) : 0;
-       if (fsid_len + uniq_len > maxbuf)
-               return 0;
-
-       memcpy(buffer, &fsc->client->fsid, fsid_len);
-       if (uniq_len)
-               memcpy(buffer + fsid_len, fscache_uniq, uniq_len);
-
-       return fsid_len + uniq_len;
-}
-
 static const struct fscache_cookie_def ceph_fscache_fsid_object_def = {
        .name           = "CEPH.fsid",
        .type           = FSCACHE_COOKIE_TYPE_INDEX,
-       .get_key        = ceph_fscache_session_get_key,
 };
 
 int __init ceph_fscache_register(void)
@@ -110,16 +90,19 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
                goto out_unlock;
        }
 
+       memcpy(&ent->fsid, fsid, sizeof(*fsid));
+       if (uniq_len > 0) {
+               memcpy(&ent->uniquifier, fscache_uniq, uniq_len);
+               ent->uniq_len = uniq_len;
+       }
+
        fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index,
                                              &ceph_fscache_fsid_object_def,
-                                             fsc, true);
+                                             &ent->fsid, sizeof(ent->fsid) + uniq_len,
+                                             NULL, 0,
+                                             fsc, 0, true);
 
        if (fsc->fscache) {
-               memcpy(&ent->fsid, fsid, sizeof(*fsid));
-               if (uniq_len > 0) {
-                       memcpy(&ent->uniquifier, fscache_uniq, uniq_len);
-                       ent->uniq_len = uniq_len;
-               }
                ent->fscache = fsc->fscache;
                list_add_tail(&ent->list, &ceph_fscache_list);
        } else {
@@ -133,59 +116,21 @@ out_unlock:
        return err;
 }
 
-static uint16_t ceph_fscache_inode_get_key(const void *cookie_netfs_data,
-                                          void *buffer, uint16_t maxbuf)
-{
-       const struct ceph_inode_info* ci = cookie_netfs_data;
-       uint16_t klen;
-
-       /* use ceph virtual inode (id + snapshot) */
-       klen = sizeof(ci->i_vino);
-       if (klen > maxbuf)
-               return 0;
-
-       memcpy(buffer, &ci->i_vino, klen);
-       return klen;
-}
-
-static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,
-                                          void *buffer, uint16_t bufmax)
-{
-       struct ceph_aux_inode aux;
-       const struct ceph_inode_info* ci = cookie_netfs_data;
-       const struct inode* inode = &ci->vfs_inode;
-
-       memset(&aux, 0, sizeof(aux));
-       aux.version = ci->i_version;
-       aux.mtime = inode->i_mtime;
-       aux.size = i_size_read(inode);
-
-       memcpy(buffer, &aux, sizeof(aux));
-
-       return sizeof(aux);
-}
-
-static void ceph_fscache_inode_get_attr(const void *cookie_netfs_data,
-                                       uint64_t *size)
-{
-       const struct ceph_inode_info* ci = cookie_netfs_data;
-       *size = i_size_read(&ci->vfs_inode);
-}
-
 static enum fscache_checkaux ceph_fscache_inode_check_aux(
-       void *cookie_netfs_data, const void *data, uint16_t dlen)
+       void *cookie_netfs_data, const void *data, uint16_t dlen,
+       loff_t object_size)
 {
        struct ceph_aux_inode aux;
        struct ceph_inode_info* ci = cookie_netfs_data;
        struct inode* inode = &ci->vfs_inode;
 
-       if (dlen != sizeof(aux))
+       if (dlen != sizeof(aux) ||
+           i_size_read(inode) != object_size)
                return FSCACHE_CHECKAUX_OBSOLETE;
 
        memset(&aux, 0, sizeof(aux));
        aux.version = ci->i_version;
        aux.mtime = inode->i_mtime;
-       aux.size = i_size_read(inode);
 
        if (memcmp(data, &aux, sizeof(aux)) != 0)
                return FSCACHE_CHECKAUX_OBSOLETE;
@@ -197,9 +142,6 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
 static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
        .name           = "CEPH.inode",
        .type           = FSCACHE_COOKIE_TYPE_DATAFILE,
-       .get_key        = ceph_fscache_inode_get_key,
-       .get_attr       = ceph_fscache_inode_get_attr,
-       .get_aux        = ceph_fscache_inode_get_aux,
        .check_aux      = ceph_fscache_inode_check_aux,
 };
 
@@ -207,6 +149,7 @@ 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_client(inode);
+       struct ceph_aux_inode aux;
 
        /* No caching for filesystem */
        if (!fsc->fscache)
@@ -218,9 +161,14 @@ void ceph_fscache_register_inode_cookie(struct inode *inode)
 
        inode_lock_nested(inode, I_MUTEX_CHILD);
        if (!ci->fscache) {
+               memset(&aux, 0, sizeof(aux));
+               aux.version = ci->i_version;
+               aux.mtime = inode->i_mtime;
                ci->fscache = fscache_acquire_cookie(fsc->fscache,
-                                       &ceph_fscache_inode_object_def,
-                                       ci, false);
+                                                    &ceph_fscache_inode_object_def,
+                                                    &ci->i_vino, sizeof(ci->i_vino),
+                                                    &aux, sizeof(aux),
+                                                    ci, i_size_read(inode), false);
        }
        inode_unlock(inode);
 }
@@ -235,7 +183,7 @@ void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
        ci->fscache = NULL;
 
        fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode);
-       fscache_relinquish_cookie(cookie, 0);
+       fscache_relinquish_cookie(cookie, &ci->i_vino, false);
 }
 
 static bool ceph_fscache_can_enable(void *data)
@@ -254,11 +202,11 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
        if (inode_is_open_for_write(inode)) {
                dout("fscache_file_set_cookie %p %p disabling cache\n",
                     inode, filp);
-               fscache_disable_cookie(ci->fscache, false);
+               fscache_disable_cookie(ci->fscache, &ci->i_vino, false);
                fscache_uncache_all_inode_pages(ci->fscache, inode);
        } else {
-               fscache_enable_cookie(ci->fscache, ceph_fscache_can_enable,
-                               inode);
+               fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode),
+                                     ceph_fscache_can_enable, inode);
                if (fscache_cookie_enabled(ci->fscache)) {
                        dout("fscache_file_set_cookie %p %p enabling cache\n",
                             inode, filp);
@@ -351,7 +299,8 @@ void ceph_readpage_to_fscache(struct inode *inode, struct page *page)
        if (!cache_valid(ci))
                return;
 
-       ret = fscache_write_page(ci->fscache, page, GFP_KERNEL);
+       ret = fscache_write_page(ci->fscache, page, i_size_read(inode),
+                                GFP_KERNEL);
        if (ret)
                 fscache_uncache_page(ci->fscache, page);
 }
@@ -385,7 +334,7 @@ void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc)
                WARN_ON_ONCE(!found);
                mutex_unlock(&ceph_fscache_lock);
 
-               __fscache_relinquish_cookie(fsc->fscache, 0);
+               __fscache_relinquish_cookie(fsc->fscache, NULL, false);
        }
        fsc->fscache = NULL;
 }
@@ -402,7 +351,7 @@ void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci)
         * truncate while the caller holds CEPH_CAP_FILE_RD */
        mutex_lock(&ci->i_truncate_mutex);
        if (!cache_valid(ci)) {
-               if (fscache_check_consistency(ci->fscache))
+               if (fscache_check_consistency(ci->fscache, &ci->i_vino))
                        fscache_invalidate(ci->fscache);
                spin_lock(&ci->i_ceph_lock);
                ci->i_fscache_gen = ci->i_rdcache_gen;