Blame view

fs/cifs/fscache.c 6.38 KB
488f1d2d6   Suresh Jayaraman   cifs: define serv...
1
2
3
4
  /*
   *   fs/cifs/fscache.c - CIFS filesystem cache interface
   *
   *   Copyright (c) 2010 Novell, Inc.
b81209de2   Suresh Jayaraman   cifs: enable fsca...
5
   *   Author(s): Suresh Jayaraman <sjayaraman@suse.de>
488f1d2d6   Suresh Jayaraman   cifs: define serv...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   *
   *   This library is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU Lesser General Public License as published
   *   by the Free Software Foundation; either version 2.1 of the License, or
   *   (at your option) any later version.
   *
   *   This library is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
   *   the GNU Lesser General Public License for more details.
   *
   *   You should have received a copy of the GNU Lesser General Public License
   *   along with this library; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  #include "fscache.h"
  #include "cifsglob.h"
  #include "cifs_debug.h"
9451a9a52   Suresh Jayaraman   cifs: define inod...
24
  #include "cifs_fs_sb.h"
488f1d2d6   Suresh Jayaraman   cifs: define serv...
25
26
27
28
29
30
  
  void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
  {
  	server->fscache =
  		fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
  				&cifs_fscache_server_index_def, server);
040d15c86   Steve French   [CIFS] trivial cl...
31
32
  	cFYI(1, "%s: (0x%p/0x%p)", __func__, server,
  			server->fscache);
488f1d2d6   Suresh Jayaraman   cifs: define serv...
33
34
35
36
  }
  
  void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
  {
040d15c86   Steve French   [CIFS] trivial cl...
37
38
  	cFYI(1, "%s: (0x%p/0x%p)", __func__, server,
  			server->fscache);
488f1d2d6   Suresh Jayaraman   cifs: define serv...
39
40
41
  	fscache_relinquish_cookie(server->fscache, 0);
  	server->fscache = NULL;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
42
  void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
d03382ce9   Suresh Jayaraman   cifs: define supe...
43
44
45
46
47
48
  {
  	struct TCP_Server_Info *server = tcon->ses->server;
  
  	tcon->fscache =
  		fscache_acquire_cookie(server->fscache,
  				&cifs_fscache_super_index_def, tcon);
040d15c86   Steve French   [CIFS] trivial cl...
49
50
  	cFYI(1, "%s: (0x%p/0x%p)", __func__, server->fscache,
  			tcon->fscache);
d03382ce9   Suresh Jayaraman   cifs: define supe...
51
  }
96daf2b09   Steve French   [CIFS] Rename thr...
52
  void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
d03382ce9   Suresh Jayaraman   cifs: define supe...
53
  {
040d15c86   Steve French   [CIFS] trivial cl...
54
  	cFYI(1, "%s: (0x%p)", __func__, tcon->fscache);
d03382ce9   Suresh Jayaraman   cifs: define supe...
55
56
57
  	fscache_relinquish_cookie(tcon->fscache, 0);
  	tcon->fscache = NULL;
  }
9451a9a52   Suresh Jayaraman   cifs: define inod...
58
59
60
61
62
  
  static void cifs_fscache_enable_inode_cookie(struct inode *inode)
  {
  	struct cifsInodeInfo *cifsi = CIFS_I(inode);
  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
96daf2b09   Steve French   [CIFS] Rename thr...
63
  	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
9451a9a52   Suresh Jayaraman   cifs: define inod...
64
65
66
  
  	if (cifsi->fscache)
  		return;
b81209de2   Suresh Jayaraman   cifs: enable fsca...
67
68
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
  		cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
0d424ad0a   Jeff Layton   cifs: add cifs_sb...
69
  				&cifs_fscache_inode_object_def, cifsi);
040d15c86   Steve French   [CIFS] trivial cl...
70
71
  		cFYI(1, "%s: got FH cookie (0x%p/0x%p)", __func__,
  				tcon->fscache, cifsi->fscache);
b81209de2   Suresh Jayaraman   cifs: enable fsca...
72
  	}
9451a9a52   Suresh Jayaraman   cifs: define inod...
73
74
75
76
77
78
79
  }
  
  void cifs_fscache_release_inode_cookie(struct inode *inode)
  {
  	struct cifsInodeInfo *cifsi = CIFS_I(inode);
  
  	if (cifsi->fscache) {
040d15c86   Steve French   [CIFS] trivial cl...
80
  		cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache);
9451a9a52   Suresh Jayaraman   cifs: define inod...
81
82
83
84
85
86
87
88
89
90
  		fscache_relinquish_cookie(cifsi->fscache, 0);
  		cifsi->fscache = NULL;
  	}
  }
  
  static void cifs_fscache_disable_inode_cookie(struct inode *inode)
  {
  	struct cifsInodeInfo *cifsi = CIFS_I(inode);
  
  	if (cifsi->fscache) {
040d15c86   Steve French   [CIFS] trivial cl...
91
  		cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache);
c902ce1bf   David Howells   FS-Cache: Add a h...
92
  		fscache_uncache_all_inode_pages(cifsi->fscache, inode);
9451a9a52   Suresh Jayaraman   cifs: define inod...
93
94
95
96
97
98
99
100
101
  		fscache_relinquish_cookie(cifsi->fscache, 1);
  		cifsi->fscache = NULL;
  	}
  }
  
  void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
  {
  	if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
  		cifs_fscache_disable_inode_cookie(inode);
b81209de2   Suresh Jayaraman   cifs: enable fsca...
102
  	else
9451a9a52   Suresh Jayaraman   cifs: define inod...
103
  		cifs_fscache_enable_inode_cookie(inode);
9451a9a52   Suresh Jayaraman   cifs: define inod...
104
105
106
107
108
109
110
111
112
113
114
  }
  
  void cifs_fscache_reset_inode_cookie(struct inode *inode)
  {
  	struct cifsInodeInfo *cifsi = CIFS_I(inode);
  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
  	struct fscache_cookie *old = cifsi->fscache;
  
  	if (cifsi->fscache) {
  		/* retire the current fscache cache and get a new one */
  		fscache_relinquish_cookie(cifsi->fscache, 1);
a6e8a8455   Jeff Layton   cifs: add functio...
115
  		cifsi->fscache = fscache_acquire_cookie(
0d424ad0a   Jeff Layton   cifs: add cifs_sb...
116
  					cifs_sb_master_tcon(cifs_sb)->fscache,
9451a9a52   Suresh Jayaraman   cifs: define inod...
117
118
  					&cifs_fscache_inode_object_def,
  					cifsi);
040d15c86   Steve French   [CIFS] trivial cl...
119
120
  		cFYI(1, "%s: new cookie 0x%p oldcookie 0x%p",
  				__func__, cifsi->fscache, old);
9451a9a52   Suresh Jayaraman   cifs: define inod...
121
122
  	}
  }
85f2d6b44   Suresh Jayaraman   cifs: FS-Cache pa...
123
124
125
126
127
128
  
  int cifs_fscache_release_page(struct page *page, gfp_t gfp)
  {
  	if (PageFsCache(page)) {
  		struct inode *inode = page->mapping->host;
  		struct cifsInodeInfo *cifsi = CIFS_I(inode);
040d15c86   Steve French   [CIFS] trivial cl...
129
130
  		cFYI(1, "%s: (0x%p/0x%p)", __func__, page,
  				cifsi->fscache);
85f2d6b44   Suresh Jayaraman   cifs: FS-Cache pa...
131
132
133
134
135
136
  		if (!fscache_maybe_release_page(cifsi->fscache, page, gfp))
  			return 0;
  	}
  
  	return 1;
  }
56698236e   Suresh Jayaraman   cifs: read pages ...
137
138
139
  static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx,
  						int error)
  {
040d15c86   Steve French   [CIFS] trivial cl...
140
  	cFYI(1, "%s: (0x%p/%d)", __func__, page, error);
56698236e   Suresh Jayaraman   cifs: read pages ...
141
142
143
144
145
146
147
148
149
150
151
  	if (!error)
  		SetPageUptodate(page);
  	unlock_page(page);
  }
  
  /*
   * Retrieve a page from FS-Cache
   */
  int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
  {
  	int ret;
040d15c86   Steve French   [CIFS] trivial cl...
152
  	cFYI(1, "%s: (fsc:%p, p:%p, i:0x%p", __func__,
56698236e   Suresh Jayaraman   cifs: read pages ...
153
154
155
156
157
158
159
160
  			CIFS_I(inode)->fscache, page, inode);
  	ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page,
  					 cifs_readpage_from_fscache_complete,
  					 NULL,
  					 GFP_KERNEL);
  	switch (ret) {
  
  	case 0: /* page found in fscache, read submitted */
040d15c86   Steve French   [CIFS] trivial cl...
161
  		cFYI(1, "%s: submitted", __func__);
56698236e   Suresh Jayaraman   cifs: read pages ...
162
163
164
  		return ret;
  	case -ENOBUFS:	/* page won't be cached */
  	case -ENODATA:	/* page not in cache */
040d15c86   Steve French   [CIFS] trivial cl...
165
  		cFYI(1, "%s: %d", __func__, ret);
56698236e   Suresh Jayaraman   cifs: read pages ...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  		return 1;
  
  	default:
  		cERROR(1, "unknown error ret = %d", ret);
  	}
  	return ret;
  }
  
  /*
   * Retrieve a set of pages from FS-Cache
   */
  int __cifs_readpages_from_fscache(struct inode *inode,
  				struct address_space *mapping,
  				struct list_head *pages,
  				unsigned *nr_pages)
  {
  	int ret;
040d15c86   Steve French   [CIFS] trivial cl...
183
  	cFYI(1, "%s: (0x%p/%u/0x%p)", __func__,
56698236e   Suresh Jayaraman   cifs: read pages ...
184
185
186
187
188
189
190
191
  			CIFS_I(inode)->fscache, *nr_pages, inode);
  	ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping,
  					  pages, nr_pages,
  					  cifs_readpage_from_fscache_complete,
  					  NULL,
  					  mapping_gfp_mask(mapping));
  	switch (ret) {
  	case 0:	/* read submitted to the cache for all pages */
040d15c86   Steve French   [CIFS] trivial cl...
192
  		cFYI(1, "%s: submitted", __func__);
56698236e   Suresh Jayaraman   cifs: read pages ...
193
194
195
196
  		return ret;
  
  	case -ENOBUFS:	/* some pages are not cached and can't be */
  	case -ENODATA:	/* some pages are not cached */
040d15c86   Steve French   [CIFS] trivial cl...
197
  		cFYI(1, "%s: no page", __func__);
56698236e   Suresh Jayaraman   cifs: read pages ...
198
199
200
201
202
203
204
205
  		return 1;
  
  	default:
  		cFYI(1, "unknown error ret = %d", ret);
  	}
  
  	return ret;
  }
9dc06558c   Suresh Jayaraman   cifs: store pages...
206
207
208
  void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
  {
  	int ret;
040d15c86   Steve French   [CIFS] trivial cl...
209
  	cFYI(1, "%s: (fsc: %p, p: %p, i: %p)", __func__,
9dc06558c   Suresh Jayaraman   cifs: store pages...
210
211
212
213
214
  			CIFS_I(inode)->fscache, page, inode);
  	ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL);
  	if (ret != 0)
  		fscache_uncache_page(CIFS_I(inode)->fscache, page);
  }
85f2d6b44   Suresh Jayaraman   cifs: FS-Cache pa...
215
216
217
218
  void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
  {
  	struct cifsInodeInfo *cifsi = CIFS_I(inode);
  	struct fscache_cookie *cookie = cifsi->fscache;
040d15c86   Steve French   [CIFS] trivial cl...
219
  	cFYI(1, "%s: (0x%p/0x%p)", __func__, page, cookie);
85f2d6b44   Suresh Jayaraman   cifs: FS-Cache pa...
220
221
222
  	fscache_wait_on_page_write(cookie, page);
  	fscache_uncache_page(cookie, page);
  }