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