aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/Makefile2
-rw-r--r--fs/nfs/client.c5
-rw-r--r--fs/nfs/fscache-index.c65
-rw-r--r--fs/nfs/fscache.c52
-rw-r--r--fs/nfs/fscache.h10
5 files changed, 133 insertions, 1 deletions
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 0e0bb6c17a86..845159814de2 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -15,4 +15,4 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
15 callback.o callback_xdr.o callback_proc.o \ 15 callback.o callback_xdr.o callback_proc.o \
16 nfs4namespace.o 16 nfs4namespace.o
17nfs-$(CONFIG_SYSCTL) += sysctl.o 17nfs-$(CONFIG_SYSCTL) += sysctl.o
18nfs-$(CONFIG_NFS_FSCACHE) += fscache-index.o 18nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index aba38017bdef..aa04da8748a6 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -45,6 +45,7 @@
45#include "delegation.h" 45#include "delegation.h"
46#include "iostat.h" 46#include "iostat.h"
47#include "internal.h" 47#include "internal.h"
48#include "fscache.h"
48 49
49#define NFSDBG_FACILITY NFSDBG_CLIENT 50#define NFSDBG_FACILITY NFSDBG_CLIENT
50 51
@@ -154,6 +155,8 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
154 if (!IS_ERR(cred)) 155 if (!IS_ERR(cred))
155 clp->cl_machine_cred = cred; 156 clp->cl_machine_cred = cred;
156 157
158 nfs_fscache_get_client_cookie(clp);
159
157 return clp; 160 return clp;
158 161
159error_3: 162error_3:
@@ -187,6 +190,8 @@ static void nfs_free_client(struct nfs_client *clp)
187 190
188 nfs4_shutdown_client(clp); 191 nfs4_shutdown_client(clp);
189 192
193 nfs_fscache_release_client_cookie(clp);
194
190 /* -EIO all pending I/O */ 195 /* -EIO all pending I/O */
191 if (!IS_ERR(clp->cl_rpcclient)) 196 if (!IS_ERR(clp->cl_rpcclient))
192 rpc_shutdown_client(clp->cl_rpcclient); 197 rpc_shutdown_client(clp->cl_rpcclient);
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
index 6d5bb5c69048..ff14b032459b 100644
--- a/fs/nfs/fscache-index.c
+++ b/fs/nfs/fscache-index.c
@@ -47,3 +47,68 @@ void nfs_fscache_unregister(void)
47{ 47{
48 fscache_unregister_netfs(&nfs_fscache_netfs); 48 fscache_unregister_netfs(&nfs_fscache_netfs);
49} 49}
50
51/*
52 * Layout of the key for an NFS server cache object.
53 */
54struct nfs_server_key {
55 uint16_t nfsversion; /* NFS protocol version */
56 uint16_t family; /* address family */
57 uint16_t port; /* IP port */
58 union {
59 struct in_addr ipv4_addr; /* IPv4 address */
60 struct in6_addr ipv6_addr; /* IPv6 address */
61 } addr[0];
62};
63
64/*
65 * Generate a key to describe a server in the main NFS index
66 * - We return the length of the key, or 0 if we can't generate one
67 */
68static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
69 void *buffer, uint16_t bufmax)
70{
71 const struct nfs_client *clp = cookie_netfs_data;
72 const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &clp->cl_addr;
73 const struct sockaddr_in *sin = (struct sockaddr_in *) &clp->cl_addr;
74 struct nfs_server_key *key = buffer;
75 uint16_t len = sizeof(struct nfs_server_key);
76
77 key->nfsversion = clp->rpc_ops->version;
78 key->family = clp->cl_addr.ss_family;
79
80 memset(key, 0, len);
81
82 switch (clp->cl_addr.ss_family) {
83 case AF_INET:
84 key->port = sin->sin_port;
85 key->addr[0].ipv4_addr = sin->sin_addr;
86 len += sizeof(key->addr[0].ipv4_addr);
87 break;
88
89 case AF_INET6:
90 key->port = sin6->sin6_port;
91 key->addr[0].ipv6_addr = sin6->sin6_addr;
92 len += sizeof(key->addr[0].ipv6_addr);
93 break;
94
95 default:
96 printk(KERN_WARNING "NFS: Unknown network family '%d'\n",
97 clp->cl_addr.ss_family);
98 len = 0;
99 break;
100 }
101
102 return len;
103}
104
105/*
106 * Define the server object for FS-Cache. This is used to describe a server
107 * object to fscache_acquire_cookie(). It is keyed by the NFS protocol and
108 * server address parameters.
109 */
110const struct fscache_cookie_def nfs_fscache_server_index_def = {
111 .name = "NFS.server",
112 .type = FSCACHE_COOKIE_TYPE_INDEX,
113 .get_key = nfs_server_get_key,
114};
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
new file mode 100644
index 000000000000..c3f056f89477
--- /dev/null
+++ b/fs/nfs/fscache.c
@@ -0,0 +1,52 @@
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/*
27 * Get the per-client index cookie for an NFS client if the appropriate mount
28 * flag was set
29 * - We always try and get an index cookie for the client, but get filehandle
30 * cookies on a per-superblock basis, depending on the mount flags
31 */
32void nfs_fscache_get_client_cookie(struct nfs_client *clp)
33{
34 /* create a cache index for looking up filehandles */
35 clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
36 &nfs_fscache_server_index_def,
37 clp);
38 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
39 clp, clp->fscache);
40}
41
42/*
43 * Dispose of a per-client cookie
44 */
45void nfs_fscache_release_client_cookie(struct nfs_client *clp)
46{
47 dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n",
48 clp, clp->fscache);
49
50 fscache_relinquish_cookie(clp->fscache, 0);
51 clp->fscache = NULL;
52}
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
index ccfcdc58066e..1d864bedf154 100644
--- a/fs/nfs/fscache.h
+++ b/fs/nfs/fscache.h
@@ -23,13 +23,23 @@
23 * fscache-index.c 23 * fscache-index.c
24 */ 24 */
25extern struct fscache_netfs nfs_fscache_netfs; 25extern struct fscache_netfs nfs_fscache_netfs;
26extern const struct fscache_cookie_def nfs_fscache_server_index_def;
26 27
27extern int nfs_fscache_register(void); 28extern int nfs_fscache_register(void);
28extern void nfs_fscache_unregister(void); 29extern void nfs_fscache_unregister(void);
29 30
31/*
32 * fscache.c
33 */
34extern void nfs_fscache_get_client_cookie(struct nfs_client *);
35extern void nfs_fscache_release_client_cookie(struct nfs_client *);
36
30#else /* CONFIG_NFS_FSCACHE */ 37#else /* CONFIG_NFS_FSCACHE */
31static inline int nfs_fscache_register(void) { return 0; } 38static inline int nfs_fscache_register(void) { return 0; }
32static inline void nfs_fscache_unregister(void) {} 39static inline void nfs_fscache_unregister(void) {}
33 40
41static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {}
42static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
43
34#endif /* CONFIG_NFS_FSCACHE */ 44#endif /* CONFIG_NFS_FSCACHE */
35#endif /* _NFS_FSCACHE_H */ 45#endif /* _NFS_FSCACHE_H */