aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c85
1 files changed, 30 insertions, 55 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 230b79fbf005..a3c7f701395a 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1,4 +1,3 @@
1#define MSNFS /* HACK HACK */
2/* 1/*
3 * File operations used by nfsd. Some of these have been ripped from 2 * File operations used by nfsd. Some of these have been ripped from
4 * other parts of the kernel because they weren't exported, others 3 * other parts of the kernel because they weren't exported, others
@@ -35,8 +34,8 @@
35#endif /* CONFIG_NFSD_V3 */ 34#endif /* CONFIG_NFSD_V3 */
36 35
37#ifdef CONFIG_NFSD_V4 36#ifdef CONFIG_NFSD_V4
38#include <linux/nfs4_acl.h> 37#include "acl.h"
39#include <linux/nfsd_idmap.h> 38#include "idmap.h"
40#endif /* CONFIG_NFSD_V4 */ 39#endif /* CONFIG_NFSD_V4 */
41 40
42#include "nfsd.h" 41#include "nfsd.h"
@@ -273,6 +272,13 @@ out:
273 return err; 272 return err;
274} 273}
275 274
275static int nfsd_break_lease(struct inode *inode)
276{
277 if (!S_ISREG(inode->i_mode))
278 return 0;
279 return break_lease(inode, O_WRONLY | O_NONBLOCK);
280}
281
276/* 282/*
277 * Commit metadata changes to stable storage. 283 * Commit metadata changes to stable storage.
278 */ 284 */
@@ -375,16 +381,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
375 goto out; 381 goto out;
376 } 382 }
377 383
378 /*
379 * If we are changing the size of the file, then
380 * we need to break all leases.
381 */
382 host_err = break_lease(inode, O_WRONLY | O_NONBLOCK);
383 if (host_err == -EWOULDBLOCK)
384 host_err = -ETIMEDOUT;
385 if (host_err) /* ENOMEM or EWOULDBLOCK */
386 goto out_nfserr;
387
388 host_err = get_write_access(inode); 384 host_err = get_write_access(inode);
389 if (host_err) 385 if (host_err)
390 goto out_nfserr; 386 goto out_nfserr;
@@ -425,7 +421,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
425 421
426 err = nfserr_notsync; 422 err = nfserr_notsync;
427 if (!check_guard || guardtime == inode->i_ctime.tv_sec) { 423 if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
424 host_err = nfsd_break_lease(inode);
425 if (host_err)
426 goto out_nfserr;
428 fh_lock(fhp); 427 fh_lock(fhp);
428
429 host_err = notify_change(dentry, iap); 429 host_err = notify_change(dentry, iap);
430 err = nfserrno(host_err); 430 err = nfserrno(host_err);
431 fh_unlock(fhp); 431 fh_unlock(fhp);
@@ -752,8 +752,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
752 */ 752 */
753 if (!(access & NFSD_MAY_NOT_BREAK_LEASE)) 753 if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
754 host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0)); 754 host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
755 if (host_err == -EWOULDBLOCK)
756 host_err = -ETIMEDOUT;
757 if (host_err) /* NOMEM or WOULDBLOCK */ 755 if (host_err) /* NOMEM or WOULDBLOCK */
758 goto out_nfserr; 756 goto out_nfserr;
759 757
@@ -874,15 +872,6 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
874 return __splice_from_pipe(pipe, sd, nfsd_splice_actor); 872 return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
875} 873}
876 874
877static inline int svc_msnfs(struct svc_fh *ffhp)
878{
879#ifdef MSNFS
880 return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS);
881#else
882 return 0;
883#endif
884}
885
886static __be32 875static __be32
887nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 876nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
888 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 877 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -895,9 +884,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
895 err = nfserr_perm; 884 err = nfserr_perm;
896 inode = file->f_path.dentry->d_inode; 885 inode = file->f_path.dentry->d_inode;
897 886
898 if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
899 goto out;
900
901 if (file->f_op->splice_read && rqstp->rq_splice_ok) { 887 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
902 struct splice_desc sd = { 888 struct splice_desc sd = {
903 .len = 0, 889 .len = 0,
@@ -922,7 +908,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
922 fsnotify_access(file); 908 fsnotify_access(file);
923 } else 909 } else
924 err = nfserrno(host_err); 910 err = nfserrno(host_err);
925out:
926 return err; 911 return err;
927} 912}
928 913
@@ -987,14 +972,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
987 int stable = *stablep; 972 int stable = *stablep;
988 int use_wgather; 973 int use_wgather;
989 974
990#ifdef MSNFS
991 err = nfserr_perm;
992
993 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
994 (!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
995 goto out;
996#endif
997
998 dentry = file->f_path.dentry; 975 dentry = file->f_path.dentry;
999 inode = dentry->d_inode; 976 inode = dentry->d_inode;
1000 exp = fhp->fh_export; 977 exp = fhp->fh_export;
@@ -1045,7 +1022,6 @@ out_nfserr:
1045 err = 0; 1022 err = 0;
1046 else 1023 else
1047 err = nfserrno(host_err); 1024 err = nfserrno(host_err);
1048out:
1049 return err; 1025 return err;
1050} 1026}
1051 1027
@@ -1665,6 +1641,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1665 err = nfserrno(host_err); 1641 err = nfserrno(host_err);
1666 goto out_dput; 1642 goto out_dput;
1667 } 1643 }
1644 err = nfserr_noent;
1645 if (!dold->d_inode)
1646 goto out_drop_write;
1647 host_err = nfsd_break_lease(dold->d_inode);
1648 if (host_err)
1649 goto out_drop_write;
1668 host_err = vfs_link(dold, dirp, dnew); 1650 host_err = vfs_link(dold, dirp, dnew);
1669 if (!host_err) { 1651 if (!host_err) {
1670 err = nfserrno(commit_metadata(ffhp)); 1652 err = nfserrno(commit_metadata(ffhp));
@@ -1676,6 +1658,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1676 else 1658 else
1677 err = nfserrno(host_err); 1659 err = nfserrno(host_err);
1678 } 1660 }
1661out_drop_write:
1679 mnt_drop_write(tfhp->fh_export->ex_path.mnt); 1662 mnt_drop_write(tfhp->fh_export->ex_path.mnt);
1680out_dput: 1663out_dput:
1681 dput(dnew); 1664 dput(dnew);
@@ -1750,12 +1733,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1750 if (ndentry == trap) 1733 if (ndentry == trap)
1751 goto out_dput_new; 1734 goto out_dput_new;
1752 1735
1753 if (svc_msnfs(ffhp) &&
1754 ((odentry->d_count > 1) || (ndentry->d_count > 1))) {
1755 host_err = -EPERM;
1756 goto out_dput_new;
1757 }
1758
1759 host_err = -EXDEV; 1736 host_err = -EXDEV;
1760 if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) 1737 if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt)
1761 goto out_dput_new; 1738 goto out_dput_new;
@@ -1763,15 +1740,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1763 if (host_err) 1740 if (host_err)
1764 goto out_dput_new; 1741 goto out_dput_new;
1765 1742
1743 host_err = nfsd_break_lease(odentry->d_inode);
1744 if (host_err)
1745 goto out_drop_write;
1766 host_err = vfs_rename(fdir, odentry, tdir, ndentry); 1746 host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1767 if (!host_err) { 1747 if (!host_err) {
1768 host_err = commit_metadata(tfhp); 1748 host_err = commit_metadata(tfhp);
1769 if (!host_err) 1749 if (!host_err)
1770 host_err = commit_metadata(ffhp); 1750 host_err = commit_metadata(ffhp);
1771 } 1751 }
1772 1752out_drop_write:
1773 mnt_drop_write(ffhp->fh_export->ex_path.mnt); 1753 mnt_drop_write(ffhp->fh_export->ex_path.mnt);
1774
1775 out_dput_new: 1754 out_dput_new:
1776 dput(ndentry); 1755 dput(ndentry);
1777 out_dput_old: 1756 out_dput_old:
@@ -1834,18 +1813,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1834 if (host_err) 1813 if (host_err)
1835 goto out_nfserr; 1814 goto out_nfserr;
1836 1815
1837 if (type != S_IFDIR) { /* It's UNLINK */ 1816 host_err = nfsd_break_lease(rdentry->d_inode);
1838#ifdef MSNFS 1817 if (host_err)
1839 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1818 goto out_put;
1840 (rdentry->d_count > 1)) { 1819 if (type != S_IFDIR)
1841 host_err = -EPERM;
1842 } else
1843#endif
1844 host_err = vfs_unlink(dirp, rdentry); 1820 host_err = vfs_unlink(dirp, rdentry);
1845 } else { /* It's RMDIR */ 1821 else
1846 host_err = vfs_rmdir(dirp, rdentry); 1822 host_err = vfs_rmdir(dirp, rdentry);
1847 } 1823out_put:
1848
1849 dput(rdentry); 1824 dput(rdentry);
1850 1825
1851 if (!host_err) 1826 if (!host_err)