^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/cifs/fscache.c - CIFS filesystem cache interface
^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) * Author(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 "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "cifs_fs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Key layout of CIFS server cache index object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct cifs_server_key {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) uint16_t family; /* address family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) __be16 port; /* IP port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) } hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct in_addr ipv4_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct in6_addr ipv6_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) } __packed;
^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) * Get a cookie for a server object keyed by {IPaddress,port,family} tuple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct cifs_server_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) uint16_t key_len = sizeof(key.hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) memset(&key, 0, sizeof(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Should not be a problem as sin_family/sin6_family overlays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * sa_family field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) key.hdr.family = sa->sa_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) switch (sa->sa_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) key.hdr.port = addr->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) key.ipv4_addr = addr->sin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) key_len += sizeof(key.ipv4_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) key.hdr.port = addr6->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) key.ipv6_addr = addr6->sin6_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) key_len += sizeof(key.ipv6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) server->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) server->fscache =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) &cifs_fscache_server_index_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) &key, key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) server, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) __func__, server, server->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __func__, server, server->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) fscache_relinquish_cookie(server->fscache, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) server->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) char *sharename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct cifs_fscache_super_auxdata auxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) sharename = extract_sharename(tcon->treeName);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (IS_ERR(sharename)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) tcon->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) memset(&auxdata, 0, sizeof(auxdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) auxdata.resource_id = tcon->resource_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) auxdata.vol_create_time = tcon->vol_create_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) auxdata.vol_serial_number = tcon->vol_serial_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) tcon->fscache =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) fscache_acquire_cookie(server->fscache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) &cifs_fscache_super_index_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) sharename, strlen(sharename),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) &auxdata, sizeof(auxdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) tcon, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) kfree(sharename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) __func__, server->fscache, tcon->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct cifs_fscache_super_auxdata auxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) memset(&auxdata, 0, sizeof(auxdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) auxdata.resource_id = tcon->resource_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) auxdata.vol_create_time = tcon->vol_create_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) auxdata.vol_serial_number = tcon->vol_serial_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) fscache_relinquish_cookie(tcon->fscache, &auxdata, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) tcon->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static void cifs_fscache_acquire_inode_cookie(struct cifsInodeInfo *cifsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct cifs_fscache_inode_auxdata auxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) memset(&auxdata, 0, sizeof(auxdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) auxdata.eof = cifsi->server_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) cifsi->fscache =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) fscache_acquire_cookie(tcon->fscache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) &cifs_fscache_inode_object_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) &cifsi->uniqueid, sizeof(cifsi->uniqueid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) &auxdata, sizeof(auxdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) cifsi, cifsi->vfs_inode.i_size, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void cifs_fscache_enable_inode_cookie(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct cifsInodeInfo *cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (cifsi->fscache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) cifs_fscache_acquire_inode_cookie(cifsi, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __func__, tcon->fscache, cifsi->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) void cifs_fscache_release_inode_cookie(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct cifs_fscache_inode_auxdata auxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct cifsInodeInfo *cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (cifsi->fscache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) memset(&auxdata, 0, sizeof(auxdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) auxdata.eof = cifsi->server_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) fscache_relinquish_cookie(cifsi->fscache, &auxdata, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) cifsi->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static void cifs_fscache_disable_inode_cookie(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct cifsInodeInfo *cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (cifsi->fscache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) fscache_uncache_all_inode_pages(cifsi->fscache, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) fscache_relinquish_cookie(cifsi->fscache, NULL, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) cifsi->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) cifs_fscache_disable_inode_cookie(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) cifs_fscache_enable_inode_cookie(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void cifs_fscache_reset_inode_cookie(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct cifsInodeInfo *cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct fscache_cookie *old = cifsi->fscache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (cifsi->fscache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* retire the current fscache cache and get a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) fscache_relinquish_cookie(cifsi->fscache, NULL, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) cifs_fscache_acquire_inode_cookie(cifsi, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) __func__, cifsi->fscache, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int cifs_fscache_release_page(struct page *page, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (PageFsCache(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct inode *inode = page->mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct cifsInodeInfo *cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) __func__, page, cifsi->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (!fscache_maybe_release_page(cifsi->fscache, page, gfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) cifs_dbg(FYI, "%s: (0x%p/%d)\n", __func__, page, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * Retrieve a page from FS-Cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) cifs_dbg(FYI, "%s: (fsc:%p, p:%p, i:0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) __func__, CIFS_I(inode)->fscache, page, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) cifs_readpage_from_fscache_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case 0: /* page found in fscache, read submitted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) cifs_dbg(FYI, "%s: submitted\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case -ENOBUFS: /* page won't be cached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case -ENODATA: /* page not in cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) cifs_dbg(FYI, "%s: %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) cifs_dbg(VFS, "unknown error ret = %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * Retrieve a set of pages from FS-Cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int __cifs_readpages_from_fscache(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct address_space *mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct list_head *pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned *nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) cifs_dbg(FYI, "%s: (0x%p/%u/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) __func__, CIFS_I(inode)->fscache, *nr_pages, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pages, nr_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) cifs_readpage_from_fscache_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) mapping_gfp_mask(mapping));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case 0: /* read submitted to the cache for all pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) cifs_dbg(FYI, "%s: submitted\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case -ENOBUFS: /* some pages are not cached and can't be */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case -ENODATA: /* some pages are not cached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) cifs_dbg(FYI, "%s: no page\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) cifs_dbg(FYI, "unknown error ret = %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct cifsInodeInfo *cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) cifs_dbg(FYI, "%s: (fsc: %p, p: %p, i: %p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) __func__, cifsi->fscache, page, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ret = fscache_write_page(cifsi->fscache, page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) cifsi->vfs_inode.i_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) fscache_uncache_page(cifsi->fscache, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) void __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) cifs_dbg(FYI, "%s: (fsc: %p, i: %p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) __func__, CIFS_I(inode)->fscache, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) fscache_readpages_cancel(CIFS_I(inode)->fscache, pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct cifsInodeInfo *cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct fscache_cookie *cookie = cifsi->fscache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", __func__, page, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) fscache_wait_on_page_write(cookie, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) fscache_uncache_page(cookie, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }