1From: Suresh Jayaraman <sjayaraman@suse.de> 2Subject: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them 3Date: Tue, 22 Jun 2010 20:53:33 +0530 4Lines: 318 5Message-ID: <1277220214-3597-1-git-send-email-sjayaraman@suse.de> 6References: <yes> 7Cc: linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org, 8 linux-kernel@vger.kernel.org, David Howells <dhowells@redhat.com> 9To: Steve French <smfrench@gmail.com> 10X-From: linux-kernel-owner@vger.kernel.org Tue Jun 22 17:45:30 2010 11Return-path: <linux-kernel-owner@vger.kernel.org> 12Envelope-to: glk-linux-kernel-3@lo.gmane.org 13Received: from vger.kernel.org ([209.132.180.67]) 14 by lo.gmane.org with esmtp (Exim 4.69) 15 (envelope-from <linux-kernel-owner@vger.kernel.org>) 16 id 1OR5fF-0000Ka-Na 17 for glk-linux-kernel-3@lo.gmane.org; Tue, 22 Jun 2010 17:45:30 +0200 18Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand 19 id S1755952Ab0FVPpP (ORCPT <rfc822;glk-linux-kernel-3@m.gmane.org>); 20 Tue, 22 Jun 2010 11:45:15 -0400 21Received: from victor.provo.novell.com ([137.65.250.26]:59441 "EHLO 22 victor.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org 23 with ESMTP id S1751397Ab0FVPoA (ORCPT 24 <rfc822;groupwise-SJayaraman@novell.com:0:0>); 25 Tue, 22 Jun 2010 11:44:00 -0400 26Received: from localhost (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) 27 by victor.provo.novell.com with ESMTP; Tue, 22 Jun 2010 09:23:35 -0600 28X-Mailer: git-send-email 1.6.4.2 29In-Reply-To: <yes> 30Sender: linux-kernel-owner@vger.kernel.org 31Precedence: bulk 32List-ID: <linux-kernel.vger.kernel.org> 33X-Mailing-List: linux-kernel@vger.kernel.org 34Archived-At: <http://permalink.gmane.org/gmane.linux.kernel/1001765> 35 36Define inode-level data storage objects (managed by cifsInodeInfo structs). 37Each inode-level object is created in a super-block level object and is itself 38a data storage object in to which pages from the inode are stored. 39 40The inode object is keyed by UniqueId. The coherency data being used is 41LastWriteTime and the file size. 42 43Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de> 44--- 45 fs/cifs/cache.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 46 fs/cifs/cifsfs.c | 7 ++++ 47 fs/cifs/cifsglob.h | 3 + 48 fs/cifs/file.c | 6 +++ 49 fs/cifs/fscache.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ 50 fs/cifs/fscache.h | 12 +++++++ 51 fs/cifs/inode.c | 4 ++ 52 7 files changed, 180 insertions(+) 53 54Index: cifs-2.6/fs/cifs/cache.c 55=================================================================== 56--- cifs-2.6.orig/fs/cifs/cache.c 57+++ cifs-2.6/fs/cifs/cache.c 58@@ -138,3 +138,83 @@ const struct fscache_cookie_def cifs_fsc 59 .get_key = cifs_super_get_key, 60 }; 61 62+/* 63+ * Auxiliary data attached to CIFS inode within the cache 64+ */ 65+struct cifs_fscache_inode_auxdata { 66+ struct timespec last_write_time; 67+ loff_t size; 68+}; 69+ 70+static uint16_t cifs_fscache_inode_get_key(const void *cookie_netfs_data, 71+ void *buffer, uint16_t maxbuf) 72+{ 73+ const struct cifsInodeInfo *cifsi = cookie_netfs_data; 74+ uint16_t keylen; 75+ 76+ /* use the UniqueId as the key */ 77+ keylen = sizeof(cifsi->uniqueid); 78+ if (keylen > maxbuf) 79+ keylen = 0; 80+ else 81+ memcpy(buffer, &cifsi->uniqueid, keylen); 82+ 83+ return keylen; 84+} 85+ 86+static void 87+cifs_fscache_inode_get_attr(const void *cookie_netfs_data, uint64_t *size) 88+{ 89+ const struct cifsInodeInfo *cifsi = cookie_netfs_data; 90+ 91+ *size = cifsi->vfs_inode.i_size; 92+} 93+ 94+static uint16_t 95+cifs_fscache_inode_get_aux(const void *cookie_netfs_data, void *buffer, 96+ uint16_t maxbuf) 97+{ 98+ struct cifs_fscache_inode_auxdata auxdata; 99+ const struct cifsInodeInfo *cifsi = cookie_netfs_data; 100+ 101+ memset(&auxdata, 0, sizeof(auxdata)); 102+ auxdata.size = cifsi->vfs_inode.i_size; 103+ auxdata.last_write_time = cifsi->vfs_inode.i_ctime; 104+ 105+ if (maxbuf > sizeof(auxdata)) 106+ maxbuf = sizeof(auxdata); 107+ 108+ memcpy(buffer, &auxdata, maxbuf); 109+ 110+ return maxbuf; 111+} 112+ 113+static enum 114+fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data, 115+ const void *data, 116+ uint16_t datalen) 117+{ 118+ struct cifs_fscache_inode_auxdata auxdata; 119+ struct cifsInodeInfo *cifsi = cookie_netfs_data; 120+ 121+ if (datalen != sizeof(auxdata)) 122+ return FSCACHE_CHECKAUX_OBSOLETE; 123+ 124+ memset(&auxdata, 0, sizeof(auxdata)); 125+ auxdata.size = cifsi->vfs_inode.i_size; 126+ auxdata.last_write_time = cifsi->vfs_inode.i_ctime; 127+ 128+ if (memcmp(data, &auxdata, datalen) != 0) 129+ return FSCACHE_CHECKAUX_OBSOLETE; 130+ 131+ return FSCACHE_CHECKAUX_OKAY; 132+} 133+ 134+const struct fscache_cookie_def cifs_fscache_inode_object_def = { 135+ .name = "CIFS.uniqueid", 136+ .type = FSCACHE_COOKIE_TYPE_DATAFILE, 137+ .get_key = cifs_fscache_inode_get_key, 138+ .get_attr = cifs_fscache_inode_get_attr, 139+ .get_aux = cifs_fscache_inode_get_aux, 140+ .check_aux = cifs_fscache_inode_check_aux, 141+}; 142Index: cifs-2.6/fs/cifs/cifsfs.c 143=================================================================== 144--- cifs-2.6.orig/fs/cifs/cifsfs.c 145+++ cifs-2.6/fs/cifs/cifsfs.c 146@@ -330,6 +330,12 @@ cifs_destroy_inode(struct inode *inode) 147 } 148 149 static void 150+cifs_clear_inode(struct inode *inode) 151+{ 152+ cifs_fscache_release_inode_cookie(inode); 153+} 154+ 155+static void 156 cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) 157 { 158 seq_printf(s, ",addr="); 159@@ -490,6 +496,7 @@ static const struct super_operations cif 160 .alloc_inode = cifs_alloc_inode, 161 .destroy_inode = cifs_destroy_inode, 162 .drop_inode = cifs_drop_inode, 163+ .clear_inode = cifs_clear_inode, 164 /* .delete_inode = cifs_delete_inode, */ /* Do not need above 165 function unless later we add lazy close of inodes or unless the 166 kernel forgets to call us with the same number of releases (closes) 167Index: cifs-2.6/fs/cifs/cifsglob.h 168=================================================================== 169--- cifs-2.6.orig/fs/cifs/cifsglob.h 170+++ cifs-2.6/fs/cifs/cifsglob.h 171@@ -407,6 +407,9 @@ struct cifsInodeInfo { 172 bool invalid_mapping:1; /* pagecache is invalid */ 173 u64 server_eof; /* current file size on server */ 174 u64 uniqueid; /* server inode number */ 175+#ifdef CONFIG_CIFS_FSCACHE 176+ struct fscache_cookie *fscache; 177+#endif 178 struct inode vfs_inode; 179 }; 180 181Index: cifs-2.6/fs/cifs/file.c 182=================================================================== 183--- cifs-2.6.orig/fs/cifs/file.c 184+++ cifs-2.6/fs/cifs/file.c 185@@ -40,6 +40,7 @@ 186 #include "cifs_unicode.h" 187 #include "cifs_debug.h" 188 #include "cifs_fs_sb.h" 189+#include "fscache.h" 190 191 static inline int cifs_convert_flags(unsigned int flags) 192 { 193@@ -282,6 +283,9 @@ int cifs_open(struct inode *inode, struc 194 CIFSSMBClose(xid, tcon, netfid); 195 rc = -ENOMEM; 196 } 197+ 198+ cifs_fscache_set_inode_cookie(inode, file); 199+ 200 goto out; 201 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 202 if (tcon->ses->serverNOS) 203@@ -373,6 +377,8 @@ int cifs_open(struct inode *inode, struc 204 goto out; 205 } 206 207+ cifs_fscache_set_inode_cookie(inode, file); 208+ 209 if (oplock & CIFS_CREATE_ACTION) { 210 /* time to set mode which we can not set earlier due to 211 problems creating new read-only files */ 212Index: cifs-2.6/fs/cifs/fscache.c 213=================================================================== 214--- cifs-2.6.orig/fs/cifs/fscache.c 215+++ cifs-2.6/fs/cifs/fscache.c 216@@ -62,3 +62,71 @@ void cifs_fscache_release_super_cookie(s 217 tcon->fscache = NULL; 218 } 219 220+static void cifs_fscache_enable_inode_cookie(struct inode *inode) 221+{ 222+ struct cifsInodeInfo *cifsi = CIFS_I(inode); 223+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 224+ 225+ if (cifsi->fscache) 226+ return; 227+ 228+ cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache, 229+ &cifs_fscache_inode_object_def, 230+ cifsi); 231+ cFYI(1, "CIFS: got FH cookie (0x%p/0x%p/0x%p)\n", 232+ cifs_sb->tcon, cifsi, cifsi->fscache); 233+} 234+ 235+void cifs_fscache_release_inode_cookie(struct inode *inode) 236+{ 237+ struct cifsInodeInfo *cifsi = CIFS_I(inode); 238+ 239+ if (cifsi->fscache) { 240+ cFYI(1, "CIFS releasing inode cookie (0x%p/0x%p)\n", 241+ cifsi, cifsi->fscache); 242+ fscache_relinquish_cookie(cifsi->fscache, 0); 243+ cifsi->fscache = NULL; 244+ } 245+} 246+ 247+static void cifs_fscache_disable_inode_cookie(struct inode *inode) 248+{ 249+ struct cifsInodeInfo *cifsi = CIFS_I(inode); 250+ 251+ if (cifsi->fscache) { 252+ cFYI(1, "CIFS disabling inode cookie (0x%p/0x%p)\n", 253+ cifsi, cifsi->fscache); 254+ fscache_relinquish_cookie(cifsi->fscache, 1); 255+ cifsi->fscache = NULL; 256+ } 257+} 258+ 259+void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp) 260+{ 261+ /* BB: parallel opens - need locking? */ 262+ if ((filp->f_flags & O_ACCMODE) != O_RDONLY) 263+ cifs_fscache_disable_inode_cookie(inode); 264+ else { 265+ cifs_fscache_enable_inode_cookie(inode); 266+ cFYI(1, "CIFS: fscache inode cookie set\n"); 267+ } 268+} 269+ 270+void cifs_fscache_reset_inode_cookie(struct inode *inode) 271+{ 272+ struct cifsInodeInfo *cifsi = CIFS_I(inode); 273+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 274+ struct fscache_cookie *old = cifsi->fscache; 275+ 276+ if (cifsi->fscache) { 277+ /* retire the current fscache cache and get a new one */ 278+ fscache_relinquish_cookie(cifsi->fscache, 1); 279+ 280+ cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache, 281+ &cifs_fscache_inode_object_def, 282+ cifsi); 283+ cFYI(1, "CIFS: new cookie (0x%p/0x%p) oldcookie 0x%p\n", 284+ cifsi, cifsi->fscache, old); 285+ } 286+} 287+ 288Index: cifs-2.6/fs/cifs/fscache.h 289=================================================================== 290--- cifs-2.6.orig/fs/cifs/fscache.h 291+++ cifs-2.6/fs/cifs/fscache.h 292@@ -29,6 +29,8 @@ 293 extern struct fscache_netfs cifs_fscache_netfs; 294 extern const struct fscache_cookie_def cifs_fscache_server_index_def; 295 extern const struct fscache_cookie_def cifs_fscache_super_index_def; 296+extern const struct fscache_cookie_def cifs_fscache_inode_object_def; 297+ 298 299 extern int cifs_fscache_register(void); 300 extern void cifs_fscache_unregister(void); 301@@ -41,6 +43,10 @@ extern void cifs_fscache_release_client_ 302 extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *); 303 extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *); 304 305+extern void cifs_fscache_release_inode_cookie(struct inode *); 306+extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *); 307+extern void cifs_fscache_reset_inode_cookie(struct inode *); 308+ 309 #else /* CONFIG_CIFS_FSCACHE */ 310 static inline int cifs_fscache_register(void) { return 0; } 311 static inline void cifs_fscache_unregister(void) {} 312@@ -53,6 +59,12 @@ static inline void cifs_fscache_get_supe 313 static inline void 314 cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {} 315 316+static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {} 317+static inline void cifs_fscache_set_inode_cookie(struct inode *inode, 318+ struct file *filp) {} 319+static inline void cifs_fscache_reset_inode_cookie(struct inode *inode) {} 320+ 321+ 322 #endif /* CONFIG_CIFS_FSCACHE */ 323 324 #endif /* _CIFS_FSCACHE_H */ 325Index: cifs-2.6/fs/cifs/inode.c 326=================================================================== 327--- cifs-2.6.orig/fs/cifs/inode.c 328+++ cifs-2.6/fs/cifs/inode.c 329@@ -29,6 +29,7 @@ 330 #include "cifsproto.h" 331 #include "cifs_debug.h" 332 #include "cifs_fs_sb.h" 333+#include "fscache.h" 334 335 336 static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) 337@@ -776,6 +777,8 @@ retry_iget5_locked: 338 inode->i_flags |= S_NOATIME | S_NOCMTIME; 339 if (inode->i_state & I_NEW) { 340 inode->i_ino = hash; 341+ /* initialize per-inode cache cookie pointer */ 342+ CIFS_I(inode)->fscache = NULL; 343 unlock_new_inode(inode); 344 } 345 } 346@@ -1568,6 +1571,7 @@ cifs_invalidate_mapping(struct inode *in 347 cifs_i->write_behind_rc = rc; 348 } 349 invalidate_remote_inode(inode); 350+ cifs_fscache_reset_inode_cookie(inode); 351 } 352 353 int cifs_revalidate_file(struct file *filp) 354 355 356