summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c91
1 files changed, 30 insertions, 61 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 184938fcff0..a3c7f701395 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1,4 +1,3 @@
-#define MSNFS /* HACK HACK */
/*
* File operations used by nfsd. Some of these have been ripped from
* other parts of the kernel because they weren't exported, others
@@ -35,8 +34,8 @@
#endif /* CONFIG_NFSD_V3 */
#ifdef CONFIG_NFSD_V4
-#include <linux/nfs4_acl.h>
-#include <linux/nfsd_idmap.h>
+#include "acl.h"
+#include "idmap.h"
#endif /* CONFIG_NFSD_V4 */
#include "nfsd.h"
@@ -273,6 +272,13 @@ out:
return err;
}
+static int nfsd_break_lease(struct inode *inode)
+{
+ if (!S_ISREG(inode->i_mode))
+ return 0;
+ return break_lease(inode, O_WRONLY | O_NONBLOCK);
+}
+
/*
* Commit metadata changes to stable storage.
*/
@@ -375,16 +381,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
goto out;
}
- /*
- * If we are changing the size of the file, then
- * we need to break all leases.
- */
- host_err = break_lease(inode, O_WRONLY | O_NONBLOCK);
- if (host_err == -EWOULDBLOCK)
- host_err = -ETIMEDOUT;
- if (host_err) /* ENOMEM or EWOULDBLOCK */
- goto out_nfserr;
-
host_err = get_write_access(inode);
if (host_err)
goto out_nfserr;
@@ -425,7 +421,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
err = nfserr_notsync;
if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
+ host_err = nfsd_break_lease(inode);
+ if (host_err)
+ goto out_nfserr;
fh_lock(fhp);
+
host_err = notify_change(dentry, iap);
err = nfserrno(host_err);
fh_unlock(fhp);
@@ -752,8 +752,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
*/
if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
- if (host_err == -EWOULDBLOCK)
- host_err = -ETIMEDOUT;
if (host_err) /* NOMEM or WOULDBLOCK */
goto out_nfserr;
@@ -845,11 +843,6 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
struct page *page = buf->page;
size_t size;
- int ret;
-
- ret = buf->ops->confirm(pipe, buf);
- if (unlikely(ret))
- return ret;
size = sd->len;
@@ -879,15 +872,6 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
}
-static inline int svc_msnfs(struct svc_fh *ffhp)
-{
-#ifdef MSNFS
- return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS);
-#else
- return 0;
-#endif
-}
-
static __be32
nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -900,9 +884,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
err = nfserr_perm;
inode = file->f_path.dentry->d_inode;
- if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
- goto out;
-
if (file->f_op->splice_read && rqstp->rq_splice_ok) {
struct splice_desc sd = {
.len = 0,
@@ -927,7 +908,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
fsnotify_access(file);
} else
err = nfserrno(host_err);
-out:
return err;
}
@@ -992,14 +972,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
int stable = *stablep;
int use_wgather;
-#ifdef MSNFS
- err = nfserr_perm;
-
- if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
- (!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
- goto out;
-#endif
-
dentry = file->f_path.dentry;
inode = dentry->d_inode;
exp = fhp->fh_export;
@@ -1050,7 +1022,6 @@ out_nfserr:
err = 0;
else
err = nfserrno(host_err);
-out:
return err;
}
@@ -1670,6 +1641,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
err = nfserrno(host_err);
goto out_dput;
}
+ err = nfserr_noent;
+ if (!dold->d_inode)
+ goto out_drop_write;
+ host_err = nfsd_break_lease(dold->d_inode);
+ if (host_err)
+ goto out_drop_write;
host_err = vfs_link(dold, dirp, dnew);
if (!host_err) {
err = nfserrno(commit_metadata(ffhp));
@@ -1681,6 +1658,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
else
err = nfserrno(host_err);
}
+out_drop_write:
mnt_drop_write(tfhp->fh_export->ex_path.mnt);
out_dput:
dput(dnew);
@@ -1755,13 +1733,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
if (ndentry == trap)
goto out_dput_new;
- if (svc_msnfs(ffhp) &&
- ((atomic_read(&odentry->d_count) > 1)
- || (atomic_read(&ndentry->d_count) > 1))) {
- host_err = -EPERM;
- goto out_dput_new;
- }
-
host_err = -EXDEV;
if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt)
goto out_dput_new;
@@ -1769,15 +1740,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
if (host_err)
goto out_dput_new;
+ host_err = nfsd_break_lease(odentry->d_inode);
+ if (host_err)
+ goto out_drop_write;
host_err = vfs_rename(fdir, odentry, tdir, ndentry);
if (!host_err) {
host_err = commit_metadata(tfhp);
if (!host_err)
host_err = commit_metadata(ffhp);
}
-
+out_drop_write:
mnt_drop_write(ffhp->fh_export->ex_path.mnt);
-
out_dput_new:
dput(ndentry);
out_dput_old:
@@ -1840,18 +1813,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
if (host_err)
goto out_nfserr;
- if (type != S_IFDIR) { /* It's UNLINK */
-#ifdef MSNFS
- if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
- (atomic_read(&rdentry->d_count) > 1)) {
- host_err = -EPERM;
- } else
-#endif
+ host_err = nfsd_break_lease(rdentry->d_inode);
+ if (host_err)
+ goto out_put;
+ if (type != S_IFDIR)
host_err = vfs_unlink(dirp, rdentry);
- } else { /* It's RMDIR */
+ else
host_err = vfs_rmdir(dirp, rdentry);
- }
-
+out_put:
dput(rdentry);
if (!host_err)