aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6917311f201c..ed7c269e2514 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -36,7 +36,6 @@
36 */ 36 */
37 37
38#include <linux/mm.h> 38#include <linux/mm.h>
39#include <linux/utsname.h>
40#include <linux/delay.h> 39#include <linux/delay.h>
41#include <linux/errno.h> 40#include <linux/errno.h>
42#include <linux/string.h> 41#include <linux/string.h>
@@ -61,6 +60,8 @@
61#define NFS4_POLL_RETRY_MIN (HZ/10) 60#define NFS4_POLL_RETRY_MIN (HZ/10)
62#define NFS4_POLL_RETRY_MAX (15*HZ) 61#define NFS4_POLL_RETRY_MAX (15*HZ)
63 62
63#define NFS4_MAX_LOOP_ON_RECOVER (10)
64
64struct nfs4_opendata; 65struct nfs4_opendata;
65static int _nfs4_proc_open(struct nfs4_opendata *data); 66static int _nfs4_proc_open(struct nfs4_opendata *data);
66static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 67static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
@@ -426,17 +427,19 @@ out:
426static int nfs4_recover_session(struct nfs4_session *session) 427static int nfs4_recover_session(struct nfs4_session *session)
427{ 428{
428 struct nfs_client *clp = session->clp; 429 struct nfs_client *clp = session->clp;
430 unsigned int loop;
429 int ret; 431 int ret;
430 432
431 for (;;) { 433 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
432 ret = nfs4_wait_clnt_recover(clp); 434 ret = nfs4_wait_clnt_recover(clp);
433 if (ret != 0) 435 if (ret != 0)
434 return ret; 436 break;
435 if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) 437 if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
436 break; 438 break;
437 nfs4_schedule_state_manager(clp); 439 nfs4_schedule_state_manager(clp);
440 ret = -EIO;
438 } 441 }
439 return 0; 442 return ret;
440} 443}
441 444
442static int nfs41_setup_sequence(struct nfs4_session *session, 445static int nfs41_setup_sequence(struct nfs4_session *session,
@@ -1444,18 +1447,20 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1444static int nfs4_recover_expired_lease(struct nfs_server *server) 1447static int nfs4_recover_expired_lease(struct nfs_server *server)
1445{ 1448{
1446 struct nfs_client *clp = server->nfs_client; 1449 struct nfs_client *clp = server->nfs_client;
1450 unsigned int loop;
1447 int ret; 1451 int ret;
1448 1452
1449 for (;;) { 1453 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
1450 ret = nfs4_wait_clnt_recover(clp); 1454 ret = nfs4_wait_clnt_recover(clp);
1451 if (ret != 0) 1455 if (ret != 0)
1452 return ret; 1456 break;
1453 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && 1457 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1454 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state)) 1458 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
1455 break; 1459 break;
1456 nfs4_schedule_state_recovery(clp); 1460 nfs4_schedule_state_recovery(clp);
1461 ret = -EIO;
1457 } 1462 }
1458 return 0; 1463 return ret;
1459} 1464}
1460 1465
1461/* 1466/*
@@ -1997,12 +2002,34 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
1997 status = nfs4_call_sync(server, &msg, &args, &res, 0); 2002 status = nfs4_call_sync(server, &msg, &args, &res, 0);
1998 if (status == 0) { 2003 if (status == 0) {
1999 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); 2004 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
2005 server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS|
2006 NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
2007 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|
2008 NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME|
2009 NFS_CAP_CTIME|NFS_CAP_MTIME);
2000 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) 2010 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
2001 server->caps |= NFS_CAP_ACLS; 2011 server->caps |= NFS_CAP_ACLS;
2002 if (res.has_links != 0) 2012 if (res.has_links != 0)
2003 server->caps |= NFS_CAP_HARDLINKS; 2013 server->caps |= NFS_CAP_HARDLINKS;
2004 if (res.has_symlinks != 0) 2014 if (res.has_symlinks != 0)
2005 server->caps |= NFS_CAP_SYMLINKS; 2015 server->caps |= NFS_CAP_SYMLINKS;
2016 if (res.attr_bitmask[0] & FATTR4_WORD0_FILEID)
2017 server->caps |= NFS_CAP_FILEID;
2018 if (res.attr_bitmask[1] & FATTR4_WORD1_MODE)
2019 server->caps |= NFS_CAP_MODE;
2020 if (res.attr_bitmask[1] & FATTR4_WORD1_NUMLINKS)
2021 server->caps |= NFS_CAP_NLINK;
2022 if (res.attr_bitmask[1] & FATTR4_WORD1_OWNER)
2023 server->caps |= NFS_CAP_OWNER;
2024 if (res.attr_bitmask[1] & FATTR4_WORD1_OWNER_GROUP)
2025 server->caps |= NFS_CAP_OWNER_GROUP;
2026 if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_ACCESS)
2027 server->caps |= NFS_CAP_ATIME;
2028 if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_METADATA)
2029 server->caps |= NFS_CAP_CTIME;
2030 if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY)
2031 server->caps |= NFS_CAP_MTIME;
2032
2006 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask)); 2033 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
2007 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; 2034 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
2008 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 2035 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;