fscache-index.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* NFS FS-Cache index structure definition
  3. *
  4. * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
  5. * Written by David Howells (dhowells@redhat.com)
  6. */
  7. #include <linux/init.h>
  8. #include <linux/kernel.h>
  9. #include <linux/sched.h>
  10. #include <linux/mm.h>
  11. #include <linux/nfs_fs.h>
  12. #include <linux/nfs_fs_sb.h>
  13. #include <linux/in6.h>
  14. #include <linux/iversion.h>
  15. #include "internal.h"
  16. #include "fscache.h"
  17. #define NFSDBG_FACILITY NFSDBG_FSCACHE
  18. /*
  19. * Define the NFS filesystem for FS-Cache. Upon registration FS-Cache sticks
  20. * the cookie for the top-level index object for NFS into here. The top-level
  21. * index can than have other cache objects inserted into it.
  22. */
  23. struct fscache_netfs nfs_fscache_netfs = {
  24. .name = "nfs",
  25. .version = 0,
  26. };
  27. /*
  28. * Register NFS for caching
  29. */
  30. int nfs_fscache_register(void)
  31. {
  32. return fscache_register_netfs(&nfs_fscache_netfs);
  33. }
  34. /*
  35. * Unregister NFS for caching
  36. */
  37. void nfs_fscache_unregister(void)
  38. {
  39. fscache_unregister_netfs(&nfs_fscache_netfs);
  40. }
  41. /*
  42. * Define the server object for FS-Cache. This is used to describe a server
  43. * object to fscache_acquire_cookie(). It is keyed by the NFS protocol and
  44. * server address parameters.
  45. */
  46. const struct fscache_cookie_def nfs_fscache_server_index_def = {
  47. .name = "NFS.server",
  48. .type = FSCACHE_COOKIE_TYPE_INDEX,
  49. };
  50. /*
  51. * Define the superblock object for FS-Cache. This is used to describe a
  52. * superblock object to fscache_acquire_cookie(). It is keyed by all the NFS
  53. * parameters that might cause a separate superblock.
  54. */
  55. const struct fscache_cookie_def nfs_fscache_super_index_def = {
  56. .name = "NFS.super",
  57. .type = FSCACHE_COOKIE_TYPE_INDEX,
  58. };
  59. /*
  60. * Consult the netfs about the state of an object
  61. * - This function can be absent if the index carries no state data
  62. * - The netfs data from the cookie being used as the target is
  63. * presented, as is the auxiliary data
  64. */
  65. static
  66. enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
  67. const void *data,
  68. uint16_t datalen,
  69. loff_t object_size)
  70. {
  71. struct nfs_fscache_inode_auxdata auxdata;
  72. struct nfs_inode *nfsi = cookie_netfs_data;
  73. if (datalen != sizeof(auxdata))
  74. return FSCACHE_CHECKAUX_OBSOLETE;
  75. memset(&auxdata, 0, sizeof(auxdata));
  76. auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
  77. auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
  78. auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
  79. auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
  80. if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
  81. auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
  82. if (memcmp(data, &auxdata, datalen) != 0)
  83. return FSCACHE_CHECKAUX_OBSOLETE;
  84. return FSCACHE_CHECKAUX_OKAY;
  85. }
  86. /*
  87. * Get an extra reference on a read context.
  88. * - This function can be absent if the completion function doesn't require a
  89. * context.
  90. * - The read context is passed back to NFS in the event that a data read on the
  91. * cache fails with EIO - in which case the server must be contacted to
  92. * retrieve the data, which requires the read context for security.
  93. */
  94. static void nfs_fh_get_context(void *cookie_netfs_data, void *context)
  95. {
  96. get_nfs_open_context(context);
  97. }
  98. /*
  99. * Release an extra reference on a read context.
  100. * - This function can be absent if the completion function doesn't require a
  101. * context.
  102. */
  103. static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
  104. {
  105. if (context)
  106. put_nfs_open_context(context);
  107. }
  108. /*
  109. * Define the inode object for FS-Cache. This is used to describe an inode
  110. * object to fscache_acquire_cookie(). It is keyed by the NFS file handle for
  111. * an inode.
  112. *
  113. * Coherency is managed by comparing the copies of i_size, i_mtime and i_ctime
  114. * held in the cache auxiliary data for the data storage object with those in
  115. * the inode struct in memory.
  116. */
  117. const struct fscache_cookie_def nfs_fscache_inode_object_def = {
  118. .name = "NFS.fh",
  119. .type = FSCACHE_COOKIE_TYPE_DATAFILE,
  120. .check_aux = nfs_fscache_inode_check_aux,
  121. .get_context = nfs_fh_get_context,
  122. .put_context = nfs_fh_put_context,
  123. };