aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/Makefile2
-rw-r--r--fs/cifs/cache.c62
-rw-r--r--fs/cifs/cifsglob.h3
-rw-r--r--fs/cifs/connect.c5
-rw-r--r--fs/cifs/fscache.c41
-rw-r--r--fs/cifs/fscache.h14
6 files changed, 126 insertions, 1 deletions
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index e2de709a6e5d..adefa60a9bdc 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -12,4 +12,4 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
12 12
13cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o 13cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
14 14
15cifs-$(CONFIG_CIFS_FSCACHE) += cache.o 15cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 1cb5ffb017f1..f46468fb6a90 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -19,6 +19,7 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#include "fscache.h" 21#include "fscache.h"
22#include "cifs_debug.h"
22 23
23/* 24/*
24 * CIFS filesystem definition for FS-Cache 25 * CIFS filesystem definition for FS-Cache
@@ -44,3 +45,64 @@ void cifs_fscache_unregister(void)
44 fscache_unregister_netfs(&cifs_fscache_netfs); 45 fscache_unregister_netfs(&cifs_fscache_netfs);
45} 46}
46 47
48/*
49 * Key layout of CIFS server cache index object
50 */
51struct cifs_server_key {
52 uint16_t family; /* address family */
53 uint16_t port; /* IP port */
54 union {
55 struct in_addr ipv4_addr;
56 struct in6_addr ipv6_addr;
57 } addr[0];
58};
59
60/*
61 * Server object keyed by {IPaddress,port,family} tuple
62 */
63static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
64 void *buffer, uint16_t maxbuf)
65{
66 const struct TCP_Server_Info *server = cookie_netfs_data;
67 const struct sockaddr *sa = (struct sockaddr *) &server->addr.sockAddr;
68 struct cifs_server_key *key = buffer;
69 uint16_t key_len = sizeof(struct cifs_server_key);
70
71 memset(key, 0, key_len);
72
73 /*
74 * Should not be a problem as sin_family/sin6_family overlays
75 * sa_family field
76 */
77 switch (sa->sa_family) {
78 case AF_INET:
79 key->family = server->addr.sockAddr.sin_family;
80 key->port = server->addr.sockAddr.sin_port;
81 key->addr[0].ipv4_addr = server->addr.sockAddr.sin_addr;
82 key_len += sizeof(key->addr[0].ipv4_addr);
83 break;
84
85 case AF_INET6:
86 key->family = server->addr.sockAddr6.sin6_family;
87 key->port = server->addr.sockAddr6.sin6_port;
88 key->addr[0].ipv6_addr = server->addr.sockAddr6.sin6_addr;
89 key_len += sizeof(key->addr[0].ipv6_addr);
90 break;
91
92 default:
93 cERROR(1, "CIFS: Unknown network family '%d'", sa->sa_family);
94 key_len = 0;
95 break;
96 }
97
98 return key_len;
99}
100
101/*
102 * Server object for FS-Cache
103 */
104const struct fscache_cookie_def cifs_fscache_server_index_def = {
105 .name = "CIFS.server",
106 .type = FSCACHE_COOKIE_TYPE_INDEX,
107 .get_key = cifs_server_get_key,
108};
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 6113427651c4..06b48998db94 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -192,6 +192,9 @@ struct TCP_Server_Info {
192 bool sec_mskerberos; /* supports legacy MS Kerberos */ 192 bool sec_mskerberos; /* supports legacy MS Kerberos */
193 bool sec_kerberosu2u; /* supports U2U Kerberos */ 193 bool sec_kerberosu2u; /* supports U2U Kerberos */
194 bool sec_ntlmssp; /* supports NTLMSSP */ 194 bool sec_ntlmssp; /* supports NTLMSSP */
195#ifdef CONFIG_CIFS_FSCACHE
196 struct fscache_cookie *fscache; /* client index cache cookie */
197#endif
195}; 198};
196 199
197/* 200/*
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2208f06e4c45..90354e39e565 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -48,6 +48,7 @@
48#include "nterr.h" 48#include "nterr.h"
49#include "rfc1002pdu.h" 49#include "rfc1002pdu.h"
50#include "cn_cifs.h" 50#include "cn_cifs.h"
51#include "fscache.h"
51 52
52#define CIFS_PORT 445 53#define CIFS_PORT 445
53#define RFC1001_PORT 139 54#define RFC1001_PORT 139
@@ -1460,6 +1461,8 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
1460 server->tcpStatus = CifsExiting; 1461 server->tcpStatus = CifsExiting;
1461 spin_unlock(&GlobalMid_Lock); 1462 spin_unlock(&GlobalMid_Lock);
1462 1463
1464 cifs_fscache_release_client_cookie(server);
1465
1463 task = xchg(&server->tsk, NULL); 1466 task = xchg(&server->tsk, NULL);
1464 if (task) 1467 if (task)
1465 force_sig(SIGKILL, task); 1468 force_sig(SIGKILL, task);
@@ -1577,6 +1580,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1577 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); 1580 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1578 write_unlock(&cifs_tcp_ses_lock); 1581 write_unlock(&cifs_tcp_ses_lock);
1579 1582
1583 cifs_fscache_get_client_cookie(tcp_ses);
1584
1580 return tcp_ses; 1585 return tcp_ses;
1581 1586
1582out_err: 1587out_err:
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
new file mode 100644
index 000000000000..ea97b76f8aa6
--- /dev/null
+++ b/fs/cifs/fscache.c
@@ -0,0 +1,41 @@
1/*
2 * fs/cifs/fscache.c - CIFS filesystem cache interface
3 *
4 * Copyright (c) 2010 Novell, Inc.
5 * Author(s): Suresh Jayaraman (sjayaraman@suse.de>
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include "fscache.h"
22#include "cifsglob.h"
23#include "cifs_debug.h"
24
25void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
26{
27 server->fscache =
28 fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
29 &cifs_fscache_server_index_def, server);
30 cFYI(1, "CIFS: get client cookie (0x%p/0x%p)", server,
31 server->fscache);
32}
33
34void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
35{
36 cFYI(1, "CIFS: release client cookie (0x%p/0x%p)", server,
37 server->fscache);
38 fscache_relinquish_cookie(server->fscache, 0);
39 server->fscache = NULL;
40}
41
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 14dae1975d78..8972306c58a5 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -23,17 +23,31 @@
23 23
24#include <linux/fscache.h> 24#include <linux/fscache.h>
25 25
26#include "cifsglob.h"
27
26#ifdef CONFIG_CIFS_FSCACHE 28#ifdef CONFIG_CIFS_FSCACHE
27 29
28extern struct fscache_netfs cifs_fscache_netfs; 30extern struct fscache_netfs cifs_fscache_netfs;
31extern const struct fscache_cookie_def cifs_fscache_server_index_def;
29 32
30extern int cifs_fscache_register(void); 33extern int cifs_fscache_register(void);
31extern void cifs_fscache_unregister(void); 34extern void cifs_fscache_unregister(void);
32 35
36/*
37 * fscache.c
38 */
39extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
40extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
41
33#else /* CONFIG_CIFS_FSCACHE */ 42#else /* CONFIG_CIFS_FSCACHE */
34static inline int cifs_fscache_register(void) { return 0; } 43static inline int cifs_fscache_register(void) { return 0; }
35static inline void cifs_fscache_unregister(void) {} 44static inline void cifs_fscache_unregister(void) {}
36 45
46static inline void
47cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
48static inline void
49cifs_fscache_get_client_cookie(struct TCP_Server_Info *server); {}
50
37#endif /* CONFIG_CIFS_FSCACHE */ 51#endif /* CONFIG_CIFS_FSCACHE */
38 52
39#endif /* _CIFS_FSCACHE_H */ 53#endif /* _CIFS_FSCACHE_H */