diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4callback.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 58 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 64 | ||||
-rw-r--r-- | fs/nfsd/nfsd.h | 6 |
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 | ||
456 | static int max_cb_time(void) | 456 | static 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 */ |
47 | static time_t lease_time = 90; /* default lease time */ | 47 | time_t nfsd4_lease = 90; /* default lease time */ |
48 | static time_t user_lease_time = 90; | 48 | time_t nfsd4_grace = 90; |
49 | static time_t boot_time; | 49 | static time_t boot_time; |
50 | static u32 current_ownerid = 1; | 50 | static u32 current_ownerid = 1; |
51 | static u32 current_fileid = 1; | 51 | static 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 | ||
2558 | static time_t | 2564 | static 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 | ||
3978 | unsigned long | ||
3979 | get_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) | |||
4007 | static int | 4007 | static 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 | ||
4041 | time_t | ||
4042 | nfs4_lease_time(void) | ||
4043 | { | ||
4044 | return lease_time; | ||
4045 | } | ||
4046 | |||
4047 | static void | 4037 | static 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 | */ | ||
4143 | void | ||
4144 | nfs4_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); | |||
69 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); | 70 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); |
70 | #ifdef CONFIG_NFSD_V4 | 71 | #ifdef CONFIG_NFSD_V4 |
71 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); | 72 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); |
73 | static ssize_t write_gracetime(struct file *file, char *buf, size_t size); | ||
72 | static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); | 74 | static 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 |
1206 | extern time_t nfs4_leasetime(void); | 1209 | static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time) |
1207 | |||
1208 | static 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 | |||
1240 | static 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 | */ |
1252 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size) | 1271 | static 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 | */ | ||
1286 | static 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 | ||
1262 | extern char *nfs4_recoverydir(void); | 1291 | extern 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); | |||
82 | void nfsd4_free_slabs(void); | 82 | void nfsd4_free_slabs(void); |
83 | int nfs4_state_start(void); | 83 | int nfs4_state_start(void); |
84 | void nfs4_state_shutdown(void); | 84 | void nfs4_state_shutdown(void); |
85 | time_t nfs4_lease_time(void); | ||
86 | void nfs4_reset_lease(time_t leasetime); | 85 | void nfs4_reset_lease(time_t leasetime); |
87 | int nfs4_reset_recoverydir(char *recdir); | 86 | int nfs4_reset_recoverydir(char *recdir); |
88 | #else | 87 | #else |
@@ -90,7 +89,6 @@ static inline int nfs4_state_init(void) { return 0; } | |||
90 | static inline void nfsd4_free_slabs(void) { } | 89 | static inline void nfsd4_free_slabs(void) { } |
91 | static inline int nfs4_state_start(void) { return 0; } | 90 | static inline int nfs4_state_start(void) { return 0; } |
92 | static inline void nfs4_state_shutdown(void) { } | 91 | static inline void nfs4_state_shutdown(void) { } |
93 | static inline time_t nfs4_lease_time(void) { return 0; } | ||
94 | static inline void nfs4_reset_lease(time_t leasetime) { } | 92 | static inline void nfs4_reset_lease(time_t leasetime) { } |
95 | static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } | 93 | static 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 | ||
230 | extern time_t nfsd4_lease; | ||
231 | extern 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 | /* |