linux/fs/cifs/cache.c
<<
>>
Prefs
   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
  56/*
  57 * Auxiliary data attached to CIFS superblock within the cache
  58 */
  59struct cifs_fscache_super_auxdata {
  60        u64     resource_id;            /* unique server resource id */
  61};
  62
  63char *extract_sharename(const char *treename)
  64{
  65        const char *src;
  66        char *delim, *dst;
  67        int len;
  68
  69        /* skip double chars at the beginning */
  70        src = treename + 2;
  71
  72        /* share name is always preceded by '\\' now */
  73        delim = strchr(src, '\\');
  74        if (!delim)
  75                return ERR_PTR(-EINVAL);
  76        delim++;
  77        len = strlen(delim);
  78
  79        /* caller has to free the memory */
  80        dst = kstrndup(delim, len, GFP_KERNEL);
  81        if (!dst)
  82                return ERR_PTR(-ENOMEM);
  83
  84        return dst;
  85}
  86
  87static enum
  88fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
  89                                              const void *data,
  90                                              uint16_t datalen,
  91                                              loff_t object_size)
  92{
  93        struct cifs_fscache_super_auxdata auxdata;
  94        const struct cifs_tcon *tcon = cookie_netfs_data;
  95
  96        if (datalen != sizeof(auxdata))
  97                return FSCACHE_CHECKAUX_OBSOLETE;
  98
  99        memset(&auxdata, 0, sizeof(auxdata));
 100        auxdata.resource_id = tcon->resource_id;
 101
 102        if (memcmp(data, &auxdata, datalen) != 0)
 103                return FSCACHE_CHECKAUX_OBSOLETE;
 104
 105        return FSCACHE_CHECKAUX_OKAY;
 106}
 107
 108/*
 109 * Superblock object for FS-Cache
 110 */
 111const struct fscache_cookie_def cifs_fscache_super_index_def = {
 112        .name = "CIFS.super",
 113        .type = FSCACHE_COOKIE_TYPE_INDEX,
 114        .check_aux = cifs_fscache_super_check_aux,
 115};
 116
 117static enum
 118fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
 119                                              const void *data,
 120                                              uint16_t datalen,
 121                                              loff_t object_size)
 122{
 123        struct cifs_fscache_inode_auxdata auxdata;
 124        struct cifsInodeInfo *cifsi = cookie_netfs_data;
 125
 126        if (datalen != sizeof(auxdata))
 127                return FSCACHE_CHECKAUX_OBSOLETE;
 128
 129        memset(&auxdata, 0, sizeof(auxdata));
 130        auxdata.eof = cifsi->server_eof;
 131        auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
 132        auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec;
 133        auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec;
 134        auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec;
 135
 136        if (memcmp(data, &auxdata, datalen) != 0)
 137                return FSCACHE_CHECKAUX_OBSOLETE;
 138
 139        return FSCACHE_CHECKAUX_OKAY;
 140}
 141
 142const struct fscache_cookie_def cifs_fscache_inode_object_def = {
 143        .name           = "CIFS.uniqueid",
 144        .type           = FSCACHE_COOKIE_TYPE_DATAFILE,
 145        .check_aux      = cifs_fscache_inode_check_aux,
 146};
 147