diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
commit | 012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch) | |
tree | 87efc733f9b164e8c85c0336f92c8fb7eff6d183 /fs/nfsd/vfs.c | |
parent | 625a1589d3d6464b5d90b8a0918789e3afffd220 (diff) |
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found
that this kernel will only boot SMP on Origin; the UP kernel freeze
soon after bootup with SCSI timeout messages. I commit this anyway
since I found that the last CVS versions had the same problem.
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 20fa7fafe..a796885e3 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1,3 +1,4 @@ +#define MSNFS /* HACK HACK */ /* * linux/fs/nfsd/vfs.c * @@ -142,6 +143,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, } else dentry = dget(dparent->d_parent); } else { + fh_lock(fhp); dentry = lookup_one(name, dparent); err = PTR_ERR(dentry); if (IS_ERR(dentry)) @@ -248,6 +250,15 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) if (err) goto out; } + + /* + * If we are changing the size of the file, then + * we need to break all leases. + */ + err = get_lease(inode, FMODE_WRITE); + if (err) + goto out_nfserr; + err = get_write_access(inode); if (err) goto out_nfserr; @@ -442,6 +453,14 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, if (!inode->i_fop) goto out; + /* + * Check to see if there are any leases on this file. + * This may block while leases are broken. + */ + err = get_lease(inode, (access & MAY_WRITE) ? FMODE_WRITE : 0); + if (err) + goto out_nfserr; + if ((access & MAY_WRITE) && (err = get_write_access(inode)) != 0) goto out_nfserr; @@ -450,11 +469,11 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, atomic_set(&filp->f_count, 1); filp->f_dentry = dentry; if (access & MAY_WRITE) { - filp->f_flags = O_WRONLY; + filp->f_flags = O_WRONLY|O_LARGEFILE; filp->f_mode = FMODE_WRITE; DQUOT_INIT(inode); } else { - filp->f_flags = O_RDONLY; + filp->f_flags = O_RDONLY|O_LARGEFILE; filp->f_mode = FMODE_READ; } @@ -576,6 +595,11 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, err = nfserr_perm; if (!file.f_op->read) goto out_close; +#ifdef MSNFS + if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && + (!lock_may_read(file.f_dentry->d_inode, offset, *count))) + goto out_close; +#endif /* Get readahead parameters */ ra = nfsd_get_raparms(fhp->fh_export->ex_dev, fhp->fh_dentry->d_inode->i_ino); @@ -642,6 +666,11 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, err = nfserr_perm; if (!file.f_op->write) goto out_close; +#ifdef MSNFS + if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && + (!lock_may_write(file.f_dentry->d_inode, offset, cnt))) + goto out_close; +#endif dentry = file.f_dentry; inode = dentry->d_inode; @@ -1249,6 +1278,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, goto out_dput_old; +#ifdef MSNFS + if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && + ((atomic_read(&odentry->d_count) > 1) + || (atomic_read(&ndentry->d_count) > 1))) { + err = nfserr_perm; + } else +#endif err = vfs_rename(fdir, odentry, tdir, ndentry); if (!err && EX_ISSYNC(tfhp->fh_export)) { nfsd_sync_dir(tdentry); @@ -1310,6 +1346,12 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, } if (type != S_IFDIR) { /* It's UNLINK */ +#ifdef MSNFS + if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && + (atomic_read(&rdentry->d_count) > 1)) { + err = nfserr_perm; + } else +#endif err = vfs_unlink(dirp, rdentry); } else { /* It's RMDIR */ err = vfs_rmdir(dirp, rdentry); |