aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/nfs-rdma.txt14
-rw-r--r--fs/lockd/svclock.c2
-rw-r--r--fs/lockd/svcsubs.c69
-rw-r--r--fs/locks.c32
-rw-r--r--fs/nfsd/nfs4state.c3
-rw-r--r--fs/nfsd/nfs4xdr.c14
-rw-r--r--fs/nfsd/nfsctl.c65
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/lockd/lockd.h8
-rw-r--r--include/linux/nfsd/nfsd.h2
10 files changed, 162 insertions, 48 deletions
diff --git a/Documentation/filesystems/nfs-rdma.txt b/Documentation/filesystems/nfs-rdma.txt
index 1ae34879574b..d0ec45ae4e7d 100644
--- a/Documentation/filesystems/nfs-rdma.txt
+++ b/Documentation/filesystems/nfs-rdma.txt
@@ -5,7 +5,7 @@
5################################################################################ 5################################################################################
6 6
7 Author: NetApp and Open Grid Computing 7 Author: NetApp and Open Grid Computing
8 Date: February 25, 2008 8 Date: April 15, 2008
9 9
10Table of Contents 10Table of Contents
11~~~~~~~~~~~~~~~~~ 11~~~~~~~~~~~~~~~~~
@@ -197,12 +197,16 @@ NFS/RDMA Setup
197 - On the server system, configure the /etc/exports file and 197 - On the server system, configure the /etc/exports file and
198 start the NFS/RDMA server. 198 start the NFS/RDMA server.
199 199
200 Exports entries with the following format have been tested: 200 Exports entries with the following formats have been tested:
201 201
202 /vol0 10.97.103.47(rw,async) 192.168.0.47(rw,async,insecure,no_root_squash) 202 /vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
203 /vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
203 204
204 Here the first IP address is the client's Ethernet address and the second 205 The IP address(es) is(are) the client's IPoIB address for an InfiniBand HCA or the
205 IP address is the clients IPoIB address. 206 cleint's iWARP address(es) for an RNIC.
207
208 NOTE: The "insecure" option must be used because the NFS/RDMA client does not
209 use a reserved port.
206 210
207 Each time a machine boots: 211 Each time a machine boots:
208 212
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 1f122c1940af..4d81553d2948 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -632,7 +632,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
632 block->b_flags |= B_TIMED_OUT; 632 block->b_flags |= B_TIMED_OUT;
633 if (conf) { 633 if (conf) {
634 if (block->b_fl) 634 if (block->b_fl)
635 locks_copy_lock(block->b_fl, conf); 635 __locks_copy_lock(block->b_fl, conf);
636 } 636 }
637} 637}
638 638
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index dbbefbcd6712..d1c48b539df8 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -18,6 +18,8 @@
18#include <linux/lockd/lockd.h> 18#include <linux/lockd/lockd.h>
19#include <linux/lockd/share.h> 19#include <linux/lockd/share.h>
20#include <linux/lockd/sm_inter.h> 20#include <linux/lockd/sm_inter.h>
21#include <linux/module.h>
22#include <linux/mount.h>
21 23
22#define NLMDBG_FACILITY NLMDBG_SVCSUBS 24#define NLMDBG_FACILITY NLMDBG_SVCSUBS
23 25
@@ -194,6 +196,12 @@ again:
194 return 0; 196 return 0;
195} 197}
196 198
199static int
200nlmsvc_always_match(void *dummy1, struct nlm_host *dummy2)
201{
202 return 1;
203}
204
197/* 205/*
198 * Inspect a single file 206 * Inspect a single file
199 */ 207 */
@@ -230,7 +238,8 @@ nlm_file_inuse(struct nlm_file *file)
230 * Loop over all files in the file table. 238 * Loop over all files in the file table.
231 */ 239 */
232static int 240static int
233nlm_traverse_files(struct nlm_host *host, nlm_host_match_fn_t match) 241nlm_traverse_files(void *data, nlm_host_match_fn_t match,
242 int (*is_failover_file)(void *data, struct nlm_file *file))
234{ 243{
235 struct hlist_node *pos, *next; 244 struct hlist_node *pos, *next;
236 struct nlm_file *file; 245 struct nlm_file *file;
@@ -239,12 +248,14 @@ nlm_traverse_files(struct nlm_host *host, nlm_host_match_fn_t match)
239 mutex_lock(&nlm_file_mutex); 248 mutex_lock(&nlm_file_mutex);
240 for (i = 0; i < FILE_NRHASH; i++) { 249 for (i = 0; i < FILE_NRHASH; i++) {
241 hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) { 250 hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) {
251 if (is_failover_file && !is_failover_file(data, file))
252 continue;
242 file->f_count++; 253 file->f_count++;
243 mutex_unlock(&nlm_file_mutex); 254 mutex_unlock(&nlm_file_mutex);
244 255
245 /* Traverse locks, blocks and shares of this file 256 /* Traverse locks, blocks and shares of this file
246 * and update file->f_locks count */ 257 * and update file->f_locks count */
247 if (nlm_inspect_file(host, file, match)) 258 if (nlm_inspect_file(data, file, match))
248 ret = 1; 259 ret = 1;
249 260
250 mutex_lock(&nlm_file_mutex); 261 mutex_lock(&nlm_file_mutex);
@@ -303,21 +314,27 @@ nlm_release_file(struct nlm_file *file)
303 * Used by nlmsvc_invalidate_all 314 * Used by nlmsvc_invalidate_all
304 */ 315 */
305static int 316static int
306nlmsvc_mark_host(struct nlm_host *host, struct nlm_host *dummy) 317nlmsvc_mark_host(void *data, struct nlm_host *dummy)
307{ 318{
319 struct nlm_host *host = data;
320
308 host->h_inuse = 1; 321 host->h_inuse = 1;
309 return 0; 322 return 0;
310} 323}
311 324
312static int 325static int
313nlmsvc_same_host(struct nlm_host *host, struct nlm_host *other) 326nlmsvc_same_host(void *data, struct nlm_host *other)
314{ 327{
328 struct nlm_host *host = data;
329
315 return host == other; 330 return host == other;
316} 331}
317 332
318static int 333static int
319nlmsvc_is_client(struct nlm_host *host, struct nlm_host *dummy) 334nlmsvc_is_client(void *data, struct nlm_host *dummy)
320{ 335{
336 struct nlm_host *host = data;
337
321 if (host->h_server) { 338 if (host->h_server) {
322 /* we are destroying locks even though the client 339 /* we are destroying locks even though the client
323 * hasn't asked us too, so don't unmonitor the 340 * hasn't asked us too, so don't unmonitor the
@@ -337,7 +354,7 @@ void
337nlmsvc_mark_resources(void) 354nlmsvc_mark_resources(void)
338{ 355{
339 dprintk("lockd: nlmsvc_mark_resources\n"); 356 dprintk("lockd: nlmsvc_mark_resources\n");
340 nlm_traverse_files(NULL, nlmsvc_mark_host); 357 nlm_traverse_files(NULL, nlmsvc_mark_host, NULL);
341} 358}
342 359
343/* 360/*
@@ -348,7 +365,7 @@ nlmsvc_free_host_resources(struct nlm_host *host)
348{ 365{
349 dprintk("lockd: nlmsvc_free_host_resources\n"); 366 dprintk("lockd: nlmsvc_free_host_resources\n");
350 367
351 if (nlm_traverse_files(host, nlmsvc_same_host)) { 368 if (nlm_traverse_files(host, nlmsvc_same_host, NULL)) {
352 printk(KERN_WARNING 369 printk(KERN_WARNING
353 "lockd: couldn't remove all locks held by %s\n", 370 "lockd: couldn't remove all locks held by %s\n",
354 host->h_name); 371 host->h_name);
@@ -368,5 +385,41 @@ nlmsvc_invalidate_all(void)
368 * turn, which is about as inefficient as it gets. 385 * turn, which is about as inefficient as it gets.
369 * Now we just do it once in nlm_traverse_files. 386 * Now we just do it once in nlm_traverse_files.
370 */ 387 */
371 nlm_traverse_files(NULL, nlmsvc_is_client); 388 nlm_traverse_files(NULL, nlmsvc_is_client, NULL);
389}
390
391static int
392nlmsvc_match_sb(void *datap, struct nlm_file *file)
393{
394 struct super_block *sb = datap;
395
396 return sb == file->f_file->f_path.mnt->mnt_sb;
397}
398
399int
400nlmsvc_unlock_all_by_sb(struct super_block *sb)
401{
402 int ret;
403
404 ret = nlm_traverse_files(sb, nlmsvc_always_match, nlmsvc_match_sb);
405 return ret ? -EIO : 0;
406}
407EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_sb);
408
409static int
410nlmsvc_match_ip(void *datap, struct nlm_host *host)
411{
412 __be32 *server_addr = datap;
413
414 return host->h_saddr.sin_addr.s_addr == *server_addr;
415}
416
417int
418nlmsvc_unlock_all_by_ip(__be32 server_addr)
419{
420 int ret;
421 ret = nlm_traverse_files(&server_addr, nlmsvc_match_ip, NULL);
422 return ret ? -EIO : 0;
423
372} 424}
425EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_ip);
diff --git a/fs/locks.c b/fs/locks.c
index 592faadbcec1..e1ea2fe03681 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -224,7 +224,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
224/* 224/*
225 * Initialize a new lock from an existing file_lock structure. 225 * Initialize a new lock from an existing file_lock structure.
226 */ 226 */
227static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) 227void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
228{ 228{
229 new->fl_owner = fl->fl_owner; 229 new->fl_owner = fl->fl_owner;
230 new->fl_pid = fl->fl_pid; 230 new->fl_pid = fl->fl_pid;
@@ -833,7 +833,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
833 if (!posix_locks_conflict(request, fl)) 833 if (!posix_locks_conflict(request, fl))
834 continue; 834 continue;
835 if (conflock) 835 if (conflock)
836 locks_copy_lock(conflock, fl); 836 __locks_copy_lock(conflock, fl);
837 error = -EAGAIN; 837 error = -EAGAIN;
838 if (!(request->fl_flags & FL_SLEEP)) 838 if (!(request->fl_flags & FL_SLEEP))
839 goto out; 839 goto out;
@@ -1367,18 +1367,20 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
1367 1367
1368 lease = *flp; 1368 lease = *flp;
1369 1369
1370 error = -EAGAIN; 1370 if (arg != F_UNLCK) {
1371 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) 1371 error = -ENOMEM;
1372 goto out; 1372 new_fl = locks_alloc_lock();
1373 if ((arg == F_WRLCK) 1373 if (new_fl == NULL)
1374 && ((atomic_read(&dentry->d_count) > 1) 1374 goto out;
1375 || (atomic_read(&inode->i_count) > 1)))
1376 goto out;
1377 1375
1378 error = -ENOMEM; 1376 error = -EAGAIN;
1379 new_fl = locks_alloc_lock(); 1377 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
1380 if (new_fl == NULL) 1378 goto out;
1381 goto out; 1379 if ((arg == F_WRLCK)
1380 && ((atomic_read(&dentry->d_count) > 1)
1381 || (atomic_read(&inode->i_count) > 1)))
1382 goto out;
1383 }
1382 1384
1383 /* 1385 /*
1384 * At this point, we know that if there is an exclusive 1386 * At this point, we know that if there is an exclusive
@@ -1404,6 +1406,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
1404 rdlease_count++; 1406 rdlease_count++;
1405 } 1407 }
1406 1408
1409 error = -EAGAIN;
1407 if ((arg == F_RDLCK && (wrlease_count > 0)) || 1410 if ((arg == F_RDLCK && (wrlease_count > 0)) ||
1408 (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0))) 1411 (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0)))
1409 goto out; 1412 goto out;
@@ -1490,8 +1493,7 @@ EXPORT_SYMBOL_GPL(vfs_setlease);
1490int fcntl_setlease(unsigned int fd, struct file *filp, long arg) 1493int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
1491{ 1494{
1492 struct file_lock fl, *flp = &fl; 1495 struct file_lock fl, *flp = &fl;
1493 struct dentry *dentry = filp->f_path.dentry; 1496 struct inode *inode = filp->f_path.dentry->d_inode;
1494 struct inode *inode = dentry->d_inode;
1495 int error; 1497 int error;
1496 1498
1497 locks_init_lock(&fl); 1499 locks_init_lock(&fl);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 55dfdd71f1b0..8799b8708188 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2712,9 +2712,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2712 * Note: locks.c uses the BKL to protect the inode's lock list. 2712 * Note: locks.c uses the BKL to protect the inode's lock list.
2713 */ 2713 */
2714 2714
2715 /* XXX?: Just to divert the locks_release_private at the start of
2716 * locks_copy_lock: */
2717 locks_init_lock(&conflock);
2718 err = vfs_lock_file(filp, cmd, &file_lock, &conflock); 2715 err = vfs_lock_file(filp, cmd, &file_lock, &conflock);
2719 switch (-err) { 2716 switch (-err) {
2720 case 0: /* success! */ 2717 case 0: /* success! */
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1ba7ad981935..c513bbdf2d36 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -376,20 +376,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
376 goto xdr_error; 376 goto xdr_error;
377 } 377 }
378 } 378 }
379 if (bmval[1] & FATTR4_WORD1_TIME_METADATA) {
380 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
381 all 32 bits of 'nseconds'. */
382 READ_BUF(12);
383 len += 12;
384 READ32(dummy32);
385 if (dummy32)
386 return nfserr_inval;
387 READ32(iattr->ia_ctime.tv_sec);
388 READ32(iattr->ia_ctime.tv_nsec);
389 if (iattr->ia_ctime.tv_nsec >= (u32)1000000000)
390 return nfserr_inval;
391 iattr->ia_valid |= ATTR_CTIME;
392 }
393 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { 379 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
394 READ_BUF(4); 380 READ_BUF(4);
395 len += 4; 381 len += 4;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 613bcb8171a5..42f3820ee8f5 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -22,6 +22,7 @@
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/pagemap.h> 23#include <linux/pagemap.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/inet.h>
25#include <linux/string.h> 26#include <linux/string.h>
26#include <linux/smp_lock.h> 27#include <linux/smp_lock.h>
27#include <linux/ctype.h> 28#include <linux/ctype.h>
@@ -35,6 +36,7 @@
35#include <linux/nfsd/cache.h> 36#include <linux/nfsd/cache.h>
36#include <linux/nfsd/xdr.h> 37#include <linux/nfsd/xdr.h>
37#include <linux/nfsd/syscall.h> 38#include <linux/nfsd/syscall.h>
39#include <linux/lockd/lockd.h>
38 40
39#include <asm/uaccess.h> 41#include <asm/uaccess.h>
40#include <net/ipv6.h> 42#include <net/ipv6.h>
@@ -53,6 +55,8 @@ enum {
53 NFSD_Getfs, 55 NFSD_Getfs,
54 NFSD_List, 56 NFSD_List,
55 NFSD_Fh, 57 NFSD_Fh,
58 NFSD_FO_UnlockIP,
59 NFSD_FO_UnlockFS,
56 NFSD_Threads, 60 NFSD_Threads,
57 NFSD_Pool_Threads, 61 NFSD_Pool_Threads,
58 NFSD_Versions, 62 NFSD_Versions,
@@ -89,6 +93,9 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
89static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); 93static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
90#endif 94#endif
91 95
96static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size);
97static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size);
98
92static ssize_t (*write_op[])(struct file *, char *, size_t) = { 99static ssize_t (*write_op[])(struct file *, char *, size_t) = {
93 [NFSD_Svc] = write_svc, 100 [NFSD_Svc] = write_svc,
94 [NFSD_Add] = write_add, 101 [NFSD_Add] = write_add,
@@ -98,6 +105,8 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
98 [NFSD_Getfd] = write_getfd, 105 [NFSD_Getfd] = write_getfd,
99 [NFSD_Getfs] = write_getfs, 106 [NFSD_Getfs] = write_getfs,
100 [NFSD_Fh] = write_filehandle, 107 [NFSD_Fh] = write_filehandle,
108 [NFSD_FO_UnlockIP] = failover_unlock_ip,
109 [NFSD_FO_UnlockFS] = failover_unlock_fs,
101 [NFSD_Threads] = write_threads, 110 [NFSD_Threads] = write_threads,
102 [NFSD_Pool_Threads] = write_pool_threads, 111 [NFSD_Pool_Threads] = write_pool_threads,
103 [NFSD_Versions] = write_versions, 112 [NFSD_Versions] = write_versions,
@@ -298,6 +307,58 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size)
298 return err; 307 return err;
299} 308}
300 309
310static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
311{
312 __be32 server_ip;
313 char *fo_path, c;
314 int b1, b2, b3, b4;
315
316 /* sanity check */
317 if (size == 0)
318 return -EINVAL;
319
320 if (buf[size-1] != '\n')
321 return -EINVAL;
322
323 fo_path = buf;
324 if (qword_get(&buf, fo_path, size) < 0)
325 return -EINVAL;
326
327 /* get ipv4 address */
328 if (sscanf(fo_path, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
329 return -EINVAL;
330 server_ip = htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
331
332 return nlmsvc_unlock_all_by_ip(server_ip);
333}
334
335static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
336{
337 struct nameidata nd;
338 char *fo_path;
339 int error;
340
341 /* sanity check */
342 if (size == 0)
343 return -EINVAL;
344
345 if (buf[size-1] != '\n')
346 return -EINVAL;
347
348 fo_path = buf;
349 if (qword_get(&buf, fo_path, size) < 0)
350 return -EINVAL;
351
352 error = path_lookup(fo_path, 0, &nd);
353 if (error)
354 return error;
355
356 error = nlmsvc_unlock_all_by_sb(nd.path.mnt->mnt_sb);
357
358 path_put(&nd.path);
359 return error;
360}
361
301static ssize_t write_filehandle(struct file *file, char *buf, size_t size) 362static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
302{ 363{
303 /* request is: 364 /* request is:
@@ -700,6 +761,10 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
700 [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR}, 761 [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR},
701 [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR}, 762 [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR},
702 [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, 763 [NFSD_List] = {"exports", &exports_operations, S_IRUGO},
764 [NFSD_FO_UnlockIP] = {"unlock_ip",
765 &transaction_ops, S_IWUSR|S_IRUSR},
766 [NFSD_FO_UnlockFS] = {"unlock_filesystem",
767 &transaction_ops, S_IWUSR|S_IRUSR},
703 [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR}, 768 [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
704 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, 769 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
705 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, 770 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cc2be2cf7d41..6556f2f967e5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -973,6 +973,7 @@ extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
973/* fs/locks.c */ 973/* fs/locks.c */
974extern void locks_init_lock(struct file_lock *); 974extern void locks_init_lock(struct file_lock *);
975extern void locks_copy_lock(struct file_lock *, struct file_lock *); 975extern void locks_copy_lock(struct file_lock *, struct file_lock *);
976extern void __locks_copy_lock(struct file_lock *, const struct file_lock *);
976extern void locks_remove_posix(struct file *, fl_owner_t); 977extern void locks_remove_posix(struct file *, fl_owner_t);
977extern void locks_remove_flock(struct file *); 978extern void locks_remove_flock(struct file *);
978extern void posix_test_lock(struct file *, struct file_lock *); 979extern void posix_test_lock(struct file *, struct file_lock *);
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 94649a8da014..102d928f7206 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -194,7 +194,7 @@ void nsm_release(struct nsm_handle *);
194 * This is used in garbage collection and resource reclaim 194 * This is used in garbage collection and resource reclaim
195 * A return value != 0 means destroy the lock/block/share 195 * A return value != 0 means destroy the lock/block/share
196 */ 196 */
197typedef int (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref); 197typedef int (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
198 198
199/* 199/*
200 * Server-side lock handling 200 * Server-side lock handling
@@ -220,6 +220,12 @@ void nlmsvc_mark_resources(void);
220void nlmsvc_free_host_resources(struct nlm_host *); 220void nlmsvc_free_host_resources(struct nlm_host *);
221void nlmsvc_invalidate_all(void); 221void nlmsvc_invalidate_all(void);
222 222
223/*
224 * Cluster failover support
225 */
226int nlmsvc_unlock_all_by_sb(struct super_block *sb);
227int nlmsvc_unlock_all_by_ip(__be32 server_addr);
228
223static inline struct inode *nlmsvc_file_inode(struct nlm_file *file) 229static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
224{ 230{
225 return file->f_file->f_path.dentry->d_inode; 231 return file->f_file->f_path.dentry->d_inode;
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 21ee440dd3e7..41d30c9c9de6 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -329,7 +329,7 @@ extern struct timeval nfssvc_boot;
329(FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL ) 329(FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL )
330#define NFSD_WRITEABLE_ATTRS_WORD1 \ 330#define NFSD_WRITEABLE_ATTRS_WORD1 \
331(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ 331(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
332 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY_SET) 332 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
333 333
334#endif /* CONFIG_NFSD_V4 */ 334#endif /* CONFIG_NFSD_V4 */
335 335