diff options
Diffstat (limited to 'fs/nfsd/nfsctl.c')
-rw-r--r-- | fs/nfsd/nfsctl.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index e3591073098f..508941c23af7 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -46,6 +46,7 @@ enum { | |||
46 | */ | 46 | */ |
47 | #ifdef CONFIG_NFSD_V4 | 47 | #ifdef CONFIG_NFSD_V4 |
48 | NFSD_Leasetime, | 48 | NFSD_Leasetime, |
49 | NFSD_Gracetime, | ||
49 | NFSD_RecoveryDir, | 50 | NFSD_RecoveryDir, |
50 | #endif | 51 | #endif |
51 | }; | 52 | }; |
@@ -70,6 +71,7 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size); | |||
70 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); | 71 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); |
71 | #ifdef CONFIG_NFSD_V4 | 72 | #ifdef CONFIG_NFSD_V4 |
72 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); | 73 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); |
74 | static ssize_t write_gracetime(struct file *file, char *buf, size_t size); | ||
73 | static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); | 75 | static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); |
74 | #endif | 76 | #endif |
75 | 77 | ||
@@ -91,6 +93,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { | |||
91 | [NFSD_MaxBlkSize] = write_maxblksize, | 93 | [NFSD_MaxBlkSize] = write_maxblksize, |
92 | #ifdef CONFIG_NFSD_V4 | 94 | #ifdef CONFIG_NFSD_V4 |
93 | [NFSD_Leasetime] = write_leasetime, | 95 | [NFSD_Leasetime] = write_leasetime, |
96 | [NFSD_Gracetime] = write_gracetime, | ||
94 | [NFSD_RecoveryDir] = write_recoverydir, | 97 | [NFSD_RecoveryDir] = write_recoverydir, |
95 | #endif | 98 | #endif |
96 | }; | 99 | }; |
@@ -995,7 +998,7 @@ static ssize_t __write_ports_addxprt(char *buf) | |||
995 | if (sscanf(buf, "%15s %4u", transport, &port) != 2) | 998 | if (sscanf(buf, "%15s %4u", transport, &port) != 2) |
996 | return -EINVAL; | 999 | return -EINVAL; |
997 | 1000 | ||
998 | if (port < 1 || port > USHORT_MAX) | 1001 | if (port < 1 || port > USHRT_MAX) |
999 | return -EINVAL; | 1002 | return -EINVAL; |
1000 | 1003 | ||
1001 | err = nfsd_create_serv(); | 1004 | err = nfsd_create_serv(); |
@@ -1037,7 +1040,7 @@ static ssize_t __write_ports_delxprt(char *buf) | |||
1037 | if (sscanf(&buf[1], "%15s %4u", transport, &port) != 2) | 1040 | if (sscanf(&buf[1], "%15s %4u", transport, &port) != 2) |
1038 | return -EINVAL; | 1041 | return -EINVAL; |
1039 | 1042 | ||
1040 | if (port < 1 || port > USHORT_MAX || nfsd_serv == NULL) | 1043 | if (port < 1 || port > USHRT_MAX || nfsd_serv == NULL) |
1041 | return -EINVAL; | 1044 | return -EINVAL; |
1042 | 1045 | ||
1043 | xprt = svc_find_xprt(nfsd_serv, transport, AF_UNSPEC, port); | 1046 | xprt = svc_find_xprt(nfsd_serv, transport, AF_UNSPEC, port); |
@@ -1204,29 +1207,45 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) | |||
1204 | } | 1207 | } |
1205 | 1208 | ||
1206 | #ifdef CONFIG_NFSD_V4 | 1209 | #ifdef CONFIG_NFSD_V4 |
1207 | extern time_t nfs4_leasetime(void); | 1210 | static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time) |
1208 | |||
1209 | static ssize_t __write_leasetime(struct file *file, char *buf, size_t size) | ||
1210 | { | 1211 | { |
1211 | /* if size > 10 seconds, call | ||
1212 | * nfs4_reset_lease() then write out the new lease (seconds) as reply | ||
1213 | */ | ||
1214 | char *mesg = buf; | 1212 | char *mesg = buf; |
1215 | int rv, lease; | 1213 | int rv, i; |
1216 | 1214 | ||
1217 | if (size > 0) { | 1215 | if (size > 0) { |
1218 | if (nfsd_serv) | 1216 | if (nfsd_serv) |
1219 | return -EBUSY; | 1217 | return -EBUSY; |
1220 | rv = get_int(&mesg, &lease); | 1218 | rv = get_int(&mesg, &i); |
1221 | if (rv) | 1219 | if (rv) |
1222 | return rv; | 1220 | return rv; |
1223 | if (lease < 10 || lease > 3600) | 1221 | /* |
1222 | * Some sanity checking. We don't have a reason for | ||
1223 | * these particular numbers, but problems with the | ||
1224 | * extremes are: | ||
1225 | * - Too short: the briefest network outage may | ||
1226 | * cause clients to lose all their locks. Also, | ||
1227 | * the frequent polling may be wasteful. | ||
1228 | * - Too long: do you really want reboot recovery | ||
1229 | * to take more than an hour? Or to make other | ||
1230 | * clients wait an hour before being able to | ||
1231 | * revoke a dead client's locks? | ||
1232 | */ | ||
1233 | if (i < 10 || i > 3600) | ||
1224 | return -EINVAL; | 1234 | return -EINVAL; |
1225 | nfs4_reset_lease(lease); | 1235 | *time = i; |
1226 | } | 1236 | } |
1227 | 1237 | ||
1228 | return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", | 1238 | return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time); |
1229 | nfs4_lease_time()); | 1239 | } |
1240 | |||
1241 | static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time) | ||
1242 | { | ||
1243 | ssize_t rv; | ||
1244 | |||
1245 | mutex_lock(&nfsd_mutex); | ||
1246 | rv = __nfsd4_write_time(file, buf, size, time); | ||
1247 | mutex_unlock(&nfsd_mutex); | ||
1248 | return rv; | ||
1230 | } | 1249 | } |
1231 | 1250 | ||
1232 | /** | 1251 | /** |
@@ -1252,12 +1271,22 @@ static ssize_t __write_leasetime(struct file *file, char *buf, size_t size) | |||
1252 | */ | 1271 | */ |
1253 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size) | 1272 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size) |
1254 | { | 1273 | { |
1255 | ssize_t rv; | 1274 | return nfsd4_write_time(file, buf, size, &nfsd4_lease); |
1275 | } | ||
1256 | 1276 | ||
1257 | mutex_lock(&nfsd_mutex); | 1277 | /** |
1258 | rv = __write_leasetime(file, buf, size); | 1278 | * write_gracetime - Set or report current NFSv4 grace period time |
1259 | mutex_unlock(&nfsd_mutex); | 1279 | * |
1260 | return rv; | 1280 | * As above, but sets the time of the NFSv4 grace period. |
1281 | * | ||
1282 | * Note this should never be set to less than the *previous* | ||
1283 | * lease-period time, but we don't try to enforce this. (In the common | ||
1284 | * case (a new boot), we don't know what the previous lease time was | ||
1285 | * anyway.) | ||
1286 | */ | ||
1287 | static ssize_t write_gracetime(struct file *file, char *buf, size_t size) | ||
1288 | { | ||
1289 | return nfsd4_write_time(file, buf, size, &nfsd4_grace); | ||
1261 | } | 1290 | } |
1262 | 1291 | ||
1263 | extern char *nfs4_recoverydir(void); | 1292 | extern char *nfs4_recoverydir(void); |
@@ -1351,6 +1380,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
1351 | [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, | 1380 | [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, |
1352 | #ifdef CONFIG_NFSD_V4 | 1381 | #ifdef CONFIG_NFSD_V4 |
1353 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, | 1382 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
1383 | [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, | ||
1354 | [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, | 1384 | [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, |
1355 | #endif | 1385 | #endif |
1356 | /* last one */ {""} | 1386 | /* last one */ {""} |