Messages in this thread Patch in this message | | | Date | Wed, 2 Sep 1998 23:17:58 -0700 (PDT) | From | "G. Allen Morris III" <> | Subject | knfd 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
| |