e3816eb53fb8d831b68c55f8929fd921a300122d
[pandora-kernel.git] / fs / nfs / fscache.c
1 /* NFS filesystem cache interface
2  *
3  * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
11
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/mm.h>
16 #include <linux/nfs_fs.h>
17 #include <linux/nfs_fs_sb.h>
18 #include <linux/in6.h>
19 #include <linux/seq_file.h>
20
21 #include "internal.h"
22 #include "fscache.h"
23
24 #define NFSDBG_FACILITY         NFSDBG_FSCACHE
25
26 static struct rb_root nfs_fscache_keys = RB_ROOT;
27 static DEFINE_SPINLOCK(nfs_fscache_keys_lock);
28
29 /*
30  * Get the per-client index cookie for an NFS client if the appropriate mount
31  * flag was set
32  * - We always try and get an index cookie for the client, but get filehandle
33  *   cookies on a per-superblock basis, depending on the mount flags
34  */
35 void nfs_fscache_get_client_cookie(struct nfs_client *clp)
36 {
37         /* create a cache index for looking up filehandles */
38         clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
39                                               &nfs_fscache_server_index_def,
40                                               clp);
41         dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
42                  clp, clp->fscache);
43 }
44
45 /*
46  * Dispose of a per-client cookie
47  */
48 void nfs_fscache_release_client_cookie(struct nfs_client *clp)
49 {
50         dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n",
51                  clp, clp->fscache);
52
53         fscache_relinquish_cookie(clp->fscache, 0);
54         clp->fscache = NULL;
55 }
56
57 /*
58  * Get the cache cookie for an NFS superblock.  We have to handle
59  * uniquification here because the cache doesn't do it for us.
60  */
61 void nfs_fscache_get_super_cookie(struct super_block *sb,
62                                   struct nfs_parsed_mount_data *data)
63 {
64         struct nfs_fscache_key *key, *xkey;
65         struct nfs_server *nfss = NFS_SB(sb);
66         struct rb_node **p, *parent;
67         const char *uniq = data->fscache_uniq ?: "";
68         int diff, ulen;
69
70         ulen = strlen(uniq);
71         key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL);
72         if (!key)
73                 return;
74
75         key->nfs_client = nfss->nfs_client;
76         key->key.super.s_flags = sb->s_flags & NFS_MS_MASK;
77         key->key.nfs_server.flags = nfss->flags;
78         key->key.nfs_server.rsize = nfss->rsize;
79         key->key.nfs_server.wsize = nfss->wsize;
80         key->key.nfs_server.acregmin = nfss->acregmin;
81         key->key.nfs_server.acregmax = nfss->acregmax;
82         key->key.nfs_server.acdirmin = nfss->acdirmin;
83         key->key.nfs_server.acdirmax = nfss->acdirmax;
84         key->key.nfs_server.fsid = nfss->fsid;
85         key->key.rpc_auth.au_flavor = nfss->client->cl_auth->au_flavor;
86
87         key->key.uniq_len = ulen;
88         memcpy(key->key.uniquifier, uniq, ulen);
89
90         spin_lock(&nfs_fscache_keys_lock);
91         p = &nfs_fscache_keys.rb_node;
92         parent = NULL;
93         while (*p) {
94                 parent = *p;
95                 xkey = rb_entry(parent, struct nfs_fscache_key, node);
96
97                 if (key->nfs_client < xkey->nfs_client)
98                         goto go_left;
99                 if (key->nfs_client > xkey->nfs_client)
100                         goto go_right;
101
102                 diff = memcmp(&key->key, &xkey->key, sizeof(key->key));
103                 if (diff < 0)
104                         goto go_left;
105                 if (diff > 0)
106                         goto go_right;
107
108                 if (key->key.uniq_len == 0)
109                         goto non_unique;
110                 diff = memcmp(key->key.uniquifier,
111                               xkey->key.uniquifier,
112                               key->key.uniq_len);
113                 if (diff < 0)
114                         goto go_left;
115                 if (diff > 0)
116                         goto go_right;
117                 goto non_unique;
118
119         go_left:
120                 p = &(*p)->rb_left;
121                 continue;
122         go_right:
123                 p = &(*p)->rb_right;
124         }
125
126         rb_link_node(&key->node, parent, p);
127         rb_insert_color(&key->node, &nfs_fscache_keys);
128         spin_unlock(&nfs_fscache_keys_lock);
129         nfss->fscache_key = key;
130
131         /* create a cache index for looking up filehandles */
132         nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
133                                                &nfs_fscache_super_index_def,
134                                                nfss);
135         dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
136                  nfss, nfss->fscache);
137         return;
138
139 non_unique:
140         spin_unlock(&nfs_fscache_keys_lock);
141         kfree(key);
142         nfss->fscache_key = NULL;
143         nfss->fscache = NULL;
144         printk(KERN_WARNING "NFS:"
145                " Cache request denied due to non-unique superblock keys\n");
146 }
147
148 /*
149  * release a per-superblock cookie
150  */
151 void nfs_fscache_release_super_cookie(struct super_block *sb)
152 {
153         struct nfs_server *nfss = NFS_SB(sb);
154
155         dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n",
156                  nfss, nfss->fscache);
157
158         fscache_relinquish_cookie(nfss->fscache, 0);
159         nfss->fscache = NULL;
160
161         if (nfss->fscache_key) {
162                 spin_lock(&nfs_fscache_keys_lock);
163                 rb_erase(&nfss->fscache_key->node, &nfs_fscache_keys);
164                 spin_unlock(&nfs_fscache_keys_lock);
165                 kfree(nfss->fscache_key);
166                 nfss->fscache_key = NULL;
167         }
168 }
169
170 /*
171  * Initialise the per-inode cache cookie pointer for an NFS inode.
172  */
173 void nfs_fscache_init_inode_cookie(struct inode *inode)
174 {
175         NFS_I(inode)->fscache = NULL;
176         if (S_ISREG(inode->i_mode))
177                 set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
178 }
179
180 /*
181  * Get the per-inode cache cookie for an NFS inode.
182  */
183 static void nfs_fscache_enable_inode_cookie(struct inode *inode)
184 {
185         struct super_block *sb = inode->i_sb;
186         struct nfs_inode *nfsi = NFS_I(inode);
187
188         if (nfsi->fscache || !NFS_FSCACHE(inode))
189                 return;
190
191         if ((NFS_SB(sb)->options & NFS_OPTION_FSCACHE)) {
192                 nfsi->fscache = fscache_acquire_cookie(
193                         NFS_SB(sb)->fscache,
194                         &nfs_fscache_inode_object_def,
195                         nfsi);
196
197                 dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n",
198                          sb, nfsi, nfsi->fscache);
199         }
200 }
201
202 /*
203  * Release a per-inode cookie.
204  */
205 void nfs_fscache_release_inode_cookie(struct inode *inode)
206 {
207         struct nfs_inode *nfsi = NFS_I(inode);
208
209         dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n",
210                  nfsi, nfsi->fscache);
211
212         fscache_relinquish_cookie(nfsi->fscache, 0);
213         nfsi->fscache = NULL;
214 }
215
216 /*
217  * Retire a per-inode cookie, destroying the data attached to it.
218  */
219 void nfs_fscache_zap_inode_cookie(struct inode *inode)
220 {
221         struct nfs_inode *nfsi = NFS_I(inode);
222
223         dfprintk(FSCACHE, "NFS: zapping cookie (0x%p/0x%p)\n",
224                  nfsi, nfsi->fscache);
225
226         fscache_relinquish_cookie(nfsi->fscache, 1);
227         nfsi->fscache = NULL;
228 }
229
230 /*
231  * Turn off the cache with regard to a per-inode cookie if opened for writing,
232  * invalidating all the pages in the page cache relating to the associated
233  * inode to clear the per-page caching.
234  */
235 static void nfs_fscache_disable_inode_cookie(struct inode *inode)
236 {
237         clear_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
238
239         if (NFS_I(inode)->fscache) {
240                 dfprintk(FSCACHE,
241                          "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode));
242
243                 /* Need to invalidate any mapped pages that were read in before
244                  * turning off the cache.
245                  */
246                 if (inode->i_mapping && inode->i_mapping->nrpages)
247                         invalidate_inode_pages2(inode->i_mapping);
248
249                 nfs_fscache_zap_inode_cookie(inode);
250         }
251 }
252
253 /*
254  * wait_on_bit() sleep function for uninterruptible waiting
255  */
256 static int nfs_fscache_wait_bit(void *flags)
257 {
258         schedule();
259         return 0;
260 }
261
262 /*
263  * Lock against someone else trying to also acquire or relinquish a cookie
264  */
265 static inline void nfs_fscache_inode_lock(struct inode *inode)
266 {
267         struct nfs_inode *nfsi = NFS_I(inode);
268
269         while (test_and_set_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags))
270                 wait_on_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK,
271                             nfs_fscache_wait_bit, TASK_UNINTERRUPTIBLE);
272 }
273
274 /*
275  * Unlock cookie management lock
276  */
277 static inline void nfs_fscache_inode_unlock(struct inode *inode)
278 {
279         struct nfs_inode *nfsi = NFS_I(inode);
280
281         smp_mb__before_clear_bit();
282         clear_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags);
283         smp_mb__after_clear_bit();
284         wake_up_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK);
285 }
286
287 /*
288  * Decide if we should enable or disable local caching for this inode.
289  * - For now, with NFS, only regular files that are open read-only will be able
290  *   to use the cache.
291  * - May be invoked multiple times in parallel by parallel nfs_open() functions.
292  */
293 void nfs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
294 {
295         if (NFS_FSCACHE(inode)) {
296                 nfs_fscache_inode_lock(inode);
297                 if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
298                         nfs_fscache_disable_inode_cookie(inode);
299                 else
300                         nfs_fscache_enable_inode_cookie(inode);
301                 nfs_fscache_inode_unlock(inode);
302         }
303 }
304
305 /*
306  * Replace a per-inode cookie due to revalidation detecting a file having
307  * changed on the server.
308  */
309 void nfs_fscache_reset_inode_cookie(struct inode *inode)
310 {
311         struct nfs_inode *nfsi = NFS_I(inode);
312         struct nfs_server *nfss = NFS_SERVER(inode);
313         struct fscache_cookie *old = nfsi->fscache;
314
315         nfs_fscache_inode_lock(inode);
316         if (nfsi->fscache) {
317                 /* retire the current fscache cache and get a new one */
318                 fscache_relinquish_cookie(nfsi->fscache, 1);
319
320                 nfsi->fscache = fscache_acquire_cookie(
321                         nfss->nfs_client->fscache,
322                         &nfs_fscache_inode_object_def,
323                         nfsi);
324
325                 dfprintk(FSCACHE,
326                          "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n",
327                          nfss, nfsi, old, nfsi->fscache);
328         }
329         nfs_fscache_inode_unlock(inode);
330 }