diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 21:05:59 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 21:05:59 +0000 |
commit | ba2dacab305c598cd4c34a604f8e276bf5bab5ff (patch) | |
tree | 78670a0139bf4d5ace617b29b7eba82bbc74d602 /fs/nfsd/vfs.c | |
parent | b77bf69998121e689c5e86cc5630d39a0a9ee6ca (diff) |
Merge with Linux 2.3.99-pre7 and various other bits.
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 86 |
1 files changed, 40 insertions, 46 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index cb6134ca1..1110e0938 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -92,7 +92,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, { struct svc_export *exp; struct dentry *dparent; - struct nameidata nd; + struct dentry *dentry; int err; dprintk("nfsd: nfsd_lookup(fh %s, %s)\n", SVCFH_fmt(fhp), name); @@ -105,76 +105,72 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, dparent = fhp->fh_dentry; exp = fhp->fh_export; -#if 0 - err = nfsd_permission(exp, dparent, MAY_EXEC); - if (err) - goto out; -#endif err = nfserr_acces; /* Lookup the name, but don't follow links */ - if (strcmp(name, "..")==0) { + if (strcmp(name, ".")==0) { + dentry = dget(dparent); + } else if (strcmp(name, "..")==0) { /* checking mountpoint crossing is very different when stepping up */ if (dparent == exp->ex_dentry) { if (!EX_CROSSMNT(exp)) - nd.dentry = dget(dparent); /* .. == . just like at / */ + dentry = dget(dparent); /* .. == . just like at / */ else { struct svc_export *exp2 = NULL; struct dentry *dp; - nd.dentry = dparent->d_covers->d_parent; - for (dp=nd.dentry; - exp2 == NULL && dp->d_covers->d_parent != dp; - dp=dp->d_covers->d_parent) + struct vfsmount *mnt = mntget(exp->ex_mnt); + dentry = dget(dparent); + while(follow_up(&mnt, &dentry)) + ; + dp = dget(dentry->d_parent); + dput(dentry); + dentry = dp; + for ( ; exp2 == NULL && dp->d_parent != dp; + dp=dp->d_parent) exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino); - if (exp2==NULL || nd.dentry->d_sb != exp2->ex_dentry->d_sb) { - nd.dentry = dget(dparent); + if (exp2==NULL) { + dput(dentry); + dentry = dget(dparent); } else { - dget(nd.dentry); exp = exp2; } + mntput(mnt); } } else - nd.dentry = dget(dparent->d_parent); + dentry = dget(dparent->d_parent); } else { - nd.mnt = NULL; - nd.dentry = dget(dparent); - nd.flags = 0; - err = walk_name(name, &nd); - if (err) + dentry = lookup_one(name, dparent); + err = PTR_ERR(dentry); + if (IS_ERR(dentry)) goto out_nfserr; /* * check if we have crossed a mount point ... */ - if (nd.dentry->d_sb != dparent->d_sb) { + if (d_mountpoint(dentry)) { struct svc_export *exp2 = NULL; + struct vfsmount *mnt = mntget(exp->ex_mnt); + struct dentry *mounts = dget(dentry); + while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)) + ; exp2 = exp_get(rqstp->rq_client, - nd.dentry->d_inode->i_dev, - nd.dentry->d_inode->i_ino); - if (exp2 && EX_CROSSMNT(exp2)) + mounts->d_inode->i_dev, + mounts->d_inode->i_ino); + if (exp2 && EX_CROSSMNT(exp2)) { /* successfully crossed mount point */ exp = exp2; - else if (nd.dentry->d_covers->d_sb == dparent->d_sb) { - /* stay in the original filesystem */ - struct dentry *tdentry = dget(nd.dentry->d_covers); - dput(nd.dentry); - nd.dentry = tdentry; - } else { - /* This cannot possibly happen */ - printk("nfsd_lookup: %s/%s impossible mount point!\n", dparent->d_name.name, nd.dentry->d_name.name); - dput(nd.dentry); - err = nfserr_acces; - goto out; - - } + dput(dentry); + dentry = mounts; + } else + dput(mounts); } } /* * Note: we compose the file handle now, but as the * dentry may be negative, it may need to be updated. */ - err = fh_compose(resfh, exp, nd.dentry); - if (!err && !nd.dentry->d_inode) + err = fh_compose(resfh, exp, dentry); + if (!err && !dentry->d_inode) err = nfserr_noent; out: return err; @@ -201,11 +197,9 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) int size_change = 0; if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) - accmode |= MAY_WRITE; - if (iap->ia_valid & ATTR_SIZE) { - accmode |= MAY_OWNER_OVERRIDE; + accmode |= MAY_WRITE|MAY_OWNER_OVERRIDE; + if (iap->ia_valid & ATTR_SIZE) ftype = S_IFREG; - } /* Get inode */ err = fh_verify(rqstp, fhp, ftype, accmode); @@ -964,7 +958,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, */ dchild = lookup_one(fname, dentry); err = PTR_ERR(dchild); - if(IS_ERR(dchild)) + if (IS_ERR(dchild)) goto out_nfserr; err = fh_compose(resfhp, fhp->fh_export, dchild); @@ -1051,7 +1045,7 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) mm_segment_t oldfs; int err; - err = fh_verify(rqstp, fhp, S_IFLNK, MAY_READ); + err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP); if (err) goto out; |