lkml.org 
[lkml]   [1998]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectknfd exports.c patch (for testing)

Here is a patch so taht you can have mulitple mounts one the
same device. It follows ther rules as stated in
_Managing NFS and NIS_ (pg 92).

I am also working on allowing mounting of subdirectories of
exports (on the same device). This will require changed to
mountd and getfh system call (dev and inode will not give
a dentry. I am going to have getfh pass the path.

Allen <gam3@acm.org>

--- linux/fs/nfsd/export.c 1998/08/29 19:38:16 1.1
+++ linux/fs/nfsd/export.c 1998/09/03 05:57:12
@@ -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 dentry *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 = exp_find(clp, dev);
- return (exp && exp->ex_ino == ino)? exp : NULL;
+
+ exp = clp->cl_export[EXPORT_HASH(dev)];
+ if (exp)
+ do {
+ if (exp->ex_ino == ino && exp->ex_dev == dev)
+ goto out;
+ } while (NULL != (exp = exp->ex_next));
+ exp = NULL;
+out:
+ return exp;
}

/*
@@ -130,18 +138,61 @@
* only by the export syscall to keep the export tree consistent.
*/
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 = dev;
+ struct dentry *xdentry = dentry;
+ struct dentry *ndentry = NULL;

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

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

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

/* Consistency check */
+ err = -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 +235,11 @@
* If there's already an export for this file, assume this
* is just a flag update.
*/
- if ((exp = exp_find(clp, dev)) != NULL) {
- /* Ensure there's only one export per FS. */
- err = -EPERM;
- if (exp->ex_ino == ino) {
- exp->ex_flags = nxp->ex_flags;
- exp->ex_anon_uid = nxp->ex_anon_uid;
- exp->ex_anon_gid = nxp->ex_anon_gid;
- err = 0;
- }
+ if ((exp = exp_get(clp, dev, ino)) != NULL) {
+ exp->ex_flags = nxp->ex_flags;
+ exp->ex_anon_uid = nxp->ex_anon_uid;
+ exp->ex_anon_gid = nxp->ex_anon_gid;
+ err = 0;
goto out_unlock;
}

@@ -203,11 +251,10 @@

err = -ENOENT;
inode = dentry->d_inode;
- if(!inode)
+ if (!inode)
goto finish;
err = -EINVAL;
- if(inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
-
+ if (inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
printk(KERN_DEBUG "exp_export: i_dev = %x, dev = %x\n",
inode->i_dev, dev);
/* I'm just being paranoid... */
@@ -221,15 +268,18 @@

/* If this is a sub-export, must be root of FS */
err = -EINVAL;
- if ((parent = exp_parent(clp, dev)) != NULL) {
+ if ((parent = exp_parent(clp, dev, dentry)) != NULL) {
struct super_block *sb = inode->i_sb;
+ if (dev = parent->ex_dev) {
+printk("exp_export: sub-export not valid.\n");
+ goto finish;
+ }

if (inode != 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
- goto finish;
}
}

@@ -368,7 +418,6 @@
if (exp->ex_dev == nxp->ex_dev) {
if (exp->ex_ino != nxp->ex_ino) {
printk("exp_unexport: ino mismatch, %ld not %ld\n", exp->ex_ino, nxp->ex_ino);
- break;
}
*expp = exp->ex_next;
exp_do_unexport(exp);
-
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.altern.org/andrebalsa/doc/lkml-faq.html

\
 
 \ /
  Last update: 2005-03-22 13:44    [W:2.801 / U:0.020 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site