mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 10:30:54 +07:00
[PATCH] knfsd: remove nfsd_versbits as intermediate storage for desired versions
We have an array 'nfsd_version' which lists the available versions of nfsd, and 'nfsd_versions' (poor choice there :-() which lists the currently active versions. Then we have a bitmap - nfsd_versbits which says which versions are wanted. The bits in this bitset cause content to be copied from nfsd_version to nfsd_versions when nfsd starts. This patch removes nfsd_versbits and moves information directly from nfsd_version to nfsd_versions when requests for version changes arrive. Note that this doesn't make it possible to change versions while the server is running. This is because serv->sv_xdrsize is calculated when a service is created, and used when threads are created, and xdrsize depends on the active versions. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
24e36663c3
commit
6658d3a7bb
@ -35,8 +35,6 @@
|
|||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
unsigned int nfsd_versbits = ~0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have a single directory with 9 nodes in it.
|
* We have a single directory with 9 nodes in it.
|
||||||
*/
|
*/
|
||||||
@ -372,6 +370,10 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
|
|||||||
|
|
||||||
if (size>0) {
|
if (size>0) {
|
||||||
if (nfsd_serv)
|
if (nfsd_serv)
|
||||||
|
/* Cannot change versions without updating
|
||||||
|
* nfsd_serv->sv_xdrsize, and reallocing
|
||||||
|
* rq_argp and rq_resp
|
||||||
|
*/
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
if (buf[size-1] != '\n')
|
if (buf[size-1] != '\n')
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -390,10 +392,7 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
|
|||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
if (sign != '-')
|
nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
|
||||||
NFSCTL_VERSET(nfsd_versbits, num);
|
|
||||||
else
|
|
||||||
NFSCTL_VERUNSET(nfsd_versbits, num);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -404,16 +403,15 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
|
|||||||
/* If all get turned off, turn them back on, as
|
/* If all get turned off, turn them back on, as
|
||||||
* having no versions is BAD
|
* having no versions is BAD
|
||||||
*/
|
*/
|
||||||
if ((nfsd_versbits & NFSCTL_VERALL)==0)
|
nfsd_reset_versions();
|
||||||
nfsd_versbits = NFSCTL_VERALL;
|
|
||||||
}
|
}
|
||||||
/* Now write current state into reply buffer */
|
/* Now write current state into reply buffer */
|
||||||
len = 0;
|
len = 0;
|
||||||
sep = "";
|
sep = "";
|
||||||
for (num=2 ; num <= 4 ; num++)
|
for (num=2 ; num <= 4 ; num++)
|
||||||
if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
|
if (nfsd_vers(num, NFSD_AVAIL)) {
|
||||||
len += sprintf(buf+len, "%s%c%d", sep,
|
len += sprintf(buf+len, "%s%c%d", sep,
|
||||||
NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
|
nfsd_vers(num, NFSD_TEST)?'+':'-',
|
||||||
num);
|
num);
|
||||||
sep = " ";
|
sep = " ";
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,32 @@ struct svc_program nfsd_program = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int nfsd_vers(int vers, enum vers_op change)
|
||||||
|
{
|
||||||
|
if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
|
||||||
|
return -1;
|
||||||
|
switch(change) {
|
||||||
|
case NFSD_SET:
|
||||||
|
nfsd_versions[vers] = nfsd_version[vers];
|
||||||
|
break;
|
||||||
|
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
||||||
|
if (vers < NFSD_ACL_NRVERS)
|
||||||
|
nfsd_acl_version[vers] = nfsd_acl_version[vers];
|
||||||
|
#endif
|
||||||
|
case NFSD_CLEAR:
|
||||||
|
nfsd_versions[vers] = NULL;
|
||||||
|
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
||||||
|
if (vers < NFSD_ACL_NRVERS)
|
||||||
|
nfsd_acl_version[vers] = NULL;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case NFSD_TEST:
|
||||||
|
return nfsd_versions[vers] != NULL;
|
||||||
|
case NFSD_AVAIL:
|
||||||
|
return nfsd_version[vers] != NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Maximum number of nfsd processes
|
* Maximum number of nfsd processes
|
||||||
*/
|
*/
|
||||||
@ -147,16 +173,36 @@ static void nfsd_last_thread(struct svc_serv *serv)
|
|||||||
nfsd_export_flush();
|
nfsd_export_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nfsd_reset_versions(void)
|
||||||
|
{
|
||||||
|
int found_one = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
|
||||||
|
if (nfsd_program.pg_vers[i])
|
||||||
|
found_one = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_one) {
|
||||||
|
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
|
||||||
|
nfsd_program.pg_vers[i] = nfsd_version[i];
|
||||||
|
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
||||||
|
for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
|
||||||
|
nfsd_acl_program.pg_vers[i] =
|
||||||
|
nfsd_acl_version[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nfsd_svc(unsigned short port, int nrservs)
|
nfsd_svc(unsigned short port, int nrservs)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
int found_one, i;
|
|
||||||
struct list_head *victim;
|
struct list_head *victim;
|
||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
dprintk("nfsd: creating service: vers 0x%x\n",
|
dprintk("nfsd: creating service\n");
|
||||||
nfsd_versbits);
|
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
if (nrservs <= 0)
|
if (nrservs <= 0)
|
||||||
nrservs = 0;
|
nrservs = 0;
|
||||||
@ -171,46 +217,7 @@ nfsd_svc(unsigned short port, int nrservs)
|
|||||||
if (error<0)
|
if (error<0)
|
||||||
goto out;
|
goto out;
|
||||||
if (!nfsd_serv) {
|
if (!nfsd_serv) {
|
||||||
/*
|
nfsd_reset_versions();
|
||||||
* Use the nfsd_ctlbits to define which
|
|
||||||
* versions that will be advertised.
|
|
||||||
* If nfsd_ctlbits doesn't list any version,
|
|
||||||
* export them all.
|
|
||||||
*/
|
|
||||||
found_one = 0;
|
|
||||||
|
|
||||||
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
|
|
||||||
if (NFSCTL_VERISSET(nfsd_versbits, i)) {
|
|
||||||
nfsd_program.pg_vers[i] = nfsd_version[i];
|
|
||||||
found_one = 1;
|
|
||||||
} else
|
|
||||||
nfsd_program.pg_vers[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_one) {
|
|
||||||
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
|
|
||||||
nfsd_program.pg_vers[i] = nfsd_version[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
|
||||||
found_one = 0;
|
|
||||||
|
|
||||||
for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
|
|
||||||
if (NFSCTL_VERISSET(nfsd_versbits, i)) {
|
|
||||||
nfsd_acl_program.pg_vers[i] =
|
|
||||||
nfsd_acl_version[i];
|
|
||||||
found_one = 1;
|
|
||||||
} else
|
|
||||||
nfsd_acl_program.pg_vers[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_one) {
|
|
||||||
for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
|
|
||||||
nfsd_acl_program.pg_vers[i] =
|
|
||||||
nfsd_acl_version[i];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
atomic_set(&nfsd_busy, 0);
|
atomic_set(&nfsd_busy, 0);
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
|
@ -140,6 +140,10 @@ struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
|
|||||||
int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
|
int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
|
||||||
|
int nfsd_vers(int vers, enum vers_op change);
|
||||||
|
void nfsd_reset_versions(void);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NFSv4 State
|
* NFSv4 State
|
||||||
|
@ -38,21 +38,6 @@
|
|||||||
#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
|
#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
|
||||||
#define NFSCTL_GETFS 8 /* get an fh by path with max FH len */
|
#define NFSCTL_GETFS 8 /* get an fh by path with max FH len */
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros used to set version
|
|
||||||
*/
|
|
||||||
#define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << (_v)))
|
|
||||||
#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
|
|
||||||
#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
|
|
||||||
|
|
||||||
#if defined(CONFIG_NFSD_V4)
|
|
||||||
#define NFSCTL_VERALL (0x1c /* 0b011100 */)
|
|
||||||
#elif defined(CONFIG_NFSD_V3)
|
|
||||||
#define NFSCTL_VERALL (0x0c /* 0b001100 */)
|
|
||||||
#else
|
|
||||||
#define NFSCTL_VERALL (0x04 /* 0b000100 */)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* SVC */
|
/* SVC */
|
||||||
struct nfsctl_svc {
|
struct nfsctl_svc {
|
||||||
unsigned short svc_port;
|
unsigned short svc_port;
|
||||||
@ -134,8 +119,6 @@ extern int exp_delclient(struct nfsctl_client *ncp);
|
|||||||
extern int exp_export(struct nfsctl_export *nxp);
|
extern int exp_export(struct nfsctl_export *nxp);
|
||||||
extern int exp_unexport(struct nfsctl_export *nxp);
|
extern int exp_unexport(struct nfsctl_export *nxp);
|
||||||
|
|
||||||
extern unsigned int nfsd_versbits;
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
#endif /* NFSD_SYSCALL_H */
|
#endif /* NFSD_SYSCALL_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user