1 /* NFS filesystem cache interface
3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.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>
24 #define NFSDBG_FACILITY NFSDBG_FSCACHE
26 static struct rb_root nfs_fscache_keys
= RB_ROOT
;
27 static DEFINE_SPINLOCK(nfs_fscache_keys_lock
);
30 * Get the per-client index cookie for an NFS client if the appropriate mount
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
35 void nfs_fscache_get_client_cookie(struct nfs_client
*clp
)
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
,
41 dfprintk(FSCACHE
, "NFS: get client cookie (0x%p/0x%p)\n",
46 * Dispose of a per-client cookie
48 void nfs_fscache_release_client_cookie(struct nfs_client
*clp
)
50 dfprintk(FSCACHE
, "NFS: releasing client cookie (0x%p/0x%p)\n",
53 fscache_relinquish_cookie(clp
->fscache
, 0);
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.
61 void nfs_fscache_get_super_cookie(struct super_block
*sb
,
62 struct nfs_parsed_mount_data
*data
)
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
?: "";
71 key
= kzalloc(sizeof(*key
) + ulen
, GFP_KERNEL
);
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
;
87 key
->key
.uniq_len
= ulen
;
88 memcpy(key
->key
.uniquifier
, uniq
, ulen
);
90 spin_lock(&nfs_fscache_keys_lock
);
91 p
= &nfs_fscache_keys
.rb_node
;
95 xkey
= rb_entry(parent
, struct nfs_fscache_key
, node
);
97 if (key
->nfs_client
< xkey
->nfs_client
)
99 if (key
->nfs_client
> xkey
->nfs_client
)
102 diff
= memcmp(&key
->key
, &xkey
->key
, sizeof(key
->key
));
108 if (key
->key
.uniq_len
== 0)
110 diff
= memcmp(key
->key
.uniquifier
,
111 xkey
->key
.uniquifier
,
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
;
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
,
135 dfprintk(FSCACHE
, "NFS: get superblock cookie (0x%p/0x%p)\n",
136 nfss
, nfss
->fscache
);
140 spin_unlock(&nfs_fscache_keys_lock
);
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");
149 * release a per-superblock cookie
151 void nfs_fscache_release_super_cookie(struct super_block
*sb
)
153 struct nfs_server
*nfss
= NFS_SB(sb
);
155 dfprintk(FSCACHE
, "NFS: releasing superblock cookie (0x%p/0x%p)\n",
156 nfss
, nfss
->fscache
);
158 fscache_relinquish_cookie(nfss
->fscache
, 0);
159 nfss
->fscache
= NULL
;
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
;