18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * fs/cifs/fscache.c - CIFS filesystem cache interface 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (c) 2010 Novell, Inc. 58c2ecf20Sopenharmony_ci * Author(s): Suresh Jayaraman <sjayaraman@suse.de> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * This library is free software; you can redistribute it and/or modify 88c2ecf20Sopenharmony_ci * it under the terms of the GNU Lesser General Public License as published 98c2ecf20Sopenharmony_ci * by the Free Software Foundation; either version 2.1 of the License, or 108c2ecf20Sopenharmony_ci * (at your option) any later version. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * This library is distributed in the hope that it will be useful, 138c2ecf20Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 148c2ecf20Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 158c2ecf20Sopenharmony_ci * the GNU Lesser General Public License for more details. 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public License 188c2ecf20Sopenharmony_ci * along with this library; if not, write to the Free Software 198c2ecf20Sopenharmony_ci * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci#include "fscache.h" 228c2ecf20Sopenharmony_ci#include "cifsglob.h" 238c2ecf20Sopenharmony_ci#include "cifs_debug.h" 248c2ecf20Sopenharmony_ci#include "cifs_fs_sb.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * Key layout of CIFS server cache index object 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_cistruct cifs_server_key { 308c2ecf20Sopenharmony_ci struct { 318c2ecf20Sopenharmony_ci uint16_t family; /* address family */ 328c2ecf20Sopenharmony_ci __be16 port; /* IP port */ 338c2ecf20Sopenharmony_ci } hdr; 348c2ecf20Sopenharmony_ci union { 358c2ecf20Sopenharmony_ci struct in_addr ipv4_addr; 368c2ecf20Sopenharmony_ci struct in6_addr ipv6_addr; 378c2ecf20Sopenharmony_ci }; 388c2ecf20Sopenharmony_ci} __packed; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * Get a cookie for a server object keyed by {IPaddress,port,family} tuple 428c2ecf20Sopenharmony_ci */ 438c2ecf20Sopenharmony_civoid cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr; 468c2ecf20Sopenharmony_ci const struct sockaddr_in *addr = (struct sockaddr_in *) sa; 478c2ecf20Sopenharmony_ci const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa; 488c2ecf20Sopenharmony_ci struct cifs_server_key key; 498c2ecf20Sopenharmony_ci uint16_t key_len = sizeof(key.hdr); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci memset(&key, 0, sizeof(key)); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci /* 548c2ecf20Sopenharmony_ci * Should not be a problem as sin_family/sin6_family overlays 558c2ecf20Sopenharmony_ci * sa_family field 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_ci key.hdr.family = sa->sa_family; 588c2ecf20Sopenharmony_ci switch (sa->sa_family) { 598c2ecf20Sopenharmony_ci case AF_INET: 608c2ecf20Sopenharmony_ci key.hdr.port = addr->sin_port; 618c2ecf20Sopenharmony_ci key.ipv4_addr = addr->sin_addr; 628c2ecf20Sopenharmony_ci key_len += sizeof(key.ipv4_addr); 638c2ecf20Sopenharmony_ci break; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci case AF_INET6: 668c2ecf20Sopenharmony_ci key.hdr.port = addr6->sin6_port; 678c2ecf20Sopenharmony_ci key.ipv6_addr = addr6->sin6_addr; 688c2ecf20Sopenharmony_ci key_len += sizeof(key.ipv6_addr); 698c2ecf20Sopenharmony_ci break; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci default: 728c2ecf20Sopenharmony_ci cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family); 738c2ecf20Sopenharmony_ci server->fscache = NULL; 748c2ecf20Sopenharmony_ci return; 758c2ecf20Sopenharmony_ci } 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci server->fscache = 788c2ecf20Sopenharmony_ci fscache_acquire_cookie(cifs_fscache_netfs.primary_index, 798c2ecf20Sopenharmony_ci &cifs_fscache_server_index_def, 808c2ecf20Sopenharmony_ci &key, key_len, 818c2ecf20Sopenharmony_ci NULL, 0, 828c2ecf20Sopenharmony_ci server, 0, true); 838c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 848c2ecf20Sopenharmony_ci __func__, server, server->fscache); 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_civoid cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 908c2ecf20Sopenharmony_ci __func__, server, server->fscache); 918c2ecf20Sopenharmony_ci fscache_relinquish_cookie(server->fscache, NULL, false); 928c2ecf20Sopenharmony_ci server->fscache = NULL; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_civoid cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci struct TCP_Server_Info *server = tcon->ses->server; 988c2ecf20Sopenharmony_ci char *sharename; 998c2ecf20Sopenharmony_ci struct cifs_fscache_super_auxdata auxdata; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci sharename = extract_sharename(tcon->treeName); 1028c2ecf20Sopenharmony_ci if (IS_ERR(sharename)) { 1038c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__); 1048c2ecf20Sopenharmony_ci tcon->fscache = NULL; 1058c2ecf20Sopenharmony_ci return; 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci memset(&auxdata, 0, sizeof(auxdata)); 1098c2ecf20Sopenharmony_ci auxdata.resource_id = tcon->resource_id; 1108c2ecf20Sopenharmony_ci auxdata.vol_create_time = tcon->vol_create_time; 1118c2ecf20Sopenharmony_ci auxdata.vol_serial_number = tcon->vol_serial_number; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci tcon->fscache = 1148c2ecf20Sopenharmony_ci fscache_acquire_cookie(server->fscache, 1158c2ecf20Sopenharmony_ci &cifs_fscache_super_index_def, 1168c2ecf20Sopenharmony_ci sharename, strlen(sharename), 1178c2ecf20Sopenharmony_ci &auxdata, sizeof(auxdata), 1188c2ecf20Sopenharmony_ci tcon, 0, true); 1198c2ecf20Sopenharmony_ci kfree(sharename); 1208c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 1218c2ecf20Sopenharmony_ci __func__, server->fscache, tcon->fscache); 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_civoid cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci struct cifs_fscache_super_auxdata auxdata; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci memset(&auxdata, 0, sizeof(auxdata)); 1298c2ecf20Sopenharmony_ci auxdata.resource_id = tcon->resource_id; 1308c2ecf20Sopenharmony_ci auxdata.vol_create_time = tcon->vol_create_time; 1318c2ecf20Sopenharmony_ci auxdata.vol_serial_number = tcon->vol_serial_number; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache); 1348c2ecf20Sopenharmony_ci fscache_relinquish_cookie(tcon->fscache, &auxdata, false); 1358c2ecf20Sopenharmony_ci tcon->fscache = NULL; 1368c2ecf20Sopenharmony_ci} 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic void cifs_fscache_acquire_inode_cookie(struct cifsInodeInfo *cifsi, 1398c2ecf20Sopenharmony_ci struct cifs_tcon *tcon) 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci struct cifs_fscache_inode_auxdata auxdata; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci memset(&auxdata, 0, sizeof(auxdata)); 1448c2ecf20Sopenharmony_ci auxdata.eof = cifsi->server_eof; 1458c2ecf20Sopenharmony_ci auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; 1468c2ecf20Sopenharmony_ci auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; 1478c2ecf20Sopenharmony_ci auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; 1488c2ecf20Sopenharmony_ci auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci cifsi->fscache = 1518c2ecf20Sopenharmony_ci fscache_acquire_cookie(tcon->fscache, 1528c2ecf20Sopenharmony_ci &cifs_fscache_inode_object_def, 1538c2ecf20Sopenharmony_ci &cifsi->uniqueid, sizeof(cifsi->uniqueid), 1548c2ecf20Sopenharmony_ci &auxdata, sizeof(auxdata), 1558c2ecf20Sopenharmony_ci cifsi, cifsi->vfs_inode.i_size, true); 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic void cifs_fscache_enable_inode_cookie(struct inode *inode) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci struct cifsInodeInfo *cifsi = CIFS_I(inode); 1618c2ecf20Sopenharmony_ci struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1628c2ecf20Sopenharmony_ci struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci if (cifsi->fscache) 1658c2ecf20Sopenharmony_ci return; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)) 1688c2ecf20Sopenharmony_ci return; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci cifs_fscache_acquire_inode_cookie(cifsi, tcon); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n", 1738c2ecf20Sopenharmony_ci __func__, tcon->fscache, cifsi->fscache); 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_civoid cifs_fscache_release_inode_cookie(struct inode *inode) 1778c2ecf20Sopenharmony_ci{ 1788c2ecf20Sopenharmony_ci struct cifs_fscache_inode_auxdata auxdata; 1798c2ecf20Sopenharmony_ci struct cifsInodeInfo *cifsi = CIFS_I(inode); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci if (cifsi->fscache) { 1828c2ecf20Sopenharmony_ci memset(&auxdata, 0, sizeof(auxdata)); 1838c2ecf20Sopenharmony_ci auxdata.eof = cifsi->server_eof; 1848c2ecf20Sopenharmony_ci auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; 1858c2ecf20Sopenharmony_ci auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; 1868c2ecf20Sopenharmony_ci auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; 1878c2ecf20Sopenharmony_ci auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache); 1908c2ecf20Sopenharmony_ci fscache_relinquish_cookie(cifsi->fscache, &auxdata, false); 1918c2ecf20Sopenharmony_ci cifsi->fscache = NULL; 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic void cifs_fscache_disable_inode_cookie(struct inode *inode) 1968c2ecf20Sopenharmony_ci{ 1978c2ecf20Sopenharmony_ci struct cifsInodeInfo *cifsi = CIFS_I(inode); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci if (cifsi->fscache) { 2008c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache); 2018c2ecf20Sopenharmony_ci fscache_uncache_all_inode_pages(cifsi->fscache, inode); 2028c2ecf20Sopenharmony_ci fscache_relinquish_cookie(cifsi->fscache, NULL, true); 2038c2ecf20Sopenharmony_ci cifsi->fscache = NULL; 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci} 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_civoid cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp) 2088c2ecf20Sopenharmony_ci{ 2098c2ecf20Sopenharmony_ci if ((filp->f_flags & O_ACCMODE) != O_RDONLY) 2108c2ecf20Sopenharmony_ci cifs_fscache_disable_inode_cookie(inode); 2118c2ecf20Sopenharmony_ci else 2128c2ecf20Sopenharmony_ci cifs_fscache_enable_inode_cookie(inode); 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_civoid cifs_fscache_reset_inode_cookie(struct inode *inode) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci struct cifsInodeInfo *cifsi = CIFS_I(inode); 2188c2ecf20Sopenharmony_ci struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 2198c2ecf20Sopenharmony_ci struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 2208c2ecf20Sopenharmony_ci struct fscache_cookie *old = cifsi->fscache; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci if (cifsi->fscache) { 2238c2ecf20Sopenharmony_ci /* retire the current fscache cache and get a new one */ 2248c2ecf20Sopenharmony_ci fscache_relinquish_cookie(cifsi->fscache, NULL, true); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci cifs_fscache_acquire_inode_cookie(cifsi, tcon); 2278c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n", 2288c2ecf20Sopenharmony_ci __func__, cifsi->fscache, old); 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ciint cifs_fscache_release_page(struct page *page, gfp_t gfp) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci if (PageFsCache(page)) { 2358c2ecf20Sopenharmony_ci struct inode *inode = page->mapping->host; 2368c2ecf20Sopenharmony_ci struct cifsInodeInfo *cifsi = CIFS_I(inode); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 2398c2ecf20Sopenharmony_ci __func__, page, cifsi->fscache); 2408c2ecf20Sopenharmony_ci if (!fscache_maybe_release_page(cifsi->fscache, page, gfp)) 2418c2ecf20Sopenharmony_ci return 0; 2428c2ecf20Sopenharmony_ci } 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci return 1; 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic void cifs_readpage_from_fscache_complete(struct page *page, void *ctx, 2488c2ecf20Sopenharmony_ci int error) 2498c2ecf20Sopenharmony_ci{ 2508c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p/%d)\n", __func__, page, error); 2518c2ecf20Sopenharmony_ci if (!error) 2528c2ecf20Sopenharmony_ci SetPageUptodate(page); 2538c2ecf20Sopenharmony_ci unlock_page(page); 2548c2ecf20Sopenharmony_ci} 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci/* 2578c2ecf20Sopenharmony_ci * Retrieve a page from FS-Cache 2588c2ecf20Sopenharmony_ci */ 2598c2ecf20Sopenharmony_ciint __cifs_readpage_from_fscache(struct inode *inode, struct page *page) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci int ret; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (fsc:%p, p:%p, i:0x%p\n", 2648c2ecf20Sopenharmony_ci __func__, CIFS_I(inode)->fscache, page, inode); 2658c2ecf20Sopenharmony_ci ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page, 2668c2ecf20Sopenharmony_ci cifs_readpage_from_fscache_complete, 2678c2ecf20Sopenharmony_ci NULL, 2688c2ecf20Sopenharmony_ci GFP_KERNEL); 2698c2ecf20Sopenharmony_ci switch (ret) { 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci case 0: /* page found in fscache, read submitted */ 2728c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: submitted\n", __func__); 2738c2ecf20Sopenharmony_ci return ret; 2748c2ecf20Sopenharmony_ci case -ENOBUFS: /* page won't be cached */ 2758c2ecf20Sopenharmony_ci case -ENODATA: /* page not in cache */ 2768c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: %d\n", __func__, ret); 2778c2ecf20Sopenharmony_ci return 1; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci default: 2808c2ecf20Sopenharmony_ci cifs_dbg(VFS, "unknown error ret = %d\n", ret); 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci return ret; 2838c2ecf20Sopenharmony_ci} 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci/* 2868c2ecf20Sopenharmony_ci * Retrieve a set of pages from FS-Cache 2878c2ecf20Sopenharmony_ci */ 2888c2ecf20Sopenharmony_ciint __cifs_readpages_from_fscache(struct inode *inode, 2898c2ecf20Sopenharmony_ci struct address_space *mapping, 2908c2ecf20Sopenharmony_ci struct list_head *pages, 2918c2ecf20Sopenharmony_ci unsigned *nr_pages) 2928c2ecf20Sopenharmony_ci{ 2938c2ecf20Sopenharmony_ci int ret; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p/%u/0x%p)\n", 2968c2ecf20Sopenharmony_ci __func__, CIFS_I(inode)->fscache, *nr_pages, inode); 2978c2ecf20Sopenharmony_ci ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping, 2988c2ecf20Sopenharmony_ci pages, nr_pages, 2998c2ecf20Sopenharmony_ci cifs_readpage_from_fscache_complete, 3008c2ecf20Sopenharmony_ci NULL, 3018c2ecf20Sopenharmony_ci mapping_gfp_mask(mapping)); 3028c2ecf20Sopenharmony_ci switch (ret) { 3038c2ecf20Sopenharmony_ci case 0: /* read submitted to the cache for all pages */ 3048c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: submitted\n", __func__); 3058c2ecf20Sopenharmony_ci return ret; 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci case -ENOBUFS: /* some pages are not cached and can't be */ 3088c2ecf20Sopenharmony_ci case -ENODATA: /* some pages are not cached */ 3098c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: no page\n", __func__); 3108c2ecf20Sopenharmony_ci return 1; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci default: 3138c2ecf20Sopenharmony_ci cifs_dbg(FYI, "unknown error ret = %d\n", ret); 3148c2ecf20Sopenharmony_ci } 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci return ret; 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_civoid __cifs_readpage_to_fscache(struct inode *inode, struct page *page) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci struct cifsInodeInfo *cifsi = CIFS_I(inode); 3228c2ecf20Sopenharmony_ci int ret; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (fsc: %p, p: %p, i: %p)\n", 3258c2ecf20Sopenharmony_ci __func__, cifsi->fscache, page, inode); 3268c2ecf20Sopenharmony_ci ret = fscache_write_page(cifsi->fscache, page, 3278c2ecf20Sopenharmony_ci cifsi->vfs_inode.i_size, GFP_KERNEL); 3288c2ecf20Sopenharmony_ci if (ret != 0) 3298c2ecf20Sopenharmony_ci fscache_uncache_page(cifsi->fscache, page); 3308c2ecf20Sopenharmony_ci} 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_civoid __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages) 3338c2ecf20Sopenharmony_ci{ 3348c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (fsc: %p, i: %p)\n", 3358c2ecf20Sopenharmony_ci __func__, CIFS_I(inode)->fscache, inode); 3368c2ecf20Sopenharmony_ci fscache_readpages_cancel(CIFS_I(inode)->fscache, pages); 3378c2ecf20Sopenharmony_ci} 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_civoid __cifs_fscache_invalidate_page(struct page *page, struct inode *inode) 3408c2ecf20Sopenharmony_ci{ 3418c2ecf20Sopenharmony_ci struct cifsInodeInfo *cifsi = CIFS_I(inode); 3428c2ecf20Sopenharmony_ci struct fscache_cookie *cookie = cifsi->fscache; 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", __func__, page, cookie); 3458c2ecf20Sopenharmony_ci fscache_wait_on_page_write(cookie, page); 3468c2ecf20Sopenharmony_ci fscache_uncache_page(cookie, page); 3478c2ecf20Sopenharmony_ci} 348