aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4callback.c2
-rw-r--r--fs/nfsd/nfs4state.c58
-rw-r--r--fs/nfsd/nfs4xdr.c2
-rw-r--r--fs/nfsd/nfsctl.c64
-rw-r--r--fs/nfsd/nfsd.h6
5 files changed, 67 insertions, 65 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 4bc22c763de7..ed12ad40828b 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -455,7 +455,7 @@ static struct rpc_program cb_program = {
455 455
456static int max_cb_time(void) 456static int max_cb_time(void)
457{ 457{
458 return max(NFSD_LEASE_TIME/10, (time_t)1) * HZ; 458 return max(nfsd4_lease/10, (time_t)1) * HZ;
459} 459}
460 460
461/* Reference counting, callback cleanup, etc., all look racy as heck. 461/* Reference counting, callback cleanup, etc., all look racy as heck.
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c97fddbd17db..efef7f2442d5 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -44,8 +44,8 @@
44#define NFSDDBG_FACILITY NFSDDBG_PROC 44#define NFSDDBG_FACILITY NFSDDBG_PROC
45 45
46/* Globals */ 46/* Globals */
47static time_t lease_time = 90; /* default lease time */ 47time_t nfsd4_lease = 90; /* default lease time */
48static time_t user_lease_time = 90; 48time_t nfsd4_grace = 90;
49static time_t boot_time; 49static time_t boot_time;
50static u32 current_ownerid = 1; 50static u32 current_ownerid = 1;
51static u32 current_fileid = 1; 51static u32 current_fileid = 1;
@@ -2553,6 +2553,12 @@ nfsd4_end_grace(void)
2553 dprintk("NFSD: end of grace period\n"); 2553 dprintk("NFSD: end of grace period\n");
2554 nfsd4_recdir_purge_old(); 2554 nfsd4_recdir_purge_old();
2555 locks_end_grace(&nfsd4_manager); 2555 locks_end_grace(&nfsd4_manager);
2556 /*
2557 * Now that every NFSv4 client has had the chance to recover and
2558 * to see the (possibly new, possibly shorter) lease time, we
2559 * can safely set the next grace time to the current lease time:
2560 */
2561 nfsd4_grace = nfsd4_lease;
2556} 2562}
2557 2563
2558static time_t 2564static time_t
@@ -2562,9 +2568,9 @@ nfs4_laundromat(void)
2562 struct nfs4_stateowner *sop; 2568 struct nfs4_stateowner *sop;
2563 struct nfs4_delegation *dp; 2569 struct nfs4_delegation *dp;
2564 struct list_head *pos, *next, reaplist; 2570 struct list_head *pos, *next, reaplist;
2565 time_t cutoff = get_seconds() - NFSD_LEASE_TIME; 2571 time_t cutoff = get_seconds() - nfsd4_lease;
2566 time_t t, clientid_val = NFSD_LEASE_TIME; 2572 time_t t, clientid_val = nfsd4_lease;
2567 time_t u, test_val = NFSD_LEASE_TIME; 2573 time_t u, test_val = nfsd4_lease;
2568 2574
2569 nfs4_lock_state(); 2575 nfs4_lock_state();
2570 2576
@@ -2604,7 +2610,7 @@ nfs4_laundromat(void)
2604 list_del_init(&dp->dl_recall_lru); 2610 list_del_init(&dp->dl_recall_lru);
2605 unhash_delegation(dp); 2611 unhash_delegation(dp);
2606 } 2612 }
2607 test_val = NFSD_LEASE_TIME; 2613 test_val = nfsd4_lease;
2608 list_for_each_safe(pos, next, &close_lru) { 2614 list_for_each_safe(pos, next, &close_lru) {
2609 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru); 2615 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
2610 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) { 2616 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
@@ -2674,7 +2680,7 @@ EXPIRED_STATEID(stateid_t *stateid)
2674{ 2680{
2675 if (time_before((unsigned long)boot_time, 2681 if (time_before((unsigned long)boot_time,
2676 ((unsigned long)stateid->si_boot)) && 2682 ((unsigned long)stateid->si_boot)) &&
2677 time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) { 2683 time_before((unsigned long)(stateid->si_boot + nfsd4_lease), get_seconds())) {
2678 dprintk("NFSD: expired stateid " STATEID_FMT "!\n", 2684 dprintk("NFSD: expired stateid " STATEID_FMT "!\n",
2679 STATEID_VAL(stateid)); 2685 STATEID_VAL(stateid));
2680 return 1; 2686 return 1;
@@ -3975,12 +3981,6 @@ nfsd4_load_reboot_recovery_data(void)
3975 printk("NFSD: Failure reading reboot recovery data\n"); 3981 printk("NFSD: Failure reading reboot recovery data\n");
3976} 3982}
3977 3983
3978unsigned long
3979get_nfs4_grace_period(void)
3980{
3981 return max(user_lease_time, lease_time) * HZ;
3982}
3983
3984/* 3984/*
3985 * Since the lifetime of a delegation isn't limited to that of an open, a 3985 * Since the lifetime of a delegation isn't limited to that of an open, a
3986 * client may quite reasonably hang on to a delegation as long as it has 3986 * client may quite reasonably hang on to a delegation as long as it has
@@ -4007,18 +4007,14 @@ set_max_delegations(void)
4007static int 4007static int
4008__nfs4_state_start(void) 4008__nfs4_state_start(void)
4009{ 4009{
4010 unsigned long grace_time;
4011
4012 boot_time = get_seconds(); 4010 boot_time = get_seconds();
4013 grace_time = get_nfs4_grace_period();
4014 lease_time = user_lease_time;
4015 locks_start_grace(&nfsd4_manager); 4011 locks_start_grace(&nfsd4_manager);
4016 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 4012 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
4017 grace_time/HZ); 4013 nfsd4_grace);
4018 laundry_wq = create_singlethread_workqueue("nfsd4"); 4014 laundry_wq = create_singlethread_workqueue("nfsd4");
4019 if (laundry_wq == NULL) 4015 if (laundry_wq == NULL)
4020 return -ENOMEM; 4016 return -ENOMEM;
4021 queue_delayed_work(laundry_wq, &laundromat_work, grace_time); 4017 queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ);
4022 set_max_delegations(); 4018 set_max_delegations();
4023 return set_callback_cred(); 4019 return set_callback_cred();
4024} 4020}
@@ -4038,12 +4034,6 @@ nfs4_state_start(void)
4038 return 0; 4034 return 0;
4039} 4035}
4040 4036
4041time_t
4042nfs4_lease_time(void)
4043{
4044 return lease_time;
4045}
4046
4047static void 4037static void
4048__nfs4_state_shutdown(void) 4038__nfs4_state_shutdown(void)
4049{ 4039{
@@ -4127,21 +4117,3 @@ nfs4_recoverydir(void)
4127{ 4117{
4128 return user_recovery_dirname; 4118 return user_recovery_dirname;
4129} 4119}
4130
4131/*
4132 * Called when leasetime is changed.
4133 *
4134 * The only way the protocol gives us to handle on-the-fly lease changes is to
4135 * simulate a reboot. Instead of doing that, we just wait till the next time
4136 * we start to register any changes in lease time. If the administrator
4137 * really wants to change the lease time *now*, they can go ahead and bring
4138 * nfsd down and then back up again after changing the lease time.
4139 *
4140 * user_lease_time is protected by nfsd_mutex since it's only really accessed
4141 * when nfsd is starting
4142 */
4143void
4144nfs4_reset_lease(time_t leasetime)
4145{
4146 user_lease_time = leasetime;
4147}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 78c7e24e5129..fb27b1db007b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1899,7 +1899,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1899 if (bmval0 & FATTR4_WORD0_LEASE_TIME) { 1899 if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
1900 if ((buflen -= 4) < 0) 1900 if ((buflen -= 4) < 0)
1901 goto out_resource; 1901 goto out_resource;
1902 WRITE32(NFSD_LEASE_TIME); 1902 WRITE32(nfsd4_lease);
1903 } 1903 }
1904 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { 1904 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
1905 if ((buflen -= 4) < 0) 1905 if ((buflen -= 4) < 0)
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 0f0e77f2012f..413cb8ef951b 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -45,6 +45,7 @@ enum {
45 */ 45 */
46#ifdef CONFIG_NFSD_V4 46#ifdef CONFIG_NFSD_V4
47 NFSD_Leasetime, 47 NFSD_Leasetime,
48 NFSD_Gracetime,
48 NFSD_RecoveryDir, 49 NFSD_RecoveryDir,
49#endif 50#endif
50}; 51};
@@ -69,6 +70,7 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size);
69static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); 70static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
70#ifdef CONFIG_NFSD_V4 71#ifdef CONFIG_NFSD_V4
71static ssize_t write_leasetime(struct file *file, char *buf, size_t size); 72static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
73static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
72static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); 74static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
73#endif 75#endif
74 76
@@ -90,6 +92,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
90 [NFSD_MaxBlkSize] = write_maxblksize, 92 [NFSD_MaxBlkSize] = write_maxblksize,
91#ifdef CONFIG_NFSD_V4 93#ifdef CONFIG_NFSD_V4
92 [NFSD_Leasetime] = write_leasetime, 94 [NFSD_Leasetime] = write_leasetime,
95 [NFSD_Gracetime] = write_gracetime,
93 [NFSD_RecoveryDir] = write_recoverydir, 96 [NFSD_RecoveryDir] = write_recoverydir,
94#endif 97#endif
95}; 98};
@@ -1203,29 +1206,45 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
1203} 1206}
1204 1207
1205#ifdef CONFIG_NFSD_V4 1208#ifdef CONFIG_NFSD_V4
1206extern time_t nfs4_leasetime(void); 1209static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time)
1207
1208static ssize_t __write_leasetime(struct file *file, char *buf, size_t size)
1209{ 1210{
1210 /* if size > 10 seconds, call
1211 * nfs4_reset_lease() then write out the new lease (seconds) as reply
1212 */
1213 char *mesg = buf; 1211 char *mesg = buf;
1214 int rv, lease; 1212 int rv, i;
1215 1213
1216 if (size > 0) { 1214 if (size > 0) {
1217 if (nfsd_serv) 1215 if (nfsd_serv)
1218 return -EBUSY; 1216 return -EBUSY;
1219 rv = get_int(&mesg, &lease); 1217 rv = get_int(&mesg, &i);
1220 if (rv) 1218 if (rv)
1221 return rv; 1219 return rv;
1222 if (lease < 10 || lease > 3600) 1220 /*
1221 * Some sanity checking. We don't have a reason for
1222 * these particular numbers, but problems with the
1223 * extremes are:
1224 * - Too short: the briefest network outage may
1225 * cause clients to lose all their locks. Also,
1226 * the frequent polling may be wasteful.
1227 * - Too long: do you really want reboot recovery
1228 * to take more than an hour? Or to make other
1229 * clients wait an hour before being able to
1230 * revoke a dead client's locks?
1231 */
1232 if (i < 10 || i > 3600)
1223 return -EINVAL; 1233 return -EINVAL;
1224 nfs4_reset_lease(lease); 1234 *time = i;
1225 } 1235 }
1226 1236
1227 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", 1237 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time);
1228 nfs4_lease_time()); 1238}
1239
1240static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time)
1241{
1242 ssize_t rv;
1243
1244 mutex_lock(&nfsd_mutex);
1245 rv = __nfsd4_write_time(file, buf, size, time);
1246 mutex_unlock(&nfsd_mutex);
1247 return rv;
1229} 1248}
1230 1249
1231/** 1250/**
@@ -1251,12 +1270,22 @@ static ssize_t __write_leasetime(struct file *file, char *buf, size_t size)
1251 */ 1270 */
1252static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 1271static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
1253{ 1272{
1254 ssize_t rv; 1273 return nfsd4_write_time(file, buf, size, &nfsd4_lease);
1274}
1255 1275
1256 mutex_lock(&nfsd_mutex); 1276/**
1257 rv = __write_leasetime(file, buf, size); 1277 * write_gracetime - Set or report current NFSv4 grace period time
1258 mutex_unlock(&nfsd_mutex); 1278 *
1259 return rv; 1279 * As above, but sets the time of the NFSv4 grace period.
1280 *
1281 * Note this should never be set to less than the *previous*
1282 * lease-period time, but we don't try to enforce this. (In the common
1283 * case (a new boot), we don't know what the previous lease time was
1284 * anyway.)
1285 */
1286static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
1287{
1288 return nfsd4_write_time(file, buf, size, &nfsd4_grace);
1260} 1289}
1261 1290
1262extern char *nfs4_recoverydir(void); 1291extern char *nfs4_recoverydir(void);
@@ -1350,6 +1379,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1350 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, 1379 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
1351#ifdef CONFIG_NFSD_V4 1380#ifdef CONFIG_NFSD_V4
1352 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, 1381 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
1382 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
1353 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, 1383 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
1354#endif 1384#endif
1355 /* last one */ {""} 1385 /* last one */ {""}
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index e942a1aaac92..72377761270e 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -82,7 +82,6 @@ int nfs4_state_init(void);
82void nfsd4_free_slabs(void); 82void nfsd4_free_slabs(void);
83int nfs4_state_start(void); 83int nfs4_state_start(void);
84void nfs4_state_shutdown(void); 84void nfs4_state_shutdown(void);
85time_t nfs4_lease_time(void);
86void nfs4_reset_lease(time_t leasetime); 85void nfs4_reset_lease(time_t leasetime);
87int nfs4_reset_recoverydir(char *recdir); 86int nfs4_reset_recoverydir(char *recdir);
88#else 87#else
@@ -90,7 +89,6 @@ static inline int nfs4_state_init(void) { return 0; }
90static inline void nfsd4_free_slabs(void) { } 89static inline void nfsd4_free_slabs(void) { }
91static inline int nfs4_state_start(void) { return 0; } 90static inline int nfs4_state_start(void) { return 0; }
92static inline void nfs4_state_shutdown(void) { } 91static inline void nfs4_state_shutdown(void) { }
93static inline time_t nfs4_lease_time(void) { return 0; }
94static inline void nfs4_reset_lease(time_t leasetime) { } 92static inline void nfs4_reset_lease(time_t leasetime) { }
95static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } 93static inline int nfs4_reset_recoverydir(char *recdir) { return 0; }
96#endif 94#endif
@@ -229,6 +227,9 @@ extern struct timeval nfssvc_boot;
229 227
230#ifdef CONFIG_NFSD_V4 228#ifdef CONFIG_NFSD_V4
231 229
230extern time_t nfsd4_lease;
231extern time_t nfsd4_grace;
232
232/* before processing a COMPOUND operation, we have to check that there 233/* before processing a COMPOUND operation, we have to check that there
233 * is enough space in the buffer for XDR encode to succeed. otherwise, 234 * is enough space in the buffer for XDR encode to succeed. otherwise,
234 * we might process an operation with side effects, and be unable to 235 * we might process an operation with side effects, and be unable to
@@ -247,7 +248,6 @@ extern struct timeval nfssvc_boot;
247#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */ 248#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */
248#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */ 249#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */
249 250
250#define NFSD_LEASE_TIME (nfs4_lease_time())
251#define NFSD_LAUNDROMAT_MINTIMEOUT 10 /* seconds */ 251#define NFSD_LAUNDROMAT_MINTIMEOUT 10 /* seconds */
252 252
253/* 253/*