[PATCH] nfsd-patch-2.1.121

G. Allen Morris III (gam3@dharma.sehda.com)
Thu, 10 Sep 1998 12:39:15 -0700


This is a multipart MIME message.

--==_Exmh_-16273052320
Content-Type: text/plain; charset=us-ascii

The 2.1.119 would not work for 2.1.120, so here is a new patch.

--==_Exmh_-16273052320
Content-Type: text/plain; name="nfsd-patch-2.1.121"; charset=us-ascii
Content-Description: nfsd-patch-2.1.121
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="nfsd-patch-2.1.121"

Index: fs/nfsd/export.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/cvs/cvsroot/linux/fs/nfsd/export.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 export.c
--- export.c 1998/09/10 16:07:46 1.1.1.1
+++ export.c 1998/09/10 16:43:07
@@ -33,7 +33,7 @@
typedef struct svc_export svc_export;
=

static svc_export * exp_find(svc_client *clp, kdev_t dev);
-static svc_export * exp_parent(svc_client *clp, kdev_t dev);
+static svc_export * exp_parent(svc_client *clp, kdev_t dev, struct dentr=
y *dentry);
static void exp_unexport_all(svc_client *clp);
static void exp_do_unexport(svc_export *unexp);
static svc_client * exp_getclientbyname(char *name);
@@ -90,8 +90,16 @@
=

if (!clp)
return NULL;
- exp =3D exp_find(clp, dev);
- return (exp && exp->ex_ino =3D=3D ino)? exp : NULL;
+
+ exp =3D clp->cl_export[EXPORT_HASH(dev)];
+ if (exp)
+ do {
+ if (exp->ex_ino =3D=3D ino && exp->ex_dev =3D=3D dev)
+ goto out;
+ } while (NULL !=3D (exp =3D exp->ex_next));
+ exp =3D NULL;
+out:
+ return exp;
}
=

/*
@@ -129,19 +137,59 @@
* Find the parent export entry for a given fs. This function is used
* only by the export syscall to keep the export tree consistent.
*/
+/* =

+ * We can use this to find exports if we have it look at the first
+ * dentry. This makes it less efficient. <gam3@acm.org>
+ */
static svc_export *
-exp_parent(svc_client *clp, kdev_t dev)
+exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry)
{
- svc_export *exp;
+ svc_export *exp;
kdev_t xdev =3D dev;
+ struct dentry *xdentry =3D dentry;
+ struct dentry *ndentry =3D NULL;
=

- do {
- exp =3D exp_find(clp, xdev);
- if (exp)
- return exp;
- } while (nfsd_parentdev(&xdev));
+ if (clp =3D=3D NULL || dentry =3D=3D NULL)
+ return NULL;
=

- return NULL;
+ exp =3D clp->cl_export[EXPORT_HASH(dev)];
+ if (exp)
+ do {
+ ndentry =3D exp->ex_dentry;
+ if (ndentry)
+ while (ndentry =3D ndentry->d_parent) {
+ if (ndentry =3D=3D xdentry) {
+dprintk("nfsd: exp_parent mount under submount.\n");
+ goto out;
+ }
+ if (ndentry =3D=3D ndentry->d_parent)
+ break;
+ }
+ } while (NULL !=3D (exp =3D exp->ex_next));
+ do {
+ xdev =3D dev;
+ do {
+ exp =3D clp->cl_export[EXPORT_HASH(xdev)];
+ if (exp)
+ do {
+ ndentry =3D exp->ex_dentry;
+ if (ndentry =3D=3D xdentry) {
+if (dev =3D=3D xdev)
+ dprintk("nfsd: exp_parent submount over mount.\n");
+else
+ dprintk("nfsd: exp_parent found.\n");
+ goto out;
+ }
+ } while (NULL !=3D (exp =3D exp->ex_next));
+ } while (nfsd_parentdev(&xdev));
+/* It should be possible to move this to the top of this loop */
+ if (xdentry =3D=3D xdentry->d_parent) {
+ break;
+ }
+ } while (xdentry =3D xdentry->d_parent);
+ exp =3D NULL;
+out:
+ return exp;
}
=

/*
@@ -160,9 +208,10 @@
ino_t ino;
=

/* Consistency check */
+ err =3D -EINVAL;
if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) ||
!exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
- return -EINVAL;
+ goto out;
=

dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n",
nxp->ex_client, nxp->ex_path,
@@ -183,15 +232,11 @@
* If there's already an export for this file, assume this
* is just a flag update.
*/
- if ((exp =3D exp_find(clp, dev)) !=3D NULL) {
- /* Ensure there's only one export per FS. */
- err =3D -EPERM;
- if (exp->ex_ino =3D=3D ino) {
- exp->ex_flags =3D nxp->ex_flags;
- exp->ex_anon_uid =3D nxp->ex_anon_uid;
- exp->ex_anon_gid =3D nxp->ex_anon_gid;
- err =3D 0;
- }
+ if ((exp =3D exp_get(clp, dev, ino)) !=3D NULL) {
+ exp->ex_flags =3D nxp->ex_flags;
+ exp->ex_anon_uid =3D nxp->ex_anon_uid;
+ exp->ex_anon_gid =3D nxp->ex_anon_gid;
+ err =3D 0;
goto out_unlock;
}
=

@@ -203,32 +248,29 @@
=

err =3D -ENOENT;
inode =3D dentry->d_inode;
- if(!inode)
+ if (!inode)
goto finish;
err =3D -EINVAL;
- if(inode->i_dev !=3D dev || inode->i_ino !=3D nxp->ex_ino) {
-
+ if (inode->i_dev !=3D dev || inode->i_ino !=3D nxp->ex_ino) {
printk(KERN_DEBUG "exp_export: i_dev =3D %x, dev =3D %x\n",
inode->i_dev, dev); =

/* I'm just being paranoid... */
goto finish;
}
=

- /* We currently export only dirs. */
+ /* We currently export only dirs and regular files.
+ * This is what umountd does.
+ */
err =3D -ENOTDIR;
- if (!S_ISDIR(inode->i_mode))
+ if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
goto finish;
=

/* If this is a sub-export, must be root of FS */
err =3D -EINVAL;
- if ((parent =3D exp_parent(clp, dev)) !=3D NULL) {
+ if ((parent =3D exp_parent(clp, dev, dentry)) !=3D NULL) {
struct super_block *sb =3D inode->i_sb;
-
- if (inode !=3D sb->s_root->d_inode) {
-#ifdef NFSD_PARANOIA
-printk("exp_export: sub-export %s not root of device %s\n",
-nxp->ex_path, kdevname(sb->s_dev));
-#endif
+ if (dev =3D parent->ex_dev) {
+dprintk("exp_export: sub-export not valid.\n");
goto finish;
}
}
@@ -368,7 +410,6 @@
if (exp->ex_dev =3D=3D nxp->ex_dev) {
if (exp->ex_ino !=3D nxp->ex_ino) {
printk("exp_unexport: ino mismatch, %ld not %ld\n", exp->ex_ino, nxp->ex=
_ino);
- break;
}
*expp =3D exp->ex_next;
exp_do_unexport(exp);
@@ -390,20 +431,31 @@
* since its harder to fool a kernel module than a user space program.
*/
int
-exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, struct knfs_fh=
*f)
+exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, char *path, st=
ruct knfs_fh *f)
{
struct svc_export *exp;
struct dentry *dentry;
struct inode *inode;
struct svc_fh fh;
+ int err;
=

- dprintk("nfsd: exp_rootfh(%s:%x/%ld)\n", clp->cl_ident, dev, ino);
+ if (path) {
+ dentry =3D lookup_dentry(path, NULL, 0);
=

- exp =3D exp_get(clp, dev, ino);
+ dev =3D dentry->d_inode->i_dev;
+ ino =3D dentry->d_inode->i_ino;
+ =

+ dprintk("nfsd: exp_rootfh(%s [%p] %s:%x/%ld)\n", path, dentry, clp->cl=
_ident, dev, ino);
+ exp =3D exp_parent(clp, dev, dentry);
+ } else {
+ dprintk("nfsd: exp_rootfh(%s:%x/%ld)\n", clp->cl_ident, dev, ino);
+ exp =3D exp_get(clp, dev, ino);
+ dentry =3D dget(exp->ex_dentry);
+ }
+ err =3D -EPERM;
if (!exp)
- return -EPERM;
+ goto out;
=

- dentry =3D exp->ex_dentry;
inode =3D dentry->d_inode;
if(!inode) {
printk("exp_rootfh: Aieee, NULL d_inode\n");
@@ -419,11 +471,14 @@
* fh must be initialized before calling fh_compose
*/
fh_init(&fh);
- fh_compose(&fh, exp, dget(dentry));
+ fh_compose(&fh, exp, dentry);
memcpy(f, &fh.fh_handle, sizeof(struct knfs_fh));
fh_put(&fh);
-
return 0;
+
+out:
+ dput(dentry);
+ return err;
}
=

/*
Index: fs/nfsd/nfsctl.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/cvs/cvsroot/linux/fs/nfsd/nfsctl.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 nfsctl.c
--- nfsctl.c 1998/09/10 16:07:46 1.1.1.1
+++ nfsctl.c 1998/09/10 16:15:29
@@ -5,6 +5,7 @@
*
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
+#define NFS_GETFH_NEW
=

#include <linux/config.h>
#include <linux/module.h>
@@ -47,6 +48,7 @@
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_ugidupdate(struct nfsctl_ugidmap *data); */
=

static int initialized =3D 0;
@@ -108,6 +110,29 @@
#endif
=

static inline int
+nfsctl_getfd(struct nfsctl_fdparm *data, struct knfs_fh *res)
+{
+ struct sockaddr_in *sin;
+ struct svc_client *clp;
+ int err =3D 0;
+
+ if (data->gd_addr.sa_family !=3D AF_INET)
+ return -EPROTONOSUPPORT;
+ if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS)
+ return -EINVAL;
+ sin =3D (struct sockaddr_in *)&data->gd_addr;
+
+ exp_readlock();
+ if (!(clp =3D exp_getclient(sin)))
+ err =3D -EPERM;
+ else
+ err =3D exp_rootfh(clp, 0, 0, data->gd_path, res);
+ exp_unlock();
+
+ return err;
+}
+
+static inline int
nfsctl_getfh(struct nfsctl_fhparm *data, struct knfs_fh *res)
{
struct sockaddr_in *sin;
@@ -124,7 +149,7 @@
if (!(clp =3D exp_getclient(sin)))
err =3D -EPERM;
else
- err =3D exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, res);
+ err =3D exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, r=
es);
exp_unlock();
=

return err;
@@ -193,6 +218,9 @@
#endif
case NFSCTL_GETFH:
err =3D nfsctl_getfh(&arg->ca_getfh, &res->cr_getfh);
+ break;
+ case NFSCTL_GETFD:
+ err =3D nfsctl_getfd(&arg->ca_getfd, &res->cr_getfh);
break;
default:
err =3D -EINVAL;
Index: fs/nfsd/vfs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/cvs/cvsroot/linux/fs/nfsd/vfs.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 vfs.c
--- vfs.c 1998/09/10 16:07:46 1.1.1.1
+++ vfs.c 1998/09/10 16:15:29
@@ -39,6 +39,7 @@
#endif
=

#define NFSDDBG_FACILITY NFSDDBG_FILEOP
+#define NFSD_PARANOIA
=

/* Open mode for nfsd_open */
#define OPEN_READ 0
@@ -171,10 +172,19 @@
* Make sure we haven't crossed a mount point ...
*/
if (dchild->d_sb !=3D dparent->d_sb) {
+ struct dentry *tdentry;
#ifdef NFSD_PARANOIA
printk("nfsd_lookup: %s/%s crossed mount point!\n", dparent->d_name.name=
, name);
#endif
- goto out_dput;
+ tdentry =3D dchild->d_covers;
+ if (tdentry =3D=3D dchild)
+ goto out_dput;
+ dput(dchild);
+ dchild =3D dget(tdentry);
+ if (dchild->d_sb !=3D dparent->d_sb) {
+printk("nfsd_lookup: %s/%s crossed mount point!\n", dparent->d_name.name=
, dchild->d_name.name);
+ goto out_dput;
+ }
}
=

/*
Index: include/linux/nfsd/export.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/cvs/cvsroot/linux/include/linux/nfsd/export.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 export.h
--- export.h 1998/09/10 16:08:46 1.1.1.1
+++ export.h 1998/09/10 17:08:54
@@ -86,6 +86,7 @@
void exp_putclient(struct svc_client *clp);
struct svc_export * exp_get(struct svc_client *clp, kdev_t dev, ino_t in=
o);
int exp_rootfh(struct svc_client *, kdev_t, ino_t,
+ char *path,
struct knfs_fh *);
int nfserrno(int errno);
void exp_nlmdetach(void);
Index: include/linux/nfsd/syscall.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/cvs/cvsroot/linux/include/linux/nfsd/syscall.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 syscall.h
--- syscall.h 1998/09/10 16:08:46 1.1.1.1
+++ syscall.h 1998/09/10 17:15:15
@@ -32,8 +32,8 @@
#define NFSCTL_EXPORT 3 /* export a file system. */
#define NFSCTL_UNEXPORT 4 /* unexport a file system. */
#define NFSCTL_UGIDUPDATE 5 /* update a client's uid/gid map. */
-#define NFSCTL_GETFH 6 /* get an fh (used by mountd) */
-
+#define NFSCTL_GETFH 6 /* get an fh by ino (used by mountd) */
+#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
=

/* SVC */
struct nfsctl_svc {
@@ -81,6 +81,13 @@
int gf_version;
};
=

+/* GETFD */
+struct nfsctl_fdparm {
+ struct sockaddr gd_addr;
+ char gd_path[NFS_MAXPATHLEN+1];
+ int gd_version;
+};
+
/*
* This is the argument union.
*/
@@ -92,6 +99,7 @@
struct nfsctl_export u_export;
struct nfsctl_uidmap u_umap;
struct nfsctl_fhparm u_getfh;
+ struct nfsctl_fdparm u_getfd;
unsigned int u_debug;
} u;
#define ca_svc u.u_svc
@@ -99,6 +107,7 @@
#define ca_export u.u_export
#define ca_umap u.u_umap
#define ca_getfh u.u_getfh
+#define ca_getfd u.u_getfd
#define ca_authd u.u_authd
#define ca_debug u.u_debug
};

--==_Exmh_-16273052320--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/faq.html