patch-2.3.99-pre3 linux/fs/nfsd/nfsctl.c
Next file: linux/fs/nfsd/nfsproc.c
Previous file: linux/fs/nfsd/nfs3xdr.c
Back to the patch index
Back to the overall index
- Lines: 110
- Date:
Tue Mar 21 10:49:16 2000
- Orig file:
v2.3.99-pre2/linux/fs/nfsd/nfsctl.c
- Orig date:
Sun Mar 19 18:35:31 2000
diff -u --recursive --new-file v2.3.99-pre2/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
@@ -42,8 +42,8 @@
static int nfsctl_unexport(struct nfsctl_export *data);
static int nfsctl_getfh(struct nfsctl_fhparm *, __u8 *);
static int nfsctl_getfd(struct nfsctl_fdparm *, __u8 *);
-#ifdef notyet
static int nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *);
+#ifdef notyet
static int nfsctl_ugidupdate(struct nfsctl_ugidmap *data);
#endif
@@ -112,7 +112,6 @@
}
#endif
-#ifdef notyet
static inline int
nfsctl_getfs(struct nfsctl_fsparm *data, struct knfsd_fh *res)
{
@@ -131,10 +130,9 @@
else
err = exp_rootfh(clp, 0, 0, data->gd_path, res, data->gd_maxlen);
exp_unlock();
-
+ /*HACK*/ res->fh_size = NFS_FHSIZE; /* HACK until lockd handles var-length handles */
return err;
}
-#endif
static inline int
nfsctl_getfd(struct nfsctl_fdparm *data, __u8 *res)
@@ -206,6 +204,21 @@
#define handle_sys_nfsservctl sys_nfsservctl
#endif
+static struct {
+ int argsize, respsize;
+} sizes[] = {
+ /* NFSCTL_SVC */ { sizeof(struct nfsctl_svc), 0 },
+ /* NFSCTL_ADDCLIENT */ { sizeof(struct nfsctl_client), 0},
+ /* NFSCTL_DELCLIENT */ { sizeof(struct nfsctl_client), 0},
+ /* NFSCTL_EXPORT */ { sizeof(struct nfsctl_export), 0},
+ /* NFSCTL_UNEXPORT */ { sizeof(struct nfsctl_export), 0},
+ /* NFSCTL_UGIDUPDATE */ { sizeof(struct nfsctl_uidmap), 0},
+ /* NFSCTL_GETFH */ { sizeof(struct nfsctl_fhparm), NFS_FHSIZE},
+ /* NFSCTL_GETFD */ { sizeof(struct nfsctl_fdparm), NFS_FHSIZE},
+ /* NFSCTL_GETFS */ { sizeof(struct nfsctl_fsparm), sizeof(struct knfsd_fh)},
+};
+#define CMD_MAX (sizeof(sizes)/sizeof(sizes[0])-1)
+
int
asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
{
@@ -214,6 +227,7 @@
struct nfsctl_arg * arg = NULL;
union nfsctl_res * res = NULL;
int err;
+ int argsize, respsize;
MOD_INC_USE_COUNT;
lock_kernel ();
@@ -223,12 +237,16 @@
if (!capable(CAP_SYS_ADMIN)) {
goto done;
}
+ err = -EINVAL;
+ if (cmd<0 || cmd > CMD_MAX)
+ goto done;
err = -EFAULT;
- if (!access_ok(VERIFY_READ, argp, sizeof(*argp))
- || (resp && !access_ok(VERIFY_WRITE, resp, sizeof(*resp)))) {
+ argsize = sizes[cmd].argsize + sizeof(int); /* int for ca_version */
+ respsize = sizes[cmd].respsize; /* maximum */
+ if (!access_ok(VERIFY_READ, argp, argsize)
+ || (resp && !access_ok(VERIFY_WRITE, resp, respsize))) {
goto done;
}
-
err = -ENOMEM; /* ??? */
if (!(arg = kmalloc(sizeof(*arg), GFP_USER)) ||
(resp && !(res = kmalloc(sizeof(*res), GFP_USER)))) {
@@ -236,7 +254,7 @@
}
err = -EINVAL;
- copy_from_user(arg, argp, sizeof(*argp));
+ copy_from_user(arg, argp, argsize);
if (arg->ca_version != NFSCTL_VERSION) {
printk(KERN_WARNING "nfsd: incompatible version in syscall.\n");
goto done;
@@ -269,16 +287,16 @@
case NFSCTL_GETFD:
err = nfsctl_getfd(&arg->ca_getfd, res->cr_getfh);
break;
-#ifdef notyet
case NFSCTL_GETFS:
err = nfsctl_getfs(&arg->ca_getfs, &res->cr_getfs);
-#endif
+ respsize = res->cr_getfs.fh_size+sizeof(int);
+ break;
default:
err = -EINVAL;
}
- if (!err && resp)
- copy_to_user(resp, res, sizeof(*resp));
+ if (!err && resp && respsize)
+ copy_to_user(resp, res, respsize);
done:
if (arg)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)