cache.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * fs/cifs/cache.c - CIFS filesystem cache index structure definitions
  3. *
  4. * Copyright (c) 2010 Novell, Inc.
  5. * Authors(s): Suresh Jayaraman (sjayaraman@suse.de>
  6. *
  7. * This library is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published
  9. * by the Free Software Foundation; either version 2.1 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  15. * the GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include "fscache.h"
  22. #include "cifs_debug.h"
  23. /*
  24. * CIFS filesystem definition for FS-Cache
  25. */
  26. struct fscache_netfs cifs_fscache_netfs = {
  27. .name = "cifs",
  28. .version = 0,
  29. };
  30. /*
  31. * Register CIFS for caching with FS-Cache
  32. */
  33. int cifs_fscache_register(void)
  34. {
  35. return fscache_register_netfs(&cifs_fscache_netfs);
  36. }
  37. /*
  38. * Unregister CIFS for caching
  39. */
  40. void cifs_fscache_unregister(void)
  41. {
  42. fscache_unregister_netfs(&cifs_fscache_netfs);
  43. }
  44. /*
  45. * Server object for FS-Cache
  46. */
  47. const struct fscache_cookie_def cifs_fscache_server_index_def = {
  48. .name = "CIFS.server",
  49. .type = FSCACHE_COOKIE_TYPE_INDEX,
  50. };
  51. /*
  52. * Auxiliary data attached to CIFS superblock within the cache
  53. */
  54. struct cifs_fscache_super_auxdata {
  55. u64 resource_id; /* unique server resource id */
  56. };
  57. char *extract_sharename(const char *treename)
  58. {
  59. const char *src;
  60. char *delim, *dst;
  61. int len;
  62. /* skip double chars at the beginning */
  63. src = treename + 2;
  64. /* share name is always preceded by '\\' now */
  65. delim = strchr(src, '\\');
  66. if (!delim)
  67. return ERR_PTR(-EINVAL);
  68. delim++;
  69. len = strlen(delim);
  70. /* caller has to free the memory */
  71. dst = kstrndup(delim, len, GFP_KERNEL);
  72. if (!dst)
  73. return ERR_PTR(-ENOMEM);
  74. return dst;
  75. }
  76. static enum
  77. fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
  78. const void *data,
  79. uint16_t datalen,
  80. loff_t object_size)
  81. {
  82. struct cifs_fscache_super_auxdata auxdata;
  83. const struct cifs_tcon *tcon = cookie_netfs_data;
  84. if (datalen != sizeof(auxdata))
  85. return FSCACHE_CHECKAUX_OBSOLETE;
  86. memset(&auxdata, 0, sizeof(auxdata));
  87. auxdata.resource_id = tcon->resource_id;
  88. if (memcmp(data, &auxdata, datalen) != 0)
  89. return FSCACHE_CHECKAUX_OBSOLETE;
  90. return FSCACHE_CHECKAUX_OKAY;
  91. }
  92. /*
  93. * Superblock object for FS-Cache
  94. */
  95. const struct fscache_cookie_def cifs_fscache_super_index_def = {
  96. .name = "CIFS.super",
  97. .type = FSCACHE_COOKIE_TYPE_INDEX,
  98. .check_aux = cifs_fscache_super_check_aux,
  99. };
  100. static enum
  101. fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
  102. const void *data,
  103. uint16_t datalen,
  104. loff_t object_size)
  105. {
  106. struct cifs_fscache_inode_auxdata auxdata;
  107. struct cifsInodeInfo *cifsi = cookie_netfs_data;
  108. if (datalen != sizeof(auxdata))
  109. return FSCACHE_CHECKAUX_OBSOLETE;
  110. memset(&auxdata, 0, sizeof(auxdata));
  111. auxdata.eof = cifsi->server_eof;
  112. auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
  113. auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec;
  114. auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec;
  115. auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec;
  116. if (memcmp(data, &auxdata, datalen) != 0)
  117. return FSCACHE_CHECKAUX_OBSOLETE;
  118. return FSCACHE_CHECKAUX_OKAY;
  119. }
  120. const struct fscache_cookie_def cifs_fscache_inode_object_def = {
  121. .name = "CIFS.uniqueid",
  122. .type = FSCACHE_COOKIE_TYPE_DATAFILE,
  123. .check_aux = cifs_fscache_inode_check_aux,
  124. };