~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/smb/client/fscache.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: LGPL-2.1
  2 /*
  3  *   CIFS filesystem cache interface
  4  *
  5  *   Copyright (c) 2010 Novell, Inc.
  6  *   Author(s): Suresh Jayaraman <sjayaraman@suse.de>
  7  *
  8  */
  9 #include "fscache.h"
 10 #include "cifsglob.h"
 11 #include "cifs_debug.h"
 12 #include "cifs_fs_sb.h"
 13 #include "cifsproto.h"
 14 
 15 /*
 16  * Key for fscache inode.  [!] Contents must match comparisons in cifs_find_inode().
 17  */
 18 struct cifs_fscache_inode_key {
 19 
 20         __le64  uniqueid;       /* server inode number */
 21         __le64  createtime;     /* creation time on server */
 22         u8      type;           /* S_IFMT file type */
 23 } __packed;
 24 
 25 static void cifs_fscache_fill_volume_coherency(
 26         struct cifs_tcon *tcon,
 27         struct cifs_fscache_volume_coherency_data *cd)
 28 {
 29         memset(cd, 0, sizeof(*cd));
 30         cd->resource_id         = cpu_to_le64(tcon->resource_id);
 31         cd->vol_create_time     = tcon->vol_create_time;
 32         cd->vol_serial_number   = cpu_to_le32(tcon->vol_serial_number);
 33 }
 34 
 35 int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
 36 {
 37         struct cifs_fscache_volume_coherency_data cd;
 38         struct TCP_Server_Info *server = tcon->ses->server;
 39         struct fscache_volume *vcookie;
 40         const struct sockaddr *sa = (struct sockaddr *)&server->dstaddr;
 41         size_t slen, i;
 42         char *sharename;
 43         char *key;
 44         int ret = -ENOMEM;
 45 
 46         if (tcon->fscache_acquired)
 47                 return 0;
 48 
 49         mutex_lock(&tcon->fscache_lock);
 50         if (tcon->fscache_acquired) {
 51                 mutex_unlock(&tcon->fscache_lock);
 52                 return 0;
 53         }
 54         tcon->fscache_acquired = true;
 55 
 56         tcon->fscache = NULL;
 57         switch (sa->sa_family) {
 58         case AF_INET:
 59         case AF_INET6:
 60                 break;
 61         default:
 62                 mutex_unlock(&tcon->fscache_lock);
 63                 cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
 64                 return -EINVAL;
 65         }
 66 
 67         memset(&key, 0, sizeof(key));
 68 
 69         sharename = extract_sharename(tcon->tree_name);
 70         if (IS_ERR(sharename)) {
 71                 mutex_unlock(&tcon->fscache_lock);
 72                 cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__);
 73                 return PTR_ERR(sharename);
 74         }
 75 
 76         slen = strlen(sharename);
 77         for (i = 0; i < slen; i++)
 78                 if (sharename[i] == '/')
 79                         sharename[i] = ';';
 80 
 81         key = kasprintf(GFP_KERNEL, "cifs,%pISpc,%s", sa, sharename);
 82         if (!key)
 83                 goto out;
 84 
 85         cifs_fscache_fill_volume_coherency(tcon, &cd);
 86         vcookie = fscache_acquire_volume(key,
 87                                          NULL, /* preferred_cache */
 88                                          &cd, sizeof(cd));
 89         cifs_dbg(FYI, "%s: (%s/0x%p)\n", __func__, key, vcookie);
 90         if (IS_ERR(vcookie)) {
 91                 if (vcookie != ERR_PTR(-EBUSY)) {
 92                         ret = PTR_ERR(vcookie);
 93                         goto out_2;
 94                 }
 95                 pr_err("Cache volume key already in use (%s)\n", key);
 96                 vcookie = NULL;
 97                 trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
 98                                     netfs_trace_tcon_ref_see_fscache_collision);
 99         } else {
100                 trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
101                                     netfs_trace_tcon_ref_see_fscache_okay);
102         }
103 
104         tcon->fscache = vcookie;
105         ret = 0;
106 out_2:
107         kfree(key);
108 out:
109         kfree(sharename);
110         mutex_unlock(&tcon->fscache_lock);
111         return ret;
112 }
113 
114 void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
115 {
116         struct cifs_fscache_volume_coherency_data cd;
117 
118         cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache);
119 
120         cifs_fscache_fill_volume_coherency(tcon, &cd);
121         fscache_relinquish_volume(tcon->fscache, &cd, false);
122         tcon->fscache = NULL;
123         trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
124                             netfs_trace_tcon_ref_see_fscache_relinq);
125 }
126 
127 void cifs_fscache_get_inode_cookie(struct inode *inode)
128 {
129         struct cifs_fscache_inode_coherency_data cd;
130         struct cifs_fscache_inode_key key;
131         struct cifsInodeInfo *cifsi = CIFS_I(inode);
132         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
133         struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
134 
135         key.uniqueid    = cpu_to_le64(cifsi->uniqueid);
136         key.createtime  = cpu_to_le64(cifsi->createtime);
137         key.type        = (inode->i_mode & S_IFMT) >> 12;
138         cifs_fscache_fill_coherency(&cifsi->netfs.inode, &cd);
139 
140         cifsi->netfs.cache =
141                 fscache_acquire_cookie(tcon->fscache, 0,
142                                        &key, sizeof(key),
143                                        &cd, sizeof(cd),
144                                        i_size_read(&cifsi->netfs.inode));
145         if (cifsi->netfs.cache)
146                 mapping_set_release_always(inode->i_mapping);
147 }
148 
149 void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update)
150 {
151         if (update) {
152                 struct cifs_fscache_inode_coherency_data cd;
153                 loff_t i_size = i_size_read(inode);
154 
155                 cifs_fscache_fill_coherency(inode, &cd);
156                 fscache_unuse_cookie(cifs_inode_cookie(inode), &cd, &i_size);
157         } else {
158                 fscache_unuse_cookie(cifs_inode_cookie(inode), NULL, NULL);
159         }
160 }
161 
162 void cifs_fscache_release_inode_cookie(struct inode *inode)
163 {
164         struct cifsInodeInfo *cifsi = CIFS_I(inode);
165         struct fscache_cookie *cookie = cifs_inode_cookie(inode);
166 
167         if (cookie) {
168                 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cookie);
169                 fscache_relinquish_cookie(cookie, false);
170                 cifsi->netfs.cache = NULL;
171         }
172 }
173 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php