aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/feature-removal-schedule.txt10
-rw-r--r--arch/tile/configs/tilegx_defconfig1
-rw-r--r--fs/Makefile1
-rw-r--r--fs/compat.c246
-rw-r--r--fs/nfsctl.c100
-rw-r--r--fs/nfsd/Kconfig12
-rw-r--r--fs/nfsd/export.c418
-rw-r--r--fs/nfsd/lockd.c2
-rw-r--r--fs/nfsd/nfsctl.c343
-rw-r--r--fs/nfsd/nfssvc.c7
-rw-r--r--include/linux/compat.h9
-rw-r--r--include/linux/nfsd/export.h2
-rw-r--r--include/linux/sunrpc/cache.h9
-rw-r--r--net/sunrpc/svcauth_unix.c78
14 files changed, 0 insertions, 1238 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index b1c921c27519..d43900c9ede2 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -491,16 +491,6 @@ Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
491 491
492---------------------------- 492----------------------------
493 493
494What: access to nfsd auth cache through sys_nfsservctl or '.' files
495 in the 'nfsd' filesystem.
496When: 2.6.40
497Why: This is a legacy interface which have been replaced by a more
498 dynamic cache. Continuing to maintain this interface is an
499 unnecessary burden.
500Who: NeilBrown <neilb@suse.de>
501
502----------------------------
503
504What: cancel_rearming_delayed_work[queue]() 494What: cancel_rearming_delayed_work[queue]()
505When: 2.6.39 495When: 2.6.39
506 496
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig
index 09f1c7fad8bf..2ad73fb707b9 100644
--- a/arch/tile/configs/tilegx_defconfig
+++ b/arch/tile/configs/tilegx_defconfig
@@ -1479,7 +1479,6 @@ CONFIG_NFS_FSCACHE=y
1479CONFIG_NFS_USE_KERNEL_DNS=y 1479CONFIG_NFS_USE_KERNEL_DNS=y
1480# CONFIG_NFS_USE_NEW_IDMAPPER is not set 1480# CONFIG_NFS_USE_NEW_IDMAPPER is not set
1481CONFIG_NFSD=m 1481CONFIG_NFSD=m
1482CONFIG_NFSD_DEPRECATED=y
1483CONFIG_NFSD_V2_ACL=y 1482CONFIG_NFSD_V2_ACL=y
1484CONFIG_NFSD_V3=y 1483CONFIG_NFSD_V3=y
1485CONFIG_NFSD_V3_ACL=y 1484CONFIG_NFSD_V3_ACL=y
diff --git a/fs/Makefile b/fs/Makefile
index fb68c2b8cf8a..afc109691a9b 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_EVENTFD) += eventfd.o
29obj-$(CONFIG_AIO) += aio.o 29obj-$(CONFIG_AIO) += aio.o
30obj-$(CONFIG_FILE_LOCKING) += locks.o 30obj-$(CONFIG_FILE_LOCKING) += locks.o
31obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o 31obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
32obj-$(CONFIG_NFSD_DEPRECATED) += nfsctl.o
33obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o 32obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o
34obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o 33obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o
35obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o 34obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
diff --git a/fs/compat.c b/fs/compat.c
index 0ea00832de23..0b48d018e38a 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1675,256 +1675,10 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
1675} 1675}
1676#endif /* HAVE_SET_RESTORE_SIGMASK */ 1676#endif /* HAVE_SET_RESTORE_SIGMASK */
1677 1677
1678#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && !defined(CONFIG_NFSD_DEPRECATED)
1679/* Stuff for NFS server syscalls... */
1680struct compat_nfsctl_svc {
1681 u16 svc32_port;
1682 s32 svc32_nthreads;
1683};
1684
1685struct compat_nfsctl_client {
1686 s8 cl32_ident[NFSCLNT_IDMAX+1];
1687 s32 cl32_naddr;
1688 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
1689 s32 cl32_fhkeytype;
1690 s32 cl32_fhkeylen;
1691 u8 cl32_fhkey[NFSCLNT_KEYMAX];
1692};
1693
1694struct compat_nfsctl_export {
1695 char ex32_client[NFSCLNT_IDMAX+1];
1696 char ex32_path[NFS_MAXPATHLEN+1];
1697 compat_dev_t ex32_dev;
1698 compat_ino_t ex32_ino;
1699 compat_int_t ex32_flags;
1700 __compat_uid_t ex32_anon_uid;
1701 __compat_gid_t ex32_anon_gid;
1702};
1703
1704struct compat_nfsctl_fdparm {
1705 struct sockaddr gd32_addr;
1706 s8 gd32_path[NFS_MAXPATHLEN+1];
1707 compat_int_t gd32_version;
1708};
1709
1710struct compat_nfsctl_fsparm {
1711 struct sockaddr gd32_addr;
1712 s8 gd32_path[NFS_MAXPATHLEN+1];
1713 compat_int_t gd32_maxlen;
1714};
1715
1716struct compat_nfsctl_arg {
1717 compat_int_t ca32_version; /* safeguard */
1718 union {
1719 struct compat_nfsctl_svc u32_svc;
1720 struct compat_nfsctl_client u32_client;
1721 struct compat_nfsctl_export u32_export;
1722 struct compat_nfsctl_fdparm u32_getfd;
1723 struct compat_nfsctl_fsparm u32_getfs;
1724 } u;
1725#define ca32_svc u.u32_svc
1726#define ca32_client u.u32_client
1727#define ca32_export u.u32_export
1728#define ca32_getfd u.u32_getfd
1729#define ca32_getfs u.u32_getfs
1730};
1731
1732union compat_nfsctl_res {
1733 __u8 cr32_getfh[NFS_FHSIZE];
1734 struct knfsd_fh cr32_getfs;
1735};
1736
1737static int compat_nfs_svc_trans(struct nfsctl_arg *karg,
1738 struct compat_nfsctl_arg __user *arg)
1739{
1740 if (!access_ok(VERIFY_READ, &arg->ca32_svc, sizeof(arg->ca32_svc)) ||
1741 get_user(karg->ca_version, &arg->ca32_version) ||
1742 __get_user(karg->ca_svc.svc_port, &arg->ca32_svc.svc32_port) ||
1743 __get_user(karg->ca_svc.svc_nthreads,
1744 &arg->ca32_svc.svc32_nthreads))
1745 return -EFAULT;
1746 return 0;
1747}
1748
1749static int compat_nfs_clnt_trans(struct nfsctl_arg *karg,
1750 struct compat_nfsctl_arg __user *arg)
1751{
1752 if (!access_ok(VERIFY_READ, &arg->ca32_client,
1753 sizeof(arg->ca32_client)) ||
1754 get_user(karg->ca_version, &arg->ca32_version) ||
1755 __copy_from_user(&karg->ca_client.cl_ident[0],
1756 &arg->ca32_client.cl32_ident[0],
1757 NFSCLNT_IDMAX) ||
1758 __get_user(karg->ca_client.cl_naddr,
1759 &arg->ca32_client.cl32_naddr) ||
1760 __copy_from_user(&karg->ca_client.cl_addrlist[0],
1761 &arg->ca32_client.cl32_addrlist[0],
1762 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)) ||
1763 __get_user(karg->ca_client.cl_fhkeytype,
1764 &arg->ca32_client.cl32_fhkeytype) ||
1765 __get_user(karg->ca_client.cl_fhkeylen,
1766 &arg->ca32_client.cl32_fhkeylen) ||
1767 __copy_from_user(&karg->ca_client.cl_fhkey[0],
1768 &arg->ca32_client.cl32_fhkey[0],
1769 NFSCLNT_KEYMAX))
1770 return -EFAULT;
1771
1772 return 0;
1773}
1774
1775static int compat_nfs_exp_trans(struct nfsctl_arg *karg,
1776 struct compat_nfsctl_arg __user *arg)
1777{
1778 if (!access_ok(VERIFY_READ, &arg->ca32_export,
1779 sizeof(arg->ca32_export)) ||
1780 get_user(karg->ca_version, &arg->ca32_version) ||
1781 __copy_from_user(&karg->ca_export.ex_client[0],
1782 &arg->ca32_export.ex32_client[0],
1783 NFSCLNT_IDMAX) ||
1784 __copy_from_user(&karg->ca_export.ex_path[0],
1785 &arg->ca32_export.ex32_path[0],
1786 NFS_MAXPATHLEN) ||
1787 __get_user(karg->ca_export.ex_dev,
1788 &arg->ca32_export.ex32_dev) ||
1789 __get_user(karg->ca_export.ex_ino,
1790 &arg->ca32_export.ex32_ino) ||
1791 __get_user(karg->ca_export.ex_flags,
1792 &arg->ca32_export.ex32_flags) ||
1793 __get_user(karg->ca_export.ex_anon_uid,
1794 &arg->ca32_export.ex32_anon_uid) ||
1795 __get_user(karg->ca_export.ex_anon_gid,
1796 &arg->ca32_export.ex32_anon_gid))
1797 return -EFAULT;
1798 SET_UID(karg->ca_export.ex_anon_uid, karg->ca_export.ex_anon_uid);
1799 SET_GID(karg->ca_export.ex_anon_gid, karg->ca_export.ex_anon_gid);
1800
1801 return 0;
1802}
1803
1804static int compat_nfs_getfd_trans(struct nfsctl_arg *karg,
1805 struct compat_nfsctl_arg __user *arg)
1806{
1807 if (!access_ok(VERIFY_READ, &arg->ca32_getfd,
1808 sizeof(arg->ca32_getfd)) ||
1809 get_user(karg->ca_version, &arg->ca32_version) ||
1810 __copy_from_user(&karg->ca_getfd.gd_addr,
1811 &arg->ca32_getfd.gd32_addr,
1812 (sizeof(struct sockaddr))) ||
1813 __copy_from_user(&karg->ca_getfd.gd_path,
1814 &arg->ca32_getfd.gd32_path,
1815 (NFS_MAXPATHLEN+1)) ||
1816 __get_user(karg->ca_getfd.gd_version,
1817 &arg->ca32_getfd.gd32_version))
1818 return -EFAULT;
1819
1820 return 0;
1821}
1822
1823static int compat_nfs_getfs_trans(struct nfsctl_arg *karg,
1824 struct compat_nfsctl_arg __user *arg)
1825{
1826 if (!access_ok(VERIFY_READ,&arg->ca32_getfs,sizeof(arg->ca32_getfs)) ||
1827 get_user(karg->ca_version, &arg->ca32_version) ||
1828 __copy_from_user(&karg->ca_getfs.gd_addr,
1829 &arg->ca32_getfs.gd32_addr,
1830 (sizeof(struct sockaddr))) ||
1831 __copy_from_user(&karg->ca_getfs.gd_path,
1832 &arg->ca32_getfs.gd32_path,
1833 (NFS_MAXPATHLEN+1)) ||
1834 __get_user(karg->ca_getfs.gd_maxlen,
1835 &arg->ca32_getfs.gd32_maxlen))
1836 return -EFAULT;
1837
1838 return 0;
1839}
1840
1841/* This really doesn't need translations, we are only passing
1842 * back a union which contains opaque nfs file handle data.
1843 */
1844static int compat_nfs_getfh_res_trans(union nfsctl_res *kres,
1845 union compat_nfsctl_res __user *res)
1846{
1847 int err;
1848
1849 err = copy_to_user(res, kres, sizeof(*res));
1850
1851 return (err) ? -EFAULT : 0;
1852}
1853
1854asmlinkage long compat_sys_nfsservctl(int cmd,
1855 struct compat_nfsctl_arg __user *arg,
1856 union compat_nfsctl_res __user *res)
1857{
1858 struct nfsctl_arg *karg;
1859 union nfsctl_res *kres;
1860 mm_segment_t oldfs;
1861 int err;
1862
1863 karg = kmalloc(sizeof(*karg), GFP_USER);
1864 kres = kmalloc(sizeof(*kres), GFP_USER);
1865 if(!karg || !kres) {
1866 err = -ENOMEM;
1867 goto done;
1868 }
1869
1870 switch(cmd) {
1871 case NFSCTL_SVC:
1872 err = compat_nfs_svc_trans(karg, arg);
1873 break;
1874
1875 case NFSCTL_ADDCLIENT:
1876 err = compat_nfs_clnt_trans(karg, arg);
1877 break;
1878
1879 case NFSCTL_DELCLIENT:
1880 err = compat_nfs_clnt_trans(karg, arg);
1881 break;
1882
1883 case NFSCTL_EXPORT:
1884 case NFSCTL_UNEXPORT:
1885 err = compat_nfs_exp_trans(karg, arg);
1886 break;
1887
1888 case NFSCTL_GETFD:
1889 err = compat_nfs_getfd_trans(karg, arg);
1890 break;
1891
1892 case NFSCTL_GETFS:
1893 err = compat_nfs_getfs_trans(karg, arg);
1894 break;
1895
1896 default:
1897 err = -EINVAL;
1898 break;
1899 }
1900
1901 if (err)
1902 goto done;
1903
1904 oldfs = get_fs();
1905 set_fs(KERNEL_DS);
1906 /* The __user pointer casts are valid because of the set_fs() */
1907 err = sys_nfsservctl(cmd, (void __user *) karg, (void __user *) kres);
1908 set_fs(oldfs);
1909
1910 if (err)
1911 goto done;
1912
1913 if((cmd == NFSCTL_GETFD) ||
1914 (cmd == NFSCTL_GETFS))
1915 err = compat_nfs_getfh_res_trans(kres, res);
1916
1917done:
1918 kfree(karg);
1919 kfree(kres);
1920 return err;
1921}
1922#else /* !NFSD */
1923long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2) 1678long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2)
1924{ 1679{
1925 return sys_ni_syscall(); 1680 return sys_ni_syscall();
1926} 1681}
1927#endif
1928 1682
1929#ifdef CONFIG_EPOLL 1683#ifdef CONFIG_EPOLL
1930 1684
diff --git a/fs/nfsctl.c b/fs/nfsctl.c
deleted file mode 100644
index 124e8fcb0dd6..000000000000
--- a/fs/nfsctl.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * fs/nfsctl.c
3 *
4 * This should eventually move to userland.
5 *
6 */
7#include <linux/types.h>
8#include <linux/file.h>
9#include <linux/fs.h>
10#include <linux/nfsd/syscall.h>
11#include <linux/cred.h>
12#include <linux/sched.h>
13#include <linux/linkage.h>
14#include <linux/namei.h>
15#include <linux/mount.h>
16#include <linux/syscalls.h>
17#include <asm/uaccess.h>
18
19/*
20 * open a file on nfsd fs
21 */
22
23static struct file *do_open(char *name, int flags)
24{
25 struct vfsmount *mnt;
26 struct file *file;
27
28 mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
29 if (IS_ERR(mnt))
30 return (struct file *)mnt;
31
32 file = file_open_root(mnt->mnt_root, mnt, name, flags);
33
34 mntput(mnt); /* drop do_kern_mount reference */
35 return file;
36}
37
38static struct {
39 char *name; int wsize; int rsize;
40} map[] = {
41 [NFSCTL_SVC] = {
42 .name = ".svc",
43 .wsize = sizeof(struct nfsctl_svc)
44 },
45 [NFSCTL_ADDCLIENT] = {
46 .name = ".add",
47 .wsize = sizeof(struct nfsctl_client)
48 },
49 [NFSCTL_DELCLIENT] = {
50 .name = ".del",
51 .wsize = sizeof(struct nfsctl_client)
52 },
53 [NFSCTL_EXPORT] = {
54 .name = ".export",
55 .wsize = sizeof(struct nfsctl_export)
56 },
57 [NFSCTL_UNEXPORT] = {
58 .name = ".unexport",
59 .wsize = sizeof(struct nfsctl_export)
60 },
61 [NFSCTL_GETFD] = {
62 .name = ".getfd",
63 .wsize = sizeof(struct nfsctl_fdparm),
64 .rsize = NFS_FHSIZE
65 },
66 [NFSCTL_GETFS] = {
67 .name = ".getfs",
68 .wsize = sizeof(struct nfsctl_fsparm),
69 .rsize = sizeof(struct knfsd_fh)
70 },
71};
72
73SYSCALL_DEFINE3(nfsservctl, int, cmd, struct nfsctl_arg __user *, arg,
74 void __user *, res)
75{
76 struct file *file;
77 void __user *p = &arg->u;
78 int version;
79 int err;
80
81 if (copy_from_user(&version, &arg->ca_version, sizeof(int)))
82 return -EFAULT;
83
84 if (version != NFSCTL_VERSION)
85 return -EINVAL;
86
87 if (cmd < 0 || cmd >= ARRAY_SIZE(map) || !map[cmd].name)
88 return -EINVAL;
89
90 file = do_open(map[cmd].name, map[cmd].rsize ? O_RDWR : O_WRONLY);
91 if (IS_ERR(file))
92 return PTR_ERR(file);
93 err = file->f_op->write(file, p, map[cmd].wsize, &file->f_pos);
94 if (err >= 0 && map[cmd].rsize)
95 err = file->f_op->read(file, res, map[cmd].rsize, &file->f_pos);
96 if (err >= 0)
97 err = 0;
98 fput(file);
99 return err;
100}
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index fbb2a5ef5817..10e6366608f2 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -28,18 +28,6 @@ config NFSD
28 28
29 If unsure, say N. 29 If unsure, say N.
30 30
31config NFSD_DEPRECATED
32 bool "Include support for deprecated syscall interface to NFSD"
33 depends on NFSD
34 default y
35 help
36 The syscall interface to nfsd was obsoleted in 2.6.0 by a new
37 filesystem based interface. The old interface is due for removal
38 in 2.6.40. If you wish to remove the interface before then
39 say N.
40
41 In unsure, say Y.
42
43config NFSD_V2_ACL 31config NFSD_V2_ACL
44 bool 32 bool
45 depends on NFSD 33 depends on NFSD
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index b9566e46219f..f4cc1e2bfc54 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -797,58 +797,6 @@ exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp)
797 return ek; 797 return ek;
798} 798}
799 799
800#ifdef CONFIG_NFSD_DEPRECATED
801static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv,
802 struct svc_export *exp)
803{
804 struct svc_expkey key, *ek;
805
806 key.ek_client = clp;
807 key.ek_fsidtype = fsid_type;
808 memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
809 key.ek_path = exp->ex_path;
810 key.h.expiry_time = NEVER;
811 key.h.flags = 0;
812
813 ek = svc_expkey_lookup(&key);
814 if (ek)
815 ek = svc_expkey_update(&key,ek);
816 if (ek) {
817 cache_put(&ek->h, &svc_expkey_cache);
818 return 0;
819 }
820 return -ENOMEM;
821}
822
823/*
824 * Find the client's export entry matching xdev/xino.
825 */
826static inline struct svc_expkey *
827exp_get_key(svc_client *clp, dev_t dev, ino_t ino)
828{
829 u32 fsidv[3];
830
831 if (old_valid_dev(dev)) {
832 mk_fsid(FSID_DEV, fsidv, dev, ino, 0, NULL);
833 return exp_find_key(clp, FSID_DEV, fsidv, NULL);
834 }
835 mk_fsid(FSID_ENCODE_DEV, fsidv, dev, ino, 0, NULL);
836 return exp_find_key(clp, FSID_ENCODE_DEV, fsidv, NULL);
837}
838
839/*
840 * Find the client's export entry matching fsid
841 */
842static inline struct svc_expkey *
843exp_get_fsid_key(svc_client *clp, int fsid)
844{
845 u32 fsidv[2];
846
847 mk_fsid(FSID_NUM, fsidv, 0, 0, fsid, NULL);
848
849 return exp_find_key(clp, FSID_NUM, fsidv, NULL);
850}
851#endif
852 800
853static svc_export *exp_get_by_name(svc_client *clp, const struct path *path, 801static svc_export *exp_get_by_name(svc_client *clp, const struct path *path,
854 struct cache_req *reqp) 802 struct cache_req *reqp)
@@ -890,275 +838,7 @@ static struct svc_export *exp_parent(svc_client *clp, struct path *path)
890 return exp; 838 return exp;
891} 839}
892 840
893#ifdef CONFIG_NFSD_DEPRECATED
894/*
895 * Hashtable locking. Write locks are placed only by user processes
896 * wanting to modify export information.
897 * Write locking only done in this file. Read locking
898 * needed externally.
899 */
900
901static DECLARE_RWSEM(hash_sem);
902
903void
904exp_readlock(void)
905{
906 down_read(&hash_sem);
907}
908
909static inline void
910exp_writelock(void)
911{
912 down_write(&hash_sem);
913}
914
915void
916exp_readunlock(void)
917{
918 up_read(&hash_sem);
919}
920
921static inline void
922exp_writeunlock(void)
923{
924 up_write(&hash_sem);
925}
926#else
927
928/* hash_sem not needed once deprecated interface is removed */
929void exp_readlock(void) {}
930static inline void exp_writelock(void){}
931void exp_readunlock(void) {}
932static inline void exp_writeunlock(void){}
933
934#endif
935
936#ifdef CONFIG_NFSD_DEPRECATED
937static void exp_do_unexport(svc_export *unexp);
938static int exp_verify_string(char *cp, int max);
939
940static void exp_fsid_unhash(struct svc_export *exp)
941{
942 struct svc_expkey *ek;
943
944 if ((exp->ex_flags & NFSEXP_FSID) == 0)
945 return;
946
947 ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid);
948 if (!IS_ERR(ek)) {
949 sunrpc_invalidate(&ek->h, &svc_expkey_cache);
950 cache_put(&ek->h, &svc_expkey_cache);
951 }
952}
953
954static int exp_fsid_hash(svc_client *clp, struct svc_export *exp)
955{
956 u32 fsid[2];
957
958 if ((exp->ex_flags & NFSEXP_FSID) == 0)
959 return 0;
960
961 mk_fsid(FSID_NUM, fsid, 0, 0, exp->ex_fsid, NULL);
962 return exp_set_key(clp, FSID_NUM, fsid, exp);
963}
964
965static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
966{
967 u32 fsid[2];
968 struct inode *inode = exp->ex_path.dentry->d_inode;
969 dev_t dev = inode->i_sb->s_dev;
970
971 if (old_valid_dev(dev)) {
972 mk_fsid(FSID_DEV, fsid, dev, inode->i_ino, 0, NULL);
973 return exp_set_key(clp, FSID_DEV, fsid, exp);
974 }
975 mk_fsid(FSID_ENCODE_DEV, fsid, dev, inode->i_ino, 0, NULL);
976 return exp_set_key(clp, FSID_ENCODE_DEV, fsid, exp);
977}
978 841
979static void exp_unhash(struct svc_export *exp)
980{
981 struct svc_expkey *ek;
982 struct inode *inode = exp->ex_path.dentry->d_inode;
983
984 ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino);
985 if (!IS_ERR(ek)) {
986 sunrpc_invalidate(&ek->h, &svc_expkey_cache);
987 cache_put(&ek->h, &svc_expkey_cache);
988 }
989}
990
991/*
992 * Export a file system.
993 */
994int
995exp_export(struct nfsctl_export *nxp)
996{
997 svc_client *clp;
998 struct svc_export *exp = NULL;
999 struct svc_export new;
1000 struct svc_expkey *fsid_key = NULL;
1001 struct path path;
1002 int err;
1003
1004 /* Consistency check */
1005 err = -EINVAL;
1006 if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) ||
1007 !exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
1008 goto out;
1009
1010 dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n",
1011 nxp->ex_client, nxp->ex_path,
1012 (unsigned)nxp->ex_dev, (long)nxp->ex_ino,
1013 nxp->ex_flags);
1014
1015 /* Try to lock the export table for update */
1016 exp_writelock();
1017
1018 /* Look up client info */
1019 if (!(clp = auth_domain_find(nxp->ex_client)))
1020 goto out_unlock;
1021
1022
1023 /* Look up the dentry */
1024 err = kern_path(nxp->ex_path, 0, &path);
1025 if (err)
1026 goto out_put_clp;
1027 err = -EINVAL;
1028
1029 exp = exp_get_by_name(clp, &path, NULL);
1030
1031 memset(&new, 0, sizeof(new));
1032
1033 /* must make sure there won't be an ex_fsid clash */
1034 if ((nxp->ex_flags & NFSEXP_FSID) &&
1035 (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
1036 fsid_key->ek_path.mnt &&
1037 (fsid_key->ek_path.mnt != path.mnt ||
1038 fsid_key->ek_path.dentry != path.dentry))
1039 goto finish;
1040
1041 if (!IS_ERR(exp)) {
1042 /* just a flags/id/fsid update */
1043
1044 exp_fsid_unhash(exp);
1045 exp->ex_flags = nxp->ex_flags;
1046 exp->ex_anon_uid = nxp->ex_anon_uid;
1047 exp->ex_anon_gid = nxp->ex_anon_gid;
1048 exp->ex_fsid = nxp->ex_dev;
1049
1050 err = exp_fsid_hash(clp, exp);
1051 goto finish;
1052 }
1053
1054 err = check_export(path.dentry->d_inode, &nxp->ex_flags, NULL);
1055 if (err) goto finish;
1056
1057 err = -ENOMEM;
1058
1059 dprintk("nfsd: creating export entry %p for client %p\n", exp, clp);
1060
1061 new.h.expiry_time = NEVER;
1062 new.h.flags = 0;
1063 new.ex_pathname = kstrdup(nxp->ex_path, GFP_KERNEL);
1064 if (!new.ex_pathname)
1065 goto finish;
1066 new.ex_client = clp;
1067 new.ex_path = path;
1068 new.ex_flags = nxp->ex_flags;
1069 new.ex_anon_uid = nxp->ex_anon_uid;
1070 new.ex_anon_gid = nxp->ex_anon_gid;
1071 new.ex_fsid = nxp->ex_dev;
1072
1073 exp = svc_export_lookup(&new);
1074 if (exp)
1075 exp = svc_export_update(&new, exp);
1076
1077 if (!exp)
1078 goto finish;
1079
1080 if (exp_hash(clp, exp) ||
1081 exp_fsid_hash(clp, exp)) {
1082 /* failed to create at least one index */
1083 exp_do_unexport(exp);
1084 cache_flush();
1085 } else
1086 err = 0;
1087finish:
1088 kfree(new.ex_pathname);
1089 if (!IS_ERR_OR_NULL(exp))
1090 exp_put(exp);
1091 if (!IS_ERR_OR_NULL(fsid_key))
1092 cache_put(&fsid_key->h, &svc_expkey_cache);
1093 path_put(&path);
1094out_put_clp:
1095 auth_domain_put(clp);
1096out_unlock:
1097 exp_writeunlock();
1098out:
1099 return err;
1100}
1101
1102/*
1103 * Unexport a file system. The export entry has already
1104 * been removed from the client's list of exported fs's.
1105 */
1106static void
1107exp_do_unexport(svc_export *unexp)
1108{
1109 sunrpc_invalidate(&unexp->h, &svc_export_cache);
1110 exp_unhash(unexp);
1111 exp_fsid_unhash(unexp);
1112}
1113
1114
1115/*
1116 * unexport syscall.
1117 */
1118int
1119exp_unexport(struct nfsctl_export *nxp)
1120{
1121 struct auth_domain *dom;
1122 svc_export *exp;
1123 struct path path;
1124 int err;
1125
1126 /* Consistency check */
1127 if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) ||
1128 !exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
1129 return -EINVAL;
1130
1131 exp_writelock();
1132
1133 err = -EINVAL;
1134 dom = auth_domain_find(nxp->ex_client);
1135 if (!dom) {
1136 dprintk("nfsd: unexport couldn't find %s\n", nxp->ex_client);
1137 goto out_unlock;
1138 }
1139
1140 err = kern_path(nxp->ex_path, 0, &path);
1141 if (err)
1142 goto out_domain;
1143
1144 err = -EINVAL;
1145 exp = exp_get_by_name(dom, &path, NULL);
1146 path_put(&path);
1147 if (IS_ERR(exp))
1148 goto out_domain;
1149
1150 exp_do_unexport(exp);
1151 exp_put(exp);
1152 err = 0;
1153
1154out_domain:
1155 auth_domain_put(dom);
1156 cache_flush();
1157out_unlock:
1158 exp_writeunlock();
1159 return err;
1160}
1161#endif /* CONFIG_NFSD_DEPRECATED */
1162 842
1163/* 843/*
1164 * Obtain the root fh on behalf of a client. 844 * Obtain the root fh on behalf of a client.
@@ -1367,7 +1047,6 @@ static void *e_start(struct seq_file *m, loff_t *pos)
1367 unsigned hash, export; 1047 unsigned hash, export;
1368 struct cache_head *ch; 1048 struct cache_head *ch;
1369 1049
1370 exp_readlock();
1371 read_lock(&svc_export_cache.hash_lock); 1050 read_lock(&svc_export_cache.hash_lock);
1372 if (!n--) 1051 if (!n--)
1373 return SEQ_START_TOKEN; 1052 return SEQ_START_TOKEN;
@@ -1418,7 +1097,6 @@ static void e_stop(struct seq_file *m, void *p)
1418 __releases(svc_export_cache.hash_lock) 1097 __releases(svc_export_cache.hash_lock)
1419{ 1098{
1420 read_unlock(&svc_export_cache.hash_lock); 1099 read_unlock(&svc_export_cache.hash_lock);
1421 exp_readunlock();
1422} 1100}
1423 1101
1424static struct flags { 1102static struct flags {
@@ -1550,97 +1228,6 @@ const struct seq_operations nfs_exports_op = {
1550 .show = e_show, 1228 .show = e_show,
1551}; 1229};
1552 1230
1553#ifdef CONFIG_NFSD_DEPRECATED
1554/*
1555 * Add or modify a client.
1556 * Change requests may involve the list of host addresses. The list of
1557 * exports and possibly existing uid maps are left untouched.
1558 */
1559int
1560exp_addclient(struct nfsctl_client *ncp)
1561{
1562 struct auth_domain *dom;
1563 int i, err;
1564 struct in6_addr addr6;
1565
1566 /* First, consistency check. */
1567 err = -EINVAL;
1568 if (! exp_verify_string(ncp->cl_ident, NFSCLNT_IDMAX))
1569 goto out;
1570 if (ncp->cl_naddr > NFSCLNT_ADDRMAX)
1571 goto out;
1572
1573 /* Lock the hashtable */
1574 exp_writelock();
1575
1576 dom = unix_domain_find(ncp->cl_ident);
1577
1578 err = -ENOMEM;
1579 if (!dom)
1580 goto out_unlock;
1581
1582 /* Insert client into hashtable. */
1583 for (i = 0; i < ncp->cl_naddr; i++) {
1584 ipv6_addr_set_v4mapped(ncp->cl_addrlist[i].s_addr, &addr6);
1585 auth_unix_add_addr(&init_net, &addr6, dom);
1586 }
1587 auth_unix_forget_old(dom);
1588 auth_domain_put(dom);
1589
1590 err = 0;
1591
1592out_unlock:
1593 exp_writeunlock();
1594out:
1595 return err;
1596}
1597
1598/*
1599 * Delete a client given an identifier.
1600 */
1601int
1602exp_delclient(struct nfsctl_client *ncp)
1603{
1604 int err;
1605 struct auth_domain *dom;
1606
1607 err = -EINVAL;
1608 if (!exp_verify_string(ncp->cl_ident, NFSCLNT_IDMAX))
1609 goto out;
1610
1611 /* Lock the hashtable */
1612 exp_writelock();
1613
1614 dom = auth_domain_find(ncp->cl_ident);
1615 /* just make sure that no addresses work
1616 * and that it will expire soon
1617 */
1618 if (dom) {
1619 err = auth_unix_forget_old(dom);
1620 auth_domain_put(dom);
1621 }
1622
1623 exp_writeunlock();
1624out:
1625 return err;
1626}
1627
1628/*
1629 * Verify that string is non-empty and does not exceed max length.
1630 */
1631static int
1632exp_verify_string(char *cp, int max)
1633{
1634 int i;
1635
1636 for (i = 0; i < max; i++)
1637 if (!cp[i])
1638 return i;
1639 cp[i] = 0;
1640 printk(KERN_NOTICE "nfsd: couldn't validate string %s\n", cp);
1641 return 0;
1642}
1643#endif /* CONFIG_NFSD_DEPRECATED */
1644 1231
1645/* 1232/*
1646 * Initialize the exports module. 1233 * Initialize the exports module.
@@ -1667,10 +1254,8 @@ nfsd_export_init(void)
1667void 1254void
1668nfsd_export_flush(void) 1255nfsd_export_flush(void)
1669{ 1256{
1670 exp_writelock();
1671 cache_purge(&svc_expkey_cache); 1257 cache_purge(&svc_expkey_cache);
1672 cache_purge(&svc_export_cache); 1258 cache_purge(&svc_export_cache);
1673 exp_writeunlock();
1674} 1259}
1675 1260
1676/* 1261/*
@@ -1682,12 +1267,9 @@ nfsd_export_shutdown(void)
1682 1267
1683 dprintk("nfsd: shutting down export module.\n"); 1268 dprintk("nfsd: shutting down export module.\n");
1684 1269
1685 exp_writelock();
1686
1687 cache_unregister(&svc_expkey_cache); 1270 cache_unregister(&svc_expkey_cache);
1688 cache_unregister(&svc_export_cache); 1271 cache_unregister(&svc_export_cache);
1689 svcauth_unix_purge(); 1272 svcauth_unix_purge();
1690 1273
1691 exp_writeunlock();
1692 dprintk("nfsd: export shutdown complete.\n"); 1274 dprintk("nfsd: export shutdown complete.\n");
1693} 1275}
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c
index 7c831a2731fa..77e7a5cca888 100644
--- a/fs/nfsd/lockd.c
+++ b/fs/nfsd/lockd.c
@@ -35,10 +35,8 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
35 memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size); 35 memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size);
36 fh.fh_export = NULL; 36 fh.fh_export = NULL;
37 37
38 exp_readlock();
39 nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp); 38 nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp);
40 fh_put(&fh); 39 fh_put(&fh);
41 exp_readunlock();
42 /* We return nlm error codes as nlm doesn't know 40 /* We return nlm error codes as nlm doesn't know
43 * about nfsd, but nfsd does know about nlm.. 41 * about nfsd, but nfsd does know about nlm..
44 */ 42 */
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 2b1449dd2f49..c7716143cbd1 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -24,15 +24,6 @@
24 */ 24 */
25enum { 25enum {
26 NFSD_Root = 1, 26 NFSD_Root = 1,
27#ifdef CONFIG_NFSD_DEPRECATED
28 NFSD_Svc,
29 NFSD_Add,
30 NFSD_Del,
31 NFSD_Export,
32 NFSD_Unexport,
33 NFSD_Getfd,
34 NFSD_Getfs,
35#endif
36 NFSD_List, 27 NFSD_List,
37 NFSD_Export_features, 28 NFSD_Export_features,
38 NFSD_Fh, 29 NFSD_Fh,
@@ -59,15 +50,6 @@ enum {
59/* 50/*
60 * write() for these nodes. 51 * write() for these nodes.
61 */ 52 */
62#ifdef CONFIG_NFSD_DEPRECATED
63static ssize_t write_svc(struct file *file, char *buf, size_t size);
64static ssize_t write_add(struct file *file, char *buf, size_t size);
65static ssize_t write_del(struct file *file, char *buf, size_t size);
66static ssize_t write_export(struct file *file, char *buf, size_t size);
67static ssize_t write_unexport(struct file *file, char *buf, size_t size);
68static ssize_t write_getfd(struct file *file, char *buf, size_t size);
69static ssize_t write_getfs(struct file *file, char *buf, size_t size);
70#endif
71static ssize_t write_filehandle(struct file *file, char *buf, size_t size); 53static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
72static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size); 54static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size);
73static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size); 55static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size);
@@ -83,15 +65,6 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
83#endif 65#endif
84 66
85static ssize_t (*write_op[])(struct file *, char *, size_t) = { 67static ssize_t (*write_op[])(struct file *, char *, size_t) = {
86#ifdef CONFIG_NFSD_DEPRECATED
87 [NFSD_Svc] = write_svc,
88 [NFSD_Add] = write_add,
89 [NFSD_Del] = write_del,
90 [NFSD_Export] = write_export,
91 [NFSD_Unexport] = write_unexport,
92 [NFSD_Getfd] = write_getfd,
93 [NFSD_Getfs] = write_getfs,
94#endif
95 [NFSD_Fh] = write_filehandle, 68 [NFSD_Fh] = write_filehandle,
96 [NFSD_FO_UnlockIP] = write_unlock_ip, 69 [NFSD_FO_UnlockIP] = write_unlock_ip,
97 [NFSD_FO_UnlockFS] = write_unlock_fs, 70 [NFSD_FO_UnlockFS] = write_unlock_fs,
@@ -130,16 +103,6 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
130 103
131static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos) 104static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
132{ 105{
133#ifdef CONFIG_NFSD_DEPRECATED
134 static int warned;
135 if (file->f_dentry->d_name.name[0] == '.' && !warned) {
136 printk(KERN_INFO
137 "Warning: \"%s\" uses deprecated NFSD interface: %s."
138 " This will be removed in 2.6.40\n",
139 current->comm, file->f_dentry->d_name.name);
140 warned = 1;
141 }
142#endif
143 if (! file->private_data) { 106 if (! file->private_data) {
144 /* An attempt to read a transaction file without writing 107 /* An attempt to read a transaction file without writing
145 * causes a 0-byte write so that the file can return 108 * causes a 0-byte write so that the file can return
@@ -226,303 +189,6 @@ static const struct file_operations pool_stats_operations = {
226 * payload - write methods 189 * payload - write methods
227 */ 190 */
228 191
229#ifdef CONFIG_NFSD_DEPRECATED
230/**
231 * write_svc - Start kernel's NFSD server
232 *
233 * Deprecated. /proc/fs/nfsd/threads is preferred.
234 * Function remains to support old versions of nfs-utils.
235 *
236 * Input:
237 * buf: struct nfsctl_svc
238 * svc_port: port number of this
239 * server's listener
240 * svc_nthreads: number of threads to start
241 * size: size in bytes of passed in nfsctl_svc
242 * Output:
243 * On success: returns zero
244 * On error: return code is negative errno value
245 */
246static ssize_t write_svc(struct file *file, char *buf, size_t size)
247{
248 struct nfsctl_svc *data;
249 int err;
250 if (size < sizeof(*data))
251 return -EINVAL;
252 data = (struct nfsctl_svc*) buf;
253 err = nfsd_svc(data->svc_port, data->svc_nthreads);
254 if (err < 0)
255 return err;
256 return 0;
257}
258
259/**
260 * write_add - Add or modify client entry in auth unix cache
261 *
262 * Deprecated. /proc/net/rpc/auth.unix.ip is preferred.
263 * Function remains to support old versions of nfs-utils.
264 *
265 * Input:
266 * buf: struct nfsctl_client
267 * cl_ident: '\0'-terminated C string
268 * containing domain name
269 * of client
270 * cl_naddr: no. of items in cl_addrlist
271 * cl_addrlist: array of client addresses
272 * cl_fhkeytype: ignored
273 * cl_fhkeylen: ignored
274 * cl_fhkey: ignored
275 * size: size in bytes of passed in nfsctl_client
276 * Output:
277 * On success: returns zero
278 * On error: return code is negative errno value
279 *
280 * Note: Only AF_INET client addresses are passed in, since
281 * nfsctl_client.cl_addrlist contains only in_addr fields for addresses.
282 */
283static ssize_t write_add(struct file *file, char *buf, size_t size)
284{
285 struct nfsctl_client *data;
286 if (size < sizeof(*data))
287 return -EINVAL;
288 data = (struct nfsctl_client *)buf;
289 return exp_addclient(data);
290}
291
292/**
293 * write_del - Remove client from auth unix cache
294 *
295 * Deprecated. /proc/net/rpc/auth.unix.ip is preferred.
296 * Function remains to support old versions of nfs-utils.
297 *
298 * Input:
299 * buf: struct nfsctl_client
300 * cl_ident: '\0'-terminated C string
301 * containing domain name
302 * of client
303 * cl_naddr: ignored
304 * cl_addrlist: ignored
305 * cl_fhkeytype: ignored
306 * cl_fhkeylen: ignored
307 * cl_fhkey: ignored
308 * size: size in bytes of passed in nfsctl_client
309 * Output:
310 * On success: returns zero
311 * On error: return code is negative errno value
312 *
313 * Note: Only AF_INET client addresses are passed in, since
314 * nfsctl_client.cl_addrlist contains only in_addr fields for addresses.
315 */
316static ssize_t write_del(struct file *file, char *buf, size_t size)
317{
318 struct nfsctl_client *data;
319 if (size < sizeof(*data))
320 return -EINVAL;
321 data = (struct nfsctl_client *)buf;
322 return exp_delclient(data);
323}
324
325/**
326 * write_export - Export part or all of a local file system
327 *
328 * Deprecated. /proc/net/rpc/{nfsd.export,nfsd.fh} are preferred.
329 * Function remains to support old versions of nfs-utils.
330 *
331 * Input:
332 * buf: struct nfsctl_export
333 * ex_client: '\0'-terminated C string
334 * containing domain name
335 * of client allowed to access
336 * this export
337 * ex_path: '\0'-terminated C string
338 * containing pathname of
339 * directory in local file system
340 * ex_dev: fsid to use for this export
341 * ex_ino: ignored
342 * ex_flags: export flags for this export
343 * ex_anon_uid: UID to use for anonymous
344 * requests
345 * ex_anon_gid: GID to use for anonymous
346 * requests
347 * size: size in bytes of passed in nfsctl_export
348 * Output:
349 * On success: returns zero
350 * On error: return code is negative errno value
351 */
352static ssize_t write_export(struct file *file, char *buf, size_t size)
353{
354 struct nfsctl_export *data;
355 if (size < sizeof(*data))
356 return -EINVAL;
357 data = (struct nfsctl_export*)buf;
358 return exp_export(data);
359}
360
361/**
362 * write_unexport - Unexport a previously exported file system
363 *
364 * Deprecated. /proc/net/rpc/{nfsd.export,nfsd.fh} are preferred.
365 * Function remains to support old versions of nfs-utils.
366 *
367 * Input:
368 * buf: struct nfsctl_export
369 * ex_client: '\0'-terminated C string
370 * containing domain name
371 * of client no longer allowed
372 * to access this export
373 * ex_path: '\0'-terminated C string
374 * containing pathname of
375 * directory in local file system
376 * ex_dev: ignored
377 * ex_ino: ignored
378 * ex_flags: ignored
379 * ex_anon_uid: ignored
380 * ex_anon_gid: ignored
381 * size: size in bytes of passed in nfsctl_export
382 * Output:
383 * On success: returns zero
384 * On error: return code is negative errno value
385 */
386static ssize_t write_unexport(struct file *file, char *buf, size_t size)
387{
388 struct nfsctl_export *data;
389
390 if (size < sizeof(*data))
391 return -EINVAL;
392 data = (struct nfsctl_export*)buf;
393 return exp_unexport(data);
394}
395
396/**
397 * write_getfs - Get a variable-length NFS file handle by path
398 *
399 * Deprecated. /proc/fs/nfsd/filehandle is preferred.
400 * Function remains to support old versions of nfs-utils.
401 *
402 * Input:
403 * buf: struct nfsctl_fsparm
404 * gd_addr: socket address of client
405 * gd_path: '\0'-terminated C string
406 * containing pathname of
407 * directory in local file system
408 * gd_maxlen: maximum size of returned file
409 * handle
410 * size: size in bytes of passed in nfsctl_fsparm
411 * Output:
412 * On success: passed-in buffer filled with a knfsd_fh structure
413 * (a variable-length raw NFS file handle);
414 * return code is the size in bytes of the file handle
415 * On error: return code is negative errno value
416 *
417 * Note: Only AF_INET client addresses are passed in, since gd_addr
418 * is the same size as a struct sockaddr_in.
419 */
420static ssize_t write_getfs(struct file *file, char *buf, size_t size)
421{
422 struct nfsctl_fsparm *data;
423 struct sockaddr_in *sin;
424 struct auth_domain *clp;
425 int err = 0;
426 struct knfsd_fh *res;
427 struct in6_addr in6;
428
429 if (size < sizeof(*data))
430 return -EINVAL;
431 data = (struct nfsctl_fsparm*)buf;
432 err = -EPROTONOSUPPORT;
433 if (data->gd_addr.sa_family != AF_INET)
434 goto out;
435 sin = (struct sockaddr_in *)&data->gd_addr;
436 if (data->gd_maxlen > NFS3_FHSIZE)
437 data->gd_maxlen = NFS3_FHSIZE;
438
439 res = (struct knfsd_fh*)buf;
440
441 exp_readlock();
442
443 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6);
444
445 clp = auth_unix_lookup(&init_net, &in6);
446 if (!clp)
447 err = -EPERM;
448 else {
449 err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
450 auth_domain_put(clp);
451 }
452 exp_readunlock();
453 if (err == 0)
454 err = res->fh_size + offsetof(struct knfsd_fh, fh_base);
455 out:
456 return err;
457}
458
459/**
460 * write_getfd - Get a fixed-length NFS file handle by path (used by mountd)
461 *
462 * Deprecated. /proc/fs/nfsd/filehandle is preferred.
463 * Function remains to support old versions of nfs-utils.
464 *
465 * Input:
466 * buf: struct nfsctl_fdparm
467 * gd_addr: socket address of client
468 * gd_path: '\0'-terminated C string
469 * containing pathname of
470 * directory in local file system
471 * gd_version: fdparm structure version
472 * size: size in bytes of passed in nfsctl_fdparm
473 * Output:
474 * On success: passed-in buffer filled with nfsctl_res
475 * (a fixed-length raw NFS file handle);
476 * return code is the size in bytes of the file handle
477 * On error: return code is negative errno value
478 *
479 * Note: Only AF_INET client addresses are passed in, since gd_addr
480 * is the same size as a struct sockaddr_in.
481 */
482static ssize_t write_getfd(struct file *file, char *buf, size_t size)
483{
484 struct nfsctl_fdparm *data;
485 struct sockaddr_in *sin;
486 struct auth_domain *clp;
487 int err = 0;
488 struct knfsd_fh fh;
489 char *res;
490 struct in6_addr in6;
491
492 if (size < sizeof(*data))
493 return -EINVAL;
494 data = (struct nfsctl_fdparm*)buf;
495 err = -EPROTONOSUPPORT;
496 if (data->gd_addr.sa_family != AF_INET)
497 goto out;
498 err = -EINVAL;
499 if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS)
500 goto out;
501
502 res = buf;
503 sin = (struct sockaddr_in *)&data->gd_addr;
504 exp_readlock();
505
506 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6);
507
508 clp = auth_unix_lookup(&init_net, &in6);
509 if (!clp)
510 err = -EPERM;
511 else {
512 err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
513 auth_domain_put(clp);
514 }
515 exp_readunlock();
516
517 if (err == 0) {
518 memset(res,0, NFS_FHSIZE);
519 memcpy(res, &fh.fh_base, fh.fh_size);
520 err = NFS_FHSIZE;
521 }
522 out:
523 return err;
524}
525#endif /* CONFIG_NFSD_DEPRECATED */
526 192
527/** 193/**
528 * write_unlock_ip - Release all locks used by a client 194 * write_unlock_ip - Release all locks used by a client
@@ -1397,15 +1063,6 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
1397static int nfsd_fill_super(struct super_block * sb, void * data, int silent) 1063static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1398{ 1064{
1399 static struct tree_descr nfsd_files[] = { 1065 static struct tree_descr nfsd_files[] = {
1400#ifdef CONFIG_NFSD_DEPRECATED
1401 [NFSD_Svc] = {".svc", &transaction_ops, S_IWUSR},
1402 [NFSD_Add] = {".add", &transaction_ops, S_IWUSR},
1403 [NFSD_Del] = {".del", &transaction_ops, S_IWUSR},
1404 [NFSD_Export] = {".export", &transaction_ops, S_IWUSR},
1405 [NFSD_Unexport] = {".unexport", &transaction_ops, S_IWUSR},
1406 [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR},
1407 [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR},
1408#endif
1409 [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, 1066 [NFSD_List] = {"exports", &exports_operations, S_IRUGO},
1410 [NFSD_Export_features] = {"export_features", 1067 [NFSD_Export_features] = {"export_features",
1411 &export_features_operations, S_IRUGO}, 1068 &export_features_operations, S_IRUGO},
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 18743c4d8bca..bb8397f9da25 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -528,16 +528,9 @@ nfsd(void *vrqstp)
528 continue; 528 continue;
529 } 529 }
530 530
531
532 /* Lock the export hash tables for reading. */
533 exp_readlock();
534
535 validate_process_creds(); 531 validate_process_creds();
536 svc_process(rqstp); 532 svc_process(rqstp);
537 validate_process_creds(); 533 validate_process_creds();
538
539 /* Unlock export hash tables */
540 exp_readunlock();
541 } 534 }
542 535
543 /* Clear signals before calling svc_exit_thread() */ 536 /* Clear signals before calling svc_exit_thread() */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 846bb1792572..8779405e15a8 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -438,16 +438,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
438 struct compat_timespec __user *tsp, 438 struct compat_timespec __user *tsp,
439 const compat_sigset_t __user *sigmask, 439 const compat_sigset_t __user *sigmask,
440 compat_size_t sigsetsize); 440 compat_size_t sigsetsize);
441#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && \
442 !defined(CONFIG_NFSD_DEPRECATED)
443union compat_nfsctl_res;
444struct compat_nfsctl_arg;
445asmlinkage long compat_sys_nfsservctl(int cmd,
446 struct compat_nfsctl_arg __user *arg,
447 union compat_nfsctl_res __user *res);
448#else
449asmlinkage long compat_sys_nfsservctl(int cmd, void *notused, void *notused2); 441asmlinkage long compat_sys_nfsservctl(int cmd, void *notused, void *notused2);
450#endif
451asmlinkage long compat_sys_signalfd4(int ufd, 442asmlinkage long compat_sys_signalfd4(int ufd,
452 const compat_sigset_t __user *sigmask, 443 const compat_sigset_t __user *sigmask,
453 compat_size_t sigsetsize, int flags); 444 compat_size_t sigsetsize, int flags);
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 84058ec69390..8a31a20efe7e 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -133,8 +133,6 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
133int nfsd_export_init(void); 133int nfsd_export_init(void);
134void nfsd_export_shutdown(void); 134void nfsd_export_shutdown(void);
135void nfsd_export_flush(void); 135void nfsd_export_flush(void);
136void exp_readlock(void);
137void exp_readunlock(void);
138struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, 136struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
139 struct path *); 137 struct path *);
140struct svc_export * rqst_exp_parent(struct svc_rqst *, 138struct svc_export * rqst_exp_parent(struct svc_rqst *,
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 8d2eef1a8582..d1c79a906397 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -256,13 +256,4 @@ static inline time_t get_expiry(char **bpp)
256 return rv - boot.tv_sec; 256 return rv - boot.tv_sec;
257} 257}
258 258
259#ifdef CONFIG_NFSD_DEPRECATED
260static inline void sunrpc_invalidate(struct cache_head *h,
261 struct cache_detail *detail)
262{
263 h->expiry_time = seconds_since_boot() - 1;
264 detail->nextcheck = seconds_since_boot();
265}
266#endif /* CONFIG_NFSD_DEPRECATED */
267
268#endif /* _LINUX_SUNRPC_CACHE_H_ */ 259#endif /* _LINUX_SUNRPC_CACHE_H_ */
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index c8e10216c113..31b9dea1bedd 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -30,9 +30,6 @@
30 30
31struct unix_domain { 31struct unix_domain {
32 struct auth_domain h; 32 struct auth_domain h;
33#ifdef CONFIG_NFSD_DEPRECATED
34 int addr_changes;
35#endif /* CONFIG_NFSD_DEPRECATED */
36 /* other stuff later */ 33 /* other stuff later */
37}; 34};
38 35
@@ -74,9 +71,6 @@ struct auth_domain *unix_domain_find(char *name)
74 return NULL; 71 return NULL;
75 } 72 }
76 new->h.flavour = &svcauth_unix; 73 new->h.flavour = &svcauth_unix;
77#ifdef CONFIG_NFSD_DEPRECATED
78 new->addr_changes = 0;
79#endif /* CONFIG_NFSD_DEPRECATED */
80 rv = auth_domain_lookup(name, &new->h); 74 rv = auth_domain_lookup(name, &new->h);
81 } 75 }
82} 76}
@@ -95,9 +89,6 @@ struct ip_map {
95 char m_class[8]; /* e.g. "nfsd" */ 89 char m_class[8]; /* e.g. "nfsd" */
96 struct in6_addr m_addr; 90 struct in6_addr m_addr;
97 struct unix_domain *m_client; 91 struct unix_domain *m_client;
98#ifdef CONFIG_NFSD_DEPRECATED
99 int m_add_change;
100#endif /* CONFIG_NFSD_DEPRECATED */
101}; 92};
102 93
103static void ip_map_put(struct kref *kref) 94static void ip_map_put(struct kref *kref)
@@ -151,9 +142,6 @@ static void update(struct cache_head *cnew, struct cache_head *citem)
151 142
152 kref_get(&item->m_client->h.ref); 143 kref_get(&item->m_client->h.ref);
153 new->m_client = item->m_client; 144 new->m_client = item->m_client;
154#ifdef CONFIG_NFSD_DEPRECATED
155 new->m_add_change = item->m_add_change;
156#endif /* CONFIG_NFSD_DEPRECATED */
157} 145}
158static struct cache_head *ip_map_alloc(void) 146static struct cache_head *ip_map_alloc(void)
159{ 147{
@@ -338,16 +326,6 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
338 ip.h.flags = 0; 326 ip.h.flags = 0;
339 if (!udom) 327 if (!udom)
340 set_bit(CACHE_NEGATIVE, &ip.h.flags); 328 set_bit(CACHE_NEGATIVE, &ip.h.flags);
341#ifdef CONFIG_NFSD_DEPRECATED
342 else {
343 ip.m_add_change = udom->addr_changes;
344 /* if this is from the legacy set_client system call,
345 * we need m_add_change to be one higher
346 */
347 if (expiry == NEVER)
348 ip.m_add_change++;
349 }
350#endif /* CONFIG_NFSD_DEPRECATED */
351 ip.h.expiry_time = expiry; 329 ip.h.expiry_time = expiry;
352 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, 330 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
353 hash_str(ipm->m_class, IP_HASHBITS) ^ 331 hash_str(ipm->m_class, IP_HASHBITS) ^
@@ -367,62 +345,6 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm,
367 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); 345 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);
368} 346}
369 347
370#ifdef CONFIG_NFSD_DEPRECATED
371int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom)
372{
373 struct unix_domain *udom;
374 struct ip_map *ipmp;
375
376 if (dom->flavour != &svcauth_unix)
377 return -EINVAL;
378 udom = container_of(dom, struct unix_domain, h);
379 ipmp = ip_map_lookup(net, "nfsd", addr);
380
381 if (ipmp)
382 return ip_map_update(net, ipmp, udom, NEVER);
383 else
384 return -ENOMEM;
385}
386EXPORT_SYMBOL_GPL(auth_unix_add_addr);
387
388int auth_unix_forget_old(struct auth_domain *dom)
389{
390 struct unix_domain *udom;
391
392 if (dom->flavour != &svcauth_unix)
393 return -EINVAL;
394 udom = container_of(dom, struct unix_domain, h);
395 udom->addr_changes++;
396 return 0;
397}
398EXPORT_SYMBOL_GPL(auth_unix_forget_old);
399
400struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
401{
402 struct ip_map *ipm;
403 struct auth_domain *rv;
404 struct sunrpc_net *sn;
405
406 sn = net_generic(net, sunrpc_net_id);
407 ipm = ip_map_lookup(net, "nfsd", addr);
408
409 if (!ipm)
410 return NULL;
411 if (cache_check(sn->ip_map_cache, &ipm->h, NULL))
412 return NULL;
413
414 if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) {
415 sunrpc_invalidate(&ipm->h, sn->ip_map_cache);
416 rv = NULL;
417 } else {
418 rv = &ipm->m_client->h;
419 kref_get(&rv->ref);
420 }
421 cache_put(&ipm->h, sn->ip_map_cache);
422 return rv;
423}
424EXPORT_SYMBOL_GPL(auth_unix_lookup);
425#endif /* CONFIG_NFSD_DEPRECATED */
426 348
427void svcauth_unix_purge(void) 349void svcauth_unix_purge(void)
428{ 350{