|
@@ -49,6 +49,7 @@ enum {
|
|
|
NFSD_Leasetime,
|
|
|
NFSD_Gracetime,
|
|
|
NFSD_RecoveryDir,
|
|
|
+ NFSD_V4EndGrace,
|
|
|
#endif
|
|
|
};
|
|
|
|
|
@@ -68,6 +69,7 @@ static ssize_t write_maxconn(struct file *file, char *buf, size_t size);
|
|
|
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
|
|
|
static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
|
|
|
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
|
|
|
+static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size);
|
|
|
#endif
|
|
|
|
|
|
static ssize_t (*write_op[])(struct file *, char *, size_t) = {
|
|
@@ -84,6 +86,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
|
|
|
[NFSD_Leasetime] = write_leasetime,
|
|
|
[NFSD_Gracetime] = write_gracetime,
|
|
|
[NFSD_RecoveryDir] = write_recoverydir,
|
|
|
+ [NFSD_V4EndGrace] = write_v4_end_grace,
|
|
|
#endif
|
|
|
};
|
|
|
|
|
@@ -1077,6 +1080,47 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
|
|
|
return rv;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * write_v4_end_grace - release grace period for nfsd's v4.x lock manager
|
|
|
+ *
|
|
|
+ * Input:
|
|
|
+ * buf: ignored
|
|
|
+ * size: zero
|
|
|
+ * OR
|
|
|
+ *
|
|
|
+ * Input:
|
|
|
+ * buf: any value
|
|
|
+ * size: non-zero length of C string in @buf
|
|
|
+ * Output:
|
|
|
+ * passed-in buffer filled with "Y" or "N" with a newline
|
|
|
+ * and NULL-terminated C string. This indicates whether
|
|
|
+ * the grace period has ended in the current net
|
|
|
+ * namespace. Return code is the size in bytes of the
|
|
|
+ * string. Writing a string that starts with 'Y', 'y', or
|
|
|
+ * '1' to the file will end the grace period for nfsd's v4
|
|
|
+ * lock manager.
|
|
|
+ */
|
|
|
+static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
|
|
|
+{
|
|
|
+ struct net *net = file->f_dentry->d_sb->s_fs_info;
|
|
|
+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
|
|
+
|
|
|
+ if (size > 0) {
|
|
|
+ switch(buf[0]) {
|
|
|
+ case 'Y':
|
|
|
+ case 'y':
|
|
|
+ case '1':
|
|
|
+ nfsd4_end_grace(nn);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%c\n",
|
|
|
+ nn->grace_ended ? 'Y' : 'N');
|
|
|
+}
|
|
|
+
|
|
|
#endif
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
@@ -1110,6 +1154,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
|
|
|
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
|
|
|
[NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
|
|
|
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
|
|
|
+ [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
|
|
|
#endif
|
|
|
/* last one */ {""}
|
|
|
};
|