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/* 25 * CIFS filesystem definition for FS-Cache 26 */ 27struct fscache_netfs cifs_fscache_netfs = { 28 .name = "cifs", 29 .version = 0, 30}; 31 32/* 33 * Register CIFS for caching with FS-Cache 34 */ 35int cifs_fscache_register(void) 36{ 37 return fscache_register_netfs(&cifs_fscache_netfs); 38} 39 40/* 41 * Unregister CIFS for caching 42 */ 43void cifs_fscache_unregister(void) 44{ 45 fscache_unregister_netfs(&cifs_fscache_netfs); 46} 47 48/* 49 * Server object for FS-Cache 50 */ 51const struct fscache_cookie_def cifs_fscache_server_index_def = { 52 .name = "CIFS.server", 53 .type = FSCACHE_COOKIE_TYPE_INDEX, 54}; 55 56char *extract_sharename(const char *treename) 57{ 58 const char *src; 59 char *delim, *dst; 60 int len; 61 62 /* skip double chars at the beginning */ 63 src = treename + 2; 64 65 /* share name is always preceded by '\\' now */ 66 delim = strchr(src, '\\'); 67 if (!delim) 68 return ERR_PTR(-EINVAL); 69 delim++; 70 len = strlen(delim); 71 72 /* caller has to free the memory */ 73 dst = kstrndup(delim, len, GFP_KERNEL); 74 if (!dst) 75 return ERR_PTR(-ENOMEM); 76 77 return dst; 78} 79 80static enum 81fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data, 82 const void *data, 83 uint16_t datalen, 84 loff_t object_size) 85{ 86 struct cifs_fscache_super_auxdata auxdata; 87 const struct cifs_tcon *tcon = cookie_netfs_data; 88 89 if (datalen != sizeof(auxdata)) 90 return FSCACHE_CHECKAUX_OBSOLETE; 91 92 memset(&auxdata, 0, sizeof(auxdata)); 93 auxdata.resource_id = tcon->resource_id; 94 auxdata.vol_create_time = tcon->vol_create_time; 95 auxdata.vol_serial_number = tcon->vol_serial_number; 96 97 if (memcmp(data, &auxdata, datalen) != 0) 98 return FSCACHE_CHECKAUX_OBSOLETE; 99 100 return FSCACHE_CHECKAUX_OKAY; 101} 102 103/* 104 * Superblock object for FS-Cache 105 */ 106const struct fscache_cookie_def cifs_fscache_super_index_def = { 107 .name = "CIFS.super", 108 .type = FSCACHE_COOKIE_TYPE_INDEX, 109 .check_aux = cifs_fscache_super_check_aux, 110}; 111 112static enum 113fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data, 114 const void *data, 115 uint16_t datalen, 116 loff_t object_size) 117{ 118 struct cifs_fscache_inode_auxdata auxdata; 119 struct cifsInodeInfo *cifsi = cookie_netfs_data; 120 121 if (datalen != sizeof(auxdata)) 122 return FSCACHE_CHECKAUX_OBSOLETE; 123 124 memset(&auxdata, 0, sizeof(auxdata)); 125 auxdata.eof = cifsi->server_eof; 126 auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; 127 auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; 128 auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; 129 auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; 130 131 if (memcmp(data, &auxdata, datalen) != 0) 132 return FSCACHE_CHECKAUX_OBSOLETE; 133 134 return FSCACHE_CHECKAUX_OKAY; 135} 136 137const struct fscache_cookie_def cifs_fscache_inode_object_def = { 138 .name = "CIFS.uniqueid", 139 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 140 .check_aux = cifs_fscache_inode_check_aux, 141}; 142