1From: Suresh Jayaraman <sjayaraman@suse.de> 2Subject: [RFC][PATCH 07/10] cifs: FS-Cache page management 3Date: Tue, 22 Jun 2010 20:53:48 +0530 4Lines: 175 5Message-ID: <1277220228-3635-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:44:27 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 1OR5eF-0008G7-BK 17 for glk-linux-kernel-3@lo.gmane.org; Tue, 22 Jun 2010 17:44:27 +0200 18Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand 19 id S1754757Ab0FVPoS (ORCPT <rfc822;glk-linux-kernel-3@m.gmane.org>); 20 Tue, 22 Jun 2010 11:44:18 -0400 21Received: from victor.provo.novell.com ([137.65.250.26]:54214 "EHLO 22 victor.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org 23 with ESMTP id S1752542Ab0FVPoB (ORCPT 24 <rfc822;groupwise-SJayaraman@novell.com:0:0>); 25 Tue, 22 Jun 2010 11:44:01 -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:50 -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/1001761> 35 36Takes care of invalidation and release of FS-Cache marked pages and also 37invalidation of the FsCache page flag when the inode is removed. 38 39Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de> 40--- 41 fs/cifs/cache.c | 31 +++++++++++++++++++++++++++++++ 42 fs/cifs/file.c | 20 ++++++++++++++++++++ 43 fs/cifs/fscache.c | 26 ++++++++++++++++++++++++++ 44 fs/cifs/fscache.h | 16 ++++++++++++++++ 45 4 files changed, 93 insertions(+), 0 deletions(-) 46 47diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c 48index b205424..3a733c1 100644 49--- a/fs/cifs/cache.c 50+++ b/fs/cifs/cache.c 51@@ -210,6 +210,36 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data, 52 return FSCACHE_CHECKAUX_OKAY; 53 } 54 55+static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data) 56+{ 57+ struct cifsInodeInfo *cifsi = cookie_netfs_data; 58+ struct pagevec pvec; 59+ pgoff_t first; 60+ int loop, nr_pages; 61+ 62+ pagevec_init(&pvec, 0); 63+ first = 0; 64+ 65+ cFYI(1, "cifs inode 0x%p now uncached\n", cifsi); 66+ 67+ for (;;) { 68+ nr_pages = pagevec_lookup(&pvec, 69+ cifsi->vfs_inode.i_mapping, first, 70+ PAGEVEC_SIZE - pagevec_count(&pvec)); 71+ if (!nr_pages) 72+ break; 73+ 74+ for (loop = 0; loop < nr_pages; loop++) 75+ ClearPageFsCache(pvec.pages[loop]); 76+ 77+ first = pvec.pages[nr_pages - 1]->index + 1; 78+ 79+ pvec.nr = nr_pages; 80+ pagevec_release(&pvec); 81+ cond_resched(); 82+ } 83+} 84+ 85 const struct fscache_cookie_def cifs_fscache_inode_object_def = { 86 .name = "CIFS.uniqueid", 87 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 88@@ -217,4 +247,5 @@ const struct fscache_cookie_def cifs_fscache_inode_object_def = { 89 .get_attr = cifs_fscache_inode_get_attr, 90 .get_aux = cifs_fscache_inode_get_aux, 91 .check_aux = cifs_fscache_inode_check_aux, 92+ .now_uncached = cifs_fscache_inode_now_uncached, 93 }; 94diff --git a/fs/cifs/file.c b/fs/cifs/file.c 95index 55ecb55..786ec04 100644 96--- a/fs/cifs/file.c 97+++ b/fs/cifs/file.c 98@@ -2271,6 +2271,22 @@ out: 99 return rc; 100 } 101 102+static int cifs_release_page(struct page *page, gfp_t gfp) 103+{ 104+ if (PagePrivate(page)) 105+ return 0; 106+ 107+ return cifs_fscache_release_page(page, gfp); 108+} 109+ 110+static void cifs_invalidate_page(struct page *page, unsigned long offset) 111+{ 112+ struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host); 113+ 114+ if (offset == 0) 115+ cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); 116+} 117+ 118 static void 119 cifs_oplock_break(struct slow_work *work) 120 { 121@@ -2344,6 +2360,8 @@ const struct address_space_operations cifs_addr_ops = { 122 .write_begin = cifs_write_begin, 123 .write_end = cifs_write_end, 124 .set_page_dirty = __set_page_dirty_nobuffers, 125+ .releasepage = cifs_release_page, 126+ .invalidatepage = cifs_invalidate_page, 127 /* .sync_page = cifs_sync_page, */ 128 /* .direct_IO = */ 129 }; 130@@ -2360,6 +2378,8 @@ const struct address_space_operations cifs_addr_ops_smallbuf = { 131 .write_begin = cifs_write_begin, 132 .write_end = cifs_write_end, 133 .set_page_dirty = __set_page_dirty_nobuffers, 134+ .releasepage = cifs_release_page, 135+ .invalidatepage = cifs_invalidate_page, 136 /* .sync_page = cifs_sync_page, */ 137 /* .direct_IO = */ 138 }; 139diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c 140index ddfd355..c09d3b8 100644 141--- a/fs/cifs/fscache.c 142+++ b/fs/cifs/fscache.c 143@@ -130,3 +130,29 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode) 144 } 145 } 146 147+int cifs_fscache_release_page(struct page *page, gfp_t gfp) 148+{ 149+ if (PageFsCache(page)) { 150+ struct inode *inode = page->mapping->host; 151+ struct cifsInodeInfo *cifsi = CIFS_I(inode); 152+ 153+ cFYI(1, "CIFS: fscache release page (0x%p/0x%p)\n", 154+ cifsi->fscache, page); 155+ if (!fscache_maybe_release_page(cifsi->fscache, page, gfp)) 156+ return 0; 157+ } 158+ 159+ return 1; 160+} 161+ 162+void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode) 163+{ 164+ struct cifsInodeInfo *cifsi = CIFS_I(inode); 165+ struct fscache_cookie *cookie = cifsi->fscache; 166+ 167+ cFYI(1, "CIFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n", 168+ cookie, page, cifsi); 169+ fscache_wait_on_page_write(cookie, page); 170+ fscache_uncache_page(cookie, page); 171+} 172+ 173diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h 174index 836bb02..127cb0a 100644 175--- a/fs/cifs/fscache.h 176+++ b/fs/cifs/fscache.h 177@@ -47,6 +47,16 @@ extern void cifs_fscache_release_inode_cookie(struct inode *); 178 extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *); 179 extern void cifs_fscache_reset_inode_cookie(struct inode *); 180 181+extern void __cifs_fscache_invalidate_page(struct page *, struct inode *); 182+extern int cifs_fscache_release_page(struct page *page, gfp_t gfp); 183+ 184+static inline void cifs_fscache_invalidate_page(struct page *page, 185+ struct inode *inode) 186+{ 187+ if (PageFsCache(page)) 188+ __cifs_fscache_invalidate_page(page, inode); 189+} 190+ 191 #else /* CONFIG_CIFS_FSCACHE */ 192 static inline int cifs_fscache_register(void) { return 0; } 193 static inline void cifs_fscache_unregister(void) {} 194@@ -63,7 +73,13 @@ static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {} 195 static inline void cifs_fscache_set_inode_cookie(struct inode *inode, 196 struct file *filp) {} 197 static inline void cifs_fscache_reset_inode_cookie(struct inode *inode) {} 198+static inline void cifs_fscache_release_page(struct page *page, gfp_t gfp) 199+{ 200+ return 1; /* May release page */ 201+} 202 203+static inline int cifs_fscache_invalidate_page(struct page *page, 204+ struct inode *) {} 205 206 #endif /* CONFIG_CIFS_FSCACHE */ 207 208-- 2091.6.4.2 210 211 212 213