patch-2.3.51 linux/fs/nfsd/nfsctl.c

Next file: linux/fs/nfsd/nfsfh.c
Previous file: linux/fs/nfsd/nfs3xdr.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.50/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
@@ -40,8 +40,9 @@
 static int	nfsctl_delclient(struct nfsctl_client *data);
 static int	nfsctl_export(struct nfsctl_export *data);
 static int	nfsctl_unexport(struct nfsctl_export *data);
-static int	nfsctl_getfh(struct nfsctl_fhparm *, struct knfs_fh *);
-static int	nfsctl_getfd(struct nfsctl_fdparm *, struct knfs_fh *);
+static int	nfsctl_getfh(struct nfsctl_fhparm *, __u8 *);
+static int	nfsctl_getfd(struct nfsctl_fdparm *, __u8 *);
+static int	nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *);
 /* static int	nfsctl_ugidupdate(struct nfsctl_ugidmap *data); */
 
 static int	initialized = 0;
@@ -63,7 +64,6 @@
 static void
 nfsd_init(void)
 {
-	nfsd_xdr_init();	/* XDR */
 	nfsd_stat_init();	/* Statistics */
 	nfsd_cache_init();	/* RPC reply cache */
 	nfsd_export_init();	/* Exports table */
@@ -110,12 +110,37 @@
 }
 #endif
 
+#ifdef notyet
+static inline int
+nfsctl_getfs(struct nfsctl_fsparm *data, struct knfsd_fh *res)
+{
+	struct sockaddr_in	*sin;
+	struct svc_client	*clp;
+	int			err = 0;
+
+	if (data->gd_addr.sa_family != AF_INET)
+		return -EPROTONOSUPPORT;
+	sin = (struct sockaddr_in *)&data->gd_addr;
+	if (data->gd_maxlen > NFS3_FHSIZE)
+		data->gd_maxlen = NFS3_FHSIZE;
+	exp_readlock();
+	if (!(clp = exp_getclient(sin)))
+		err = -EPERM;
+	else
+		err = exp_rootfh(clp, 0, 0, data->gd_path, res, data->gd_maxlen);
+	exp_unlock();
+
+	return err;
+}
+#endif
+
 static inline int
-nfsctl_getfd(struct nfsctl_fdparm *data, struct knfs_fh *res)
+nfsctl_getfd(struct nfsctl_fdparm *data, __u8 *res)
 {
 	struct sockaddr_in	*sin;
 	struct svc_client	*clp;
 	int			err = 0;
+	struct	knfsd_fh	fh;
 
 	if (data->gd_addr.sa_family != AF_INET)
 		return -EPROTONOSUPPORT;
@@ -127,18 +152,28 @@
 	if (!(clp = exp_getclient(sin)))
 		err = -EPERM;
 	else
-		err = exp_rootfh(clp, 0, 0, data->gd_path, res);
+		err = exp_rootfh(clp, 0, 0, data->gd_path, &fh, NFS_FHSIZE);
 	exp_unlock();
 
+	if (err == 0) {
+		if (fh.fh_size > NFS_FHSIZE)
+			err = -EINVAL;
+		else {
+			memset(res,0, NFS_FHSIZE);
+			memcpy(res, fh.fh_base.fh_pad, fh.fh_size);
+		}
+	}
+
 	return err;
 }
 
 static inline int
-nfsctl_getfh(struct nfsctl_fhparm *data, struct knfs_fh *res)
+nfsctl_getfh(struct nfsctl_fhparm *data, __u8 *res)
 {
 	struct sockaddr_in	*sin;
 	struct svc_client	*clp;
 	int			err = 0;
+	struct knfsd_fh		fh;
 
 	if (data->gf_addr.sa_family != AF_INET)
 		return -EPROTONOSUPPORT;
@@ -150,9 +185,18 @@
 	if (!(clp = exp_getclient(sin)))
 		err = -EPERM;
 	else
-		err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, res);
+		err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, &fh, NFS_FHSIZE);
 	exp_unlock();
 
+	if (err == 0) {
+		if (fh.fh_size > NFS_FHSIZE)
+			err = -EINVAL;
+		else {
+			memset(res,0, NFS_FHSIZE);
+			memcpy(res, fh.fh_base.fh_pad, fh.fh_size);
+		}
+	}
+
 	return err;
 }
 
@@ -218,11 +262,15 @@
 		break;
 #endif
 	case NFSCTL_GETFH:
-		err = nfsctl_getfh(&arg->ca_getfh, &res->cr_getfh);
+		err = nfsctl_getfh(&arg->ca_getfh, res->cr_getfh);
 		break;
 	case NFSCTL_GETFD:
-		err = nfsctl_getfd(&arg->ca_getfd, &res->cr_getfh);
+		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
 	default:
 		err = -EINVAL;
 	}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)