1*38c8a9a5SSteve French // SPDX-License-Identifier: LGPL-2.1 2*38c8a9a5SSteve French /* 3*38c8a9a5SSteve French * CIFS filesystem cache interface 4*38c8a9a5SSteve French * 5*38c8a9a5SSteve French * Copyright (c) 2010 Novell, Inc. 6*38c8a9a5SSteve French * Author(s): Suresh Jayaraman <sjayaraman@suse.de> 7*38c8a9a5SSteve French * 8*38c8a9a5SSteve French */ 9*38c8a9a5SSteve French #include "fscache.h" 10*38c8a9a5SSteve French #include "cifsglob.h" 11*38c8a9a5SSteve French #include "cifs_debug.h" 12*38c8a9a5SSteve French #include "cifs_fs_sb.h" 13*38c8a9a5SSteve French #include "cifsproto.h" 14*38c8a9a5SSteve French 15*38c8a9a5SSteve French static void cifs_fscache_fill_volume_coherency( 16*38c8a9a5SSteve French struct cifs_tcon *tcon, 17*38c8a9a5SSteve French struct cifs_fscache_volume_coherency_data *cd) 18*38c8a9a5SSteve French { 19*38c8a9a5SSteve French memset(cd, 0, sizeof(*cd)); 20*38c8a9a5SSteve French cd->resource_id = cpu_to_le64(tcon->resource_id); 21*38c8a9a5SSteve French cd->vol_create_time = tcon->vol_create_time; 22*38c8a9a5SSteve French cd->vol_serial_number = cpu_to_le32(tcon->vol_serial_number); 23*38c8a9a5SSteve French } 24*38c8a9a5SSteve French 25*38c8a9a5SSteve French int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) 26*38c8a9a5SSteve French { 27*38c8a9a5SSteve French struct cifs_fscache_volume_coherency_data cd; 28*38c8a9a5SSteve French struct TCP_Server_Info *server = tcon->ses->server; 29*38c8a9a5SSteve French struct fscache_volume *vcookie; 30*38c8a9a5SSteve French const struct sockaddr *sa = (struct sockaddr *)&server->dstaddr; 31*38c8a9a5SSteve French size_t slen, i; 32*38c8a9a5SSteve French char *sharename; 33*38c8a9a5SSteve French char *key; 34*38c8a9a5SSteve French int ret = -ENOMEM; 35*38c8a9a5SSteve French 36*38c8a9a5SSteve French tcon->fscache = NULL; 37*38c8a9a5SSteve French switch (sa->sa_family) { 38*38c8a9a5SSteve French case AF_INET: 39*38c8a9a5SSteve French case AF_INET6: 40*38c8a9a5SSteve French break; 41*38c8a9a5SSteve French default: 42*38c8a9a5SSteve French cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family); 43*38c8a9a5SSteve French return -EINVAL; 44*38c8a9a5SSteve French } 45*38c8a9a5SSteve French 46*38c8a9a5SSteve French memset(&key, 0, sizeof(key)); 47*38c8a9a5SSteve French 48*38c8a9a5SSteve French sharename = extract_sharename(tcon->tree_name); 49*38c8a9a5SSteve French if (IS_ERR(sharename)) { 50*38c8a9a5SSteve French cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__); 51*38c8a9a5SSteve French return -EINVAL; 52*38c8a9a5SSteve French } 53*38c8a9a5SSteve French 54*38c8a9a5SSteve French slen = strlen(sharename); 55*38c8a9a5SSteve French for (i = 0; i < slen; i++) 56*38c8a9a5SSteve French if (sharename[i] == '/') 57*38c8a9a5SSteve French sharename[i] = ';'; 58*38c8a9a5SSteve French 59*38c8a9a5SSteve French key = kasprintf(GFP_KERNEL, "cifs,%pISpc,%s", sa, sharename); 60*38c8a9a5SSteve French if (!key) 61*38c8a9a5SSteve French goto out; 62*38c8a9a5SSteve French 63*38c8a9a5SSteve French cifs_fscache_fill_volume_coherency(tcon, &cd); 64*38c8a9a5SSteve French vcookie = fscache_acquire_volume(key, 65*38c8a9a5SSteve French NULL, /* preferred_cache */ 66*38c8a9a5SSteve French &cd, sizeof(cd)); 67*38c8a9a5SSteve French cifs_dbg(FYI, "%s: (%s/0x%p)\n", __func__, key, vcookie); 68*38c8a9a5SSteve French if (IS_ERR(vcookie)) { 69*38c8a9a5SSteve French if (vcookie != ERR_PTR(-EBUSY)) { 70*38c8a9a5SSteve French ret = PTR_ERR(vcookie); 71*38c8a9a5SSteve French goto out_2; 72*38c8a9a5SSteve French } 73*38c8a9a5SSteve French pr_err("Cache volume key already in use (%s)\n", key); 74*38c8a9a5SSteve French vcookie = NULL; 75*38c8a9a5SSteve French } 76*38c8a9a5SSteve French 77*38c8a9a5SSteve French tcon->fscache = vcookie; 78*38c8a9a5SSteve French ret = 0; 79*38c8a9a5SSteve French out_2: 80*38c8a9a5SSteve French kfree(key); 81*38c8a9a5SSteve French out: 82*38c8a9a5SSteve French kfree(sharename); 83*38c8a9a5SSteve French return ret; 84*38c8a9a5SSteve French } 85*38c8a9a5SSteve French 86*38c8a9a5SSteve French void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) 87*38c8a9a5SSteve French { 88*38c8a9a5SSteve French struct cifs_fscache_volume_coherency_data cd; 89*38c8a9a5SSteve French 90*38c8a9a5SSteve French cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache); 91*38c8a9a5SSteve French 92*38c8a9a5SSteve French cifs_fscache_fill_volume_coherency(tcon, &cd); 93*38c8a9a5SSteve French fscache_relinquish_volume(tcon->fscache, &cd, false); 94*38c8a9a5SSteve French tcon->fscache = NULL; 95*38c8a9a5SSteve French } 96*38c8a9a5SSteve French 97*38c8a9a5SSteve French void cifs_fscache_get_inode_cookie(struct inode *inode) 98*38c8a9a5SSteve French { 99*38c8a9a5SSteve French struct cifs_fscache_inode_coherency_data cd; 100*38c8a9a5SSteve French struct cifsInodeInfo *cifsi = CIFS_I(inode); 101*38c8a9a5SSteve French struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 102*38c8a9a5SSteve French struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 103*38c8a9a5SSteve French 104*38c8a9a5SSteve French cifs_fscache_fill_coherency(&cifsi->netfs.inode, &cd); 105*38c8a9a5SSteve French 106*38c8a9a5SSteve French cifsi->netfs.cache = 107*38c8a9a5SSteve French fscache_acquire_cookie(tcon->fscache, 0, 108*38c8a9a5SSteve French &cifsi->uniqueid, sizeof(cifsi->uniqueid), 109*38c8a9a5SSteve French &cd, sizeof(cd), 110*38c8a9a5SSteve French i_size_read(&cifsi->netfs.inode)); 111*38c8a9a5SSteve French } 112*38c8a9a5SSteve French 113*38c8a9a5SSteve French void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) 114*38c8a9a5SSteve French { 115*38c8a9a5SSteve French if (update) { 116*38c8a9a5SSteve French struct cifs_fscache_inode_coherency_data cd; 117*38c8a9a5SSteve French loff_t i_size = i_size_read(inode); 118*38c8a9a5SSteve French 119*38c8a9a5SSteve French cifs_fscache_fill_coherency(inode, &cd); 120*38c8a9a5SSteve French fscache_unuse_cookie(cifs_inode_cookie(inode), &cd, &i_size); 121*38c8a9a5SSteve French } else { 122*38c8a9a5SSteve French fscache_unuse_cookie(cifs_inode_cookie(inode), NULL, NULL); 123*38c8a9a5SSteve French } 124*38c8a9a5SSteve French } 125*38c8a9a5SSteve French 126*38c8a9a5SSteve French void cifs_fscache_release_inode_cookie(struct inode *inode) 127*38c8a9a5SSteve French { 128*38c8a9a5SSteve French struct cifsInodeInfo *cifsi = CIFS_I(inode); 129*38c8a9a5SSteve French struct fscache_cookie *cookie = cifs_inode_cookie(inode); 130*38c8a9a5SSteve French 131*38c8a9a5SSteve French if (cookie) { 132*38c8a9a5SSteve French cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cookie); 133*38c8a9a5SSteve French fscache_relinquish_cookie(cookie, false); 134*38c8a9a5SSteve French cifsi->netfs.cache = NULL; 135*38c8a9a5SSteve French } 136*38c8a9a5SSteve French } 137*38c8a9a5SSteve French 138*38c8a9a5SSteve French /* 139*38c8a9a5SSteve French * Fallback page reading interface. 140*38c8a9a5SSteve French */ 141*38c8a9a5SSteve French static int fscache_fallback_read_page(struct inode *inode, struct page *page) 142*38c8a9a5SSteve French { 143*38c8a9a5SSteve French struct netfs_cache_resources cres; 144*38c8a9a5SSteve French struct fscache_cookie *cookie = cifs_inode_cookie(inode); 145*38c8a9a5SSteve French struct iov_iter iter; 146*38c8a9a5SSteve French struct bio_vec bvec; 147*38c8a9a5SSteve French int ret; 148*38c8a9a5SSteve French 149*38c8a9a5SSteve French memset(&cres, 0, sizeof(cres)); 150*38c8a9a5SSteve French bvec_set_page(&bvec, page, PAGE_SIZE, 0); 151*38c8a9a5SSteve French iov_iter_bvec(&iter, ITER_DEST, &bvec, 1, PAGE_SIZE); 152*38c8a9a5SSteve French 153*38c8a9a5SSteve French ret = fscache_begin_read_operation(&cres, cookie); 154*38c8a9a5SSteve French if (ret < 0) 155*38c8a9a5SSteve French return ret; 156*38c8a9a5SSteve French 157*38c8a9a5SSteve French ret = fscache_read(&cres, page_offset(page), &iter, NETFS_READ_HOLE_FAIL, 158*38c8a9a5SSteve French NULL, NULL); 159*38c8a9a5SSteve French fscache_end_operation(&cres); 160*38c8a9a5SSteve French return ret; 161*38c8a9a5SSteve French } 162*38c8a9a5SSteve French 163*38c8a9a5SSteve French /* 164*38c8a9a5SSteve French * Fallback page writing interface. 165*38c8a9a5SSteve French */ 166*38c8a9a5SSteve French static int fscache_fallback_write_pages(struct inode *inode, loff_t start, size_t len, 167*38c8a9a5SSteve French bool no_space_allocated_yet) 168*38c8a9a5SSteve French { 169*38c8a9a5SSteve French struct netfs_cache_resources cres; 170*38c8a9a5SSteve French struct fscache_cookie *cookie = cifs_inode_cookie(inode); 171*38c8a9a5SSteve French struct iov_iter iter; 172*38c8a9a5SSteve French int ret; 173*38c8a9a5SSteve French 174*38c8a9a5SSteve French memset(&cres, 0, sizeof(cres)); 175*38c8a9a5SSteve French iov_iter_xarray(&iter, ITER_SOURCE, &inode->i_mapping->i_pages, start, len); 176*38c8a9a5SSteve French 177*38c8a9a5SSteve French ret = fscache_begin_write_operation(&cres, cookie); 178*38c8a9a5SSteve French if (ret < 0) 179*38c8a9a5SSteve French return ret; 180*38c8a9a5SSteve French 181*38c8a9a5SSteve French ret = cres.ops->prepare_write(&cres, &start, &len, i_size_read(inode), 182*38c8a9a5SSteve French no_space_allocated_yet); 183*38c8a9a5SSteve French if (ret == 0) 184*38c8a9a5SSteve French ret = fscache_write(&cres, start, &iter, NULL, NULL); 185*38c8a9a5SSteve French fscache_end_operation(&cres); 186*38c8a9a5SSteve French return ret; 187*38c8a9a5SSteve French } 188*38c8a9a5SSteve French 189*38c8a9a5SSteve French /* 190*38c8a9a5SSteve French * Retrieve a page from FS-Cache 191*38c8a9a5SSteve French */ 192*38c8a9a5SSteve French int __cifs_readpage_from_fscache(struct inode *inode, struct page *page) 193*38c8a9a5SSteve French { 194*38c8a9a5SSteve French int ret; 195*38c8a9a5SSteve French 196*38c8a9a5SSteve French cifs_dbg(FYI, "%s: (fsc:%p, p:%p, i:0x%p\n", 197*38c8a9a5SSteve French __func__, cifs_inode_cookie(inode), page, inode); 198*38c8a9a5SSteve French 199*38c8a9a5SSteve French ret = fscache_fallback_read_page(inode, page); 200*38c8a9a5SSteve French if (ret < 0) 201*38c8a9a5SSteve French return ret; 202*38c8a9a5SSteve French 203*38c8a9a5SSteve French /* Read completed synchronously */ 204*38c8a9a5SSteve French SetPageUptodate(page); 205*38c8a9a5SSteve French return 0; 206*38c8a9a5SSteve French } 207*38c8a9a5SSteve French 208*38c8a9a5SSteve French void __cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len) 209*38c8a9a5SSteve French { 210*38c8a9a5SSteve French cifs_dbg(FYI, "%s: (fsc: %p, p: %llx, l: %zx, i: %p)\n", 211*38c8a9a5SSteve French __func__, cifs_inode_cookie(inode), pos, len, inode); 212*38c8a9a5SSteve French 213*38c8a9a5SSteve French fscache_fallback_write_pages(inode, pos, len, true); 214*38c8a9a5SSteve French } 215*38c8a9a5SSteve French 216*38c8a9a5SSteve French /* 217*38c8a9a5SSteve French * Query the cache occupancy. 218*38c8a9a5SSteve French */ 219*38c8a9a5SSteve French int __cifs_fscache_query_occupancy(struct inode *inode, 220*38c8a9a5SSteve French pgoff_t first, unsigned int nr_pages, 221*38c8a9a5SSteve French pgoff_t *_data_first, 222*38c8a9a5SSteve French unsigned int *_data_nr_pages) 223*38c8a9a5SSteve French { 224*38c8a9a5SSteve French struct netfs_cache_resources cres; 225*38c8a9a5SSteve French struct fscache_cookie *cookie = cifs_inode_cookie(inode); 226*38c8a9a5SSteve French loff_t start, data_start; 227*38c8a9a5SSteve French size_t len, data_len; 228*38c8a9a5SSteve French int ret; 229*38c8a9a5SSteve French 230*38c8a9a5SSteve French ret = fscache_begin_read_operation(&cres, cookie); 231*38c8a9a5SSteve French if (ret < 0) 232*38c8a9a5SSteve French return ret; 233*38c8a9a5SSteve French 234*38c8a9a5SSteve French start = first * PAGE_SIZE; 235*38c8a9a5SSteve French len = nr_pages * PAGE_SIZE; 236*38c8a9a5SSteve French ret = cres.ops->query_occupancy(&cres, start, len, PAGE_SIZE, 237*38c8a9a5SSteve French &data_start, &data_len); 238*38c8a9a5SSteve French if (ret == 0) { 239*38c8a9a5SSteve French *_data_first = data_start / PAGE_SIZE; 240*38c8a9a5SSteve French *_data_nr_pages = len / PAGE_SIZE; 241*38c8a9a5SSteve French } 242*38c8a9a5SSteve French 243*38c8a9a5SSteve French fscache_end_operation(&cres); 244*38c8a9a5SSteve French return ret; 245*38c8a9a5SSteve French } 246