Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-3.1' of git://linux-nfs.org/~bfields/linux

* 'for-3.1' of git://linux-nfs.org/~bfields/linux:
nfsd: don't break lease on CLAIM_DELEGATE_CUR
locks: rename lock-manager ops
nfsd4: update nfsv4.1 implementation notes
nfsd: turn on reply cache for NFSv4
nfsd4: call nfsd4_release_compoundargs from pc_release
nfsd41: Deny new lock before RECLAIM_COMPLETE done
fs: locks: remove init_once
nfsd41: check the size of request
nfsd41: error out when client sets maxreq_sz or maxresp_sz too small
nfsd4: fix file leak on open_downgrade
nfsd4: remember to put RW access on stateid destruction
NFSD: Added TEST_STATEID operation
NFSD: added FREE_STATEID operation
svcrpc: fix list-corrupting race on nfsd shutdown
rpc: allow autoloading of gss mechanisms
svcauth_unix.c: quiet sparse noise
svcsock.c: include sunrpc.h to quiet sparse noise
nfsd: Remove deprecated nfsctl system call and related code.
NFSD: allow OP_DESTROY_CLIENTID to be only op in COMPOUND

Fix up trivial conflicts in Documentation/feature-removal-schedule.txt

+559 -1426
-10
Documentation/feature-removal-schedule.txt
··· 491 491 492 492 ---------------------------- 493 493 494 - What: access to nfsd auth cache through sys_nfsservctl or '.' files 495 - in the 'nfsd' filesystem. 496 - When: 3.0 497 - Why: 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. 500 - Who: NeilBrown <neilb@suse.de> 501 - 502 - ---------------------------- 503 - 504 494 What: Legacy, non-standard chassis intrusion detection interface. 505 495 When: June 2011 506 496 Why: The adm9240, w83792d and w83793 hardware monitoring drivers have
+12 -12
Documentation/filesystems/Locking
··· 338 338 339 339 ----------------------- lock_manager_operations --------------------------- 340 340 prototypes: 341 - int (*fl_compare_owner)(struct file_lock *, struct file_lock *); 342 - void (*fl_notify)(struct file_lock *); /* unblock callback */ 343 - int (*fl_grant)(struct file_lock *, struct file_lock *, int); 344 - void (*fl_release_private)(struct file_lock *); 345 - void (*fl_break)(struct file_lock *); /* break_lease callback */ 346 - int (*fl_change)(struct file_lock **, int); 341 + int (*lm_compare_owner)(struct file_lock *, struct file_lock *); 342 + void (*lm_notify)(struct file_lock *); /* unblock callback */ 343 + int (*lm_grant)(struct file_lock *, struct file_lock *, int); 344 + void (*lm_release_private)(struct file_lock *); 345 + void (*lm_break)(struct file_lock *); /* break_lease callback */ 346 + int (*lm_change)(struct file_lock **, int); 347 347 348 348 locking rules: 349 349 file_lock_lock may block 350 - fl_compare_owner: yes no 351 - fl_notify: yes no 352 - fl_grant: no no 353 - fl_release_private: maybe no 354 - fl_break: yes no 355 - fl_change yes no 350 + lm_compare_owner: yes no 351 + lm_notify: yes no 352 + lm_grant: no no 353 + lm_release_private: maybe no 354 + lm_break: yes no 355 + lm_change yes no 356 356 357 357 --------------------------- buffer_head ----------------------------------- 358 358 prototypes:
+10 -23
Documentation/filesystems/nfs/nfs41-server.txt
··· 39 39 from a linux client are possible, but we aren't really 40 40 conformant with the spec (for example, we don't use kerberos 41 41 on the backchannel correctly). 42 - - no trunking support: no clients currently take advantage of 43 - trunking, but this is a mandatory feature, and its use is 44 - recommended to clients in a number of places. (E.g. to ensure 45 - timely renewal in case an existing connection's retry timeouts 46 - have gotten too long; see section 8.3 of the RFC.) 47 - Therefore, lack of this feature may cause future clients to 48 - fail. 49 42 - Incomplete backchannel support: incomplete backchannel gss 50 43 support and no support for BACKCHANNEL_CTL mean that 51 44 callbacks (hence delegations and layouts) may not be 52 45 available and clients confused by the incomplete 53 46 implementation may fail. 54 - - Server reboot recovery is unsupported; if the server reboots, 55 - clients may fail. 56 47 - We do not support SSV, which provides security for shared 57 48 client-server state (thus preventing unauthorized tampering 58 49 with locks and opens, for example). It is mandatory for 59 50 servers to support this, though no clients use it yet. 60 51 - Mandatory operations which we do not support, such as 61 - DESTROY_CLIENTID, FREE_STATEID, SECINFO_NO_NAME, and 62 - TEST_STATEID, are not currently used by clients, but will be 52 + DESTROY_CLIENTID, are not currently used by clients, but will be 63 53 (and the spec recommends their uses in common cases), and 64 54 clients should not be expected to know how to recover from the 65 55 case where they are not supported. This will eventually cause ··· 59 69 implementation: 60 70 61 71 - Incomplete delegation enforcement: if a file is renamed or 62 - unlinked, a client holding a delegation may continue to 63 - indefinitely allow opens of the file under the old name. 72 + unlinked by a local process, a client holding a delegation may 73 + continue to indefinitely allow opens of the file under the old 74 + name. 64 75 65 76 The table below, taken from the NFSv4.1 document, lists 66 77 the operations that are mandatory to implement (REQ), optional ··· 90 99 +----------------------+------------+--------------+----------------+ 91 100 | ACCESS | REQ | | Section 18.1 | 92 101 NS | BACKCHANNEL_CTL | REQ | | Section 18.33 | 93 - NS | BIND_CONN_TO_SESSION | REQ | | Section 18.34 | 102 + I | BIND_CONN_TO_SESSION | REQ | | Section 18.34 | 94 103 | CLOSE | REQ | | Section 18.2 | 95 104 | COMMIT | REQ | | Section 18.3 | 96 105 | CREATE | REQ | | Section 18.4 | ··· 102 111 NS | DESTROY_CLIENTID | REQ | | Section 18.50 | 103 112 I | DESTROY_SESSION | REQ | | Section 18.37 | 104 113 I | EXCHANGE_ID | REQ | | Section 18.35 | 105 - NS | FREE_STATEID | REQ | | Section 18.38 | 114 + I | FREE_STATEID | REQ | | Section 18.38 | 106 115 | GETATTR | REQ | | Section 18.7 | 107 116 P | GETDEVICEINFO | OPT | pNFS (REQ) | Section 18.40 | 108 117 P | GETDEVICELIST | OPT | pNFS (OPT) | Section 18.41 | ··· 136 145 | RESTOREFH | REQ | | Section 18.27 | 137 146 | SAVEFH | REQ | | Section 18.28 | 138 147 | SECINFO | REQ | | Section 18.29 | 139 - NS | SECINFO_NO_NAME | REC | pNFS files | Section 18.45, | 148 + I | SECINFO_NO_NAME | REC | pNFS files | Section 18.45, | 140 149 | | | layout (REQ) | Section 13.12 | 141 150 I | SEQUENCE | REQ | | Section 18.46 | 142 151 | SETATTR | REQ | | Section 18.30 | 143 152 | SETCLIENTID | MNI | | N/A | 144 153 | SETCLIENTID_CONFIRM | MNI | | N/A | 145 154 NS | SET_SSV | REQ | | Section 18.47 | 146 - NS | TEST_STATEID | REQ | | Section 18.48 | 155 + I | TEST_STATEID | REQ | | Section 18.48 | 147 156 | VERIFY | REQ | | Section 18.31 | 148 157 NS*| WANT_DELEGATION | OPT | FDELG (OPT) | Section 18.49 | 149 158 | WRITE | REQ | | Section 18.32 | ··· 197 206 SEQUENCE: 198 207 * no support for dynamic slot table renegotiation (optional) 199 208 200 - nfsv4.1 COMPOUND rules: 201 - The following cases aren't supported yet: 202 - * Enforcing of NFS4ERR_NOT_ONLY_OP for: BIND_CONN_TO_SESSION, CREATE_SESSION, 203 - DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID. 204 - * DESTROY_SESSION MUST be the final operation in the COMPOUND request. 205 - 206 209 Nonstandard compound limitations: 207 210 * No support for a sessions fore channel RPC compound that requires both a 208 211 ca_maxrequestsize request and a ca_maxresponsesize reply, so we may ··· 204 219 negotiation. 205 220 * No more than one IO operation (read, write, readdir) allowed per 206 221 compound. 222 + 223 + See also http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues.
-1
arch/tile/configs/tilegx_defconfig
··· 1479 1479 CONFIG_NFS_USE_KERNEL_DNS=y 1480 1480 # CONFIG_NFS_USE_NEW_IDMAPPER is not set 1481 1481 CONFIG_NFSD=m 1482 - CONFIG_NFSD_DEPRECATED=y 1483 1482 CONFIG_NFSD_V2_ACL=y 1484 1483 CONFIG_NFSD_V3=y 1485 1484 CONFIG_NFSD_V3_ACL=y
-1
fs/Makefile
··· 29 29 obj-$(CONFIG_AIO) += aio.o 30 30 obj-$(CONFIG_FILE_LOCKING) += locks.o 31 31 obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o 32 - obj-$(CONFIG_NFSD_DEPRECATED) += nfsctl.o 33 32 obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o 34 33 obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o 35 34 obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
-246
fs/compat.c
··· 1675 1675 } 1676 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... */ 1680 - struct compat_nfsctl_svc { 1681 - u16 svc32_port; 1682 - s32 svc32_nthreads; 1683 - }; 1684 - 1685 - struct 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 - 1694 - struct 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 - 1704 - struct compat_nfsctl_fdparm { 1705 - struct sockaddr gd32_addr; 1706 - s8 gd32_path[NFS_MAXPATHLEN+1]; 1707 - compat_int_t gd32_version; 1708 - }; 1709 - 1710 - struct compat_nfsctl_fsparm { 1711 - struct sockaddr gd32_addr; 1712 - s8 gd32_path[NFS_MAXPATHLEN+1]; 1713 - compat_int_t gd32_maxlen; 1714 - }; 1715 - 1716 - struct 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 - 1732 - union compat_nfsctl_res { 1733 - __u8 cr32_getfh[NFS_FHSIZE]; 1734 - struct knfsd_fh cr32_getfs; 1735 - }; 1736 - 1737 - static 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 - 1749 - static 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 - 1775 - static 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 - 1804 - static 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 - 1823 - static 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 - */ 1844 - static 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 - 1854 - asmlinkage 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 - 1917 - done: 1918 - kfree(karg); 1919 - kfree(kres); 1920 - return err; 1921 - } 1922 - #else /* !NFSD */ 1923 1678 long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2) 1924 1679 { 1925 1680 return sys_ni_syscall(); 1926 1681 } 1927 - #endif 1928 1682 1929 1683 #ifdef CONFIG_EPOLL 1930 1684
+5 -5
fs/dlm/plock.c
··· 92 92 op->info.number = number; 93 93 op->info.start = 0; 94 94 op->info.end = OFFSET_MAX; 95 - if (fl->fl_lmops && fl->fl_lmops->fl_grant) 95 + if (fl->fl_lmops && fl->fl_lmops->lm_grant) 96 96 op->info.owner = (__u64) fl->fl_pid; 97 97 else 98 98 op->info.owner = (__u64)(long) fl->fl_owner; ··· 128 128 op->info.number = number; 129 129 op->info.start = fl->fl_start; 130 130 op->info.end = fl->fl_end; 131 - if (fl->fl_lmops && fl->fl_lmops->fl_grant) { 131 + if (fl->fl_lmops && fl->fl_lmops->lm_grant) { 132 132 /* fl_owner is lockd which doesn't distinguish 133 133 processes on the nfs client */ 134 134 op->info.owner = (__u64) fl->fl_pid; 135 - xop->callback = fl->fl_lmops->fl_grant; 135 + xop->callback = fl->fl_lmops->lm_grant; 136 136 locks_init_lock(&xop->flc); 137 137 locks_copy_lock(&xop->flc, fl); 138 138 xop->fl = fl; ··· 268 268 op->info.number = number; 269 269 op->info.start = fl->fl_start; 270 270 op->info.end = fl->fl_end; 271 - if (fl->fl_lmops && fl->fl_lmops->fl_grant) 271 + if (fl->fl_lmops && fl->fl_lmops->lm_grant) 272 272 op->info.owner = (__u64) fl->fl_pid; 273 273 else 274 274 op->info.owner = (__u64)(long) fl->fl_owner; ··· 327 327 op->info.number = number; 328 328 op->info.start = fl->fl_start; 329 329 op->info.end = fl->fl_end; 330 - if (fl->fl_lmops && fl->fl_lmops->fl_grant) 330 + if (fl->fl_lmops && fl->fl_lmops->lm_grant) 331 331 op->info.owner = (__u64) fl->fl_pid; 332 332 else 333 333 op->info.owner = (__u64)(long) fl->fl_owner;
+1 -1
fs/fuse/file.c
··· 1507 1507 pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0; 1508 1508 int err; 1509 1509 1510 - if (fl->fl_lmops && fl->fl_lmops->fl_grant) { 1510 + if (fl->fl_lmops && fl->fl_lmops->lm_grant) { 1511 1511 /* NLM needs asynchronous locks, which we don't support yet */ 1512 1512 return -ENOLCK; 1513 1513 }
+4 -4
fs/lockd/svclock.c
··· 632 632 633 633 /* 634 634 * This is a callback from the filesystem for VFS file lock requests. 635 - * It will be used if fl_grant is defined and the filesystem can not 635 + * It will be used if lm_grant is defined and the filesystem can not 636 636 * respond to the request immediately. 637 637 * For GETLK request it will copy the reply to the nlm_block. 638 638 * For SETLK or SETLKW request it will get the local posix lock. ··· 719 719 } 720 720 721 721 const struct lock_manager_operations nlmsvc_lock_operations = { 722 - .fl_compare_owner = nlmsvc_same_owner, 723 - .fl_notify = nlmsvc_notify_blocked, 724 - .fl_grant = nlmsvc_grant_deferred, 722 + .lm_compare_owner = nlmsvc_same_owner, 723 + .lm_notify = nlmsvc_notify_blocked, 724 + .lm_grant = nlmsvc_grant_deferred, 725 725 }; 726 726 727 727 /*
+27 -48
fs/locks.c
··· 160 160 161 161 static struct kmem_cache *filelock_cache __read_mostly; 162 162 163 - static void locks_init_lock_always(struct file_lock *fl) 163 + static void locks_init_lock_heads(struct file_lock *fl) 164 164 { 165 - fl->fl_next = NULL; 166 - fl->fl_fasync = NULL; 167 - fl->fl_owner = NULL; 168 - fl->fl_pid = 0; 169 - fl->fl_nspid = NULL; 170 - fl->fl_file = NULL; 171 - fl->fl_flags = 0; 172 - fl->fl_type = 0; 173 - fl->fl_start = fl->fl_end = 0; 165 + INIT_LIST_HEAD(&fl->fl_link); 166 + INIT_LIST_HEAD(&fl->fl_block); 167 + init_waitqueue_head(&fl->fl_wait); 174 168 } 175 169 176 170 /* Allocate an empty lock structure. */ 177 171 struct file_lock *locks_alloc_lock(void) 178 172 { 179 - struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL); 173 + struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL); 180 174 181 175 if (fl) 182 - locks_init_lock_always(fl); 176 + locks_init_lock_heads(fl); 183 177 184 178 return fl; 185 179 } ··· 187 193 fl->fl_ops = NULL; 188 194 } 189 195 if (fl->fl_lmops) { 190 - if (fl->fl_lmops->fl_release_private) 191 - fl->fl_lmops->fl_release_private(fl); 196 + if (fl->fl_lmops->lm_release_private) 197 + fl->fl_lmops->lm_release_private(fl); 192 198 fl->fl_lmops = NULL; 193 199 } 194 200 ··· 209 215 210 216 void locks_init_lock(struct file_lock *fl) 211 217 { 212 - INIT_LIST_HEAD(&fl->fl_link); 213 - INIT_LIST_HEAD(&fl->fl_block); 214 - init_waitqueue_head(&fl->fl_wait); 215 - fl->fl_ops = NULL; 216 - fl->fl_lmops = NULL; 217 - locks_init_lock_always(fl); 218 + memset(fl, 0, sizeof(struct file_lock)); 219 + locks_init_lock_heads(fl); 218 220 } 219 221 220 222 EXPORT_SYMBOL(locks_init_lock); 221 - 222 - /* 223 - * Initialises the fields of the file lock which are invariant for 224 - * free file_locks. 225 - */ 226 - static void init_once(void *foo) 227 - { 228 - struct file_lock *lock = (struct file_lock *) foo; 229 - 230 - locks_init_lock(lock); 231 - } 232 223 233 224 static void locks_copy_private(struct file_lock *new, struct file_lock *fl) 234 225 { ··· 423 444 } 424 445 425 446 static const struct lock_manager_operations lease_manager_ops = { 426 - .fl_break = lease_break_callback, 427 - .fl_release_private = lease_release_private_callback, 428 - .fl_change = lease_modify, 447 + .lm_break = lease_break_callback, 448 + .lm_release_private = lease_release_private_callback, 449 + .lm_change = lease_modify, 429 450 }; 430 451 431 452 /* ··· 478 499 */ 479 500 static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2) 480 501 { 481 - if (fl1->fl_lmops && fl1->fl_lmops->fl_compare_owner) 502 + if (fl1->fl_lmops && fl1->fl_lmops->lm_compare_owner) 482 503 return fl2->fl_lmops == fl1->fl_lmops && 483 - fl1->fl_lmops->fl_compare_owner(fl1, fl2); 504 + fl1->fl_lmops->lm_compare_owner(fl1, fl2); 484 505 return fl1->fl_owner == fl2->fl_owner; 485 506 } 486 507 ··· 530 551 waiter = list_first_entry(&blocker->fl_block, 531 552 struct file_lock, fl_block); 532 553 __locks_delete_block(waiter); 533 - if (waiter->fl_lmops && waiter->fl_lmops->fl_notify) 534 - waiter->fl_lmops->fl_notify(waiter); 554 + if (waiter->fl_lmops && waiter->fl_lmops->lm_notify) 555 + waiter->fl_lmops->lm_notify(waiter); 535 556 else 536 557 wake_up(&waiter->fl_wait); 537 558 } ··· 1218 1239 fl->fl_type = future; 1219 1240 fl->fl_break_time = break_time; 1220 1241 /* lease must have lmops break callback */ 1221 - fl->fl_lmops->fl_break(fl); 1242 + fl->fl_lmops->lm_break(fl); 1222 1243 } 1223 1244 } 1224 1245 ··· 1328 1349 * @arg: type of lease to obtain 1329 1350 * @flp: input - file_lock to use, output - file_lock inserted 1330 1351 * 1331 - * The (input) flp->fl_lmops->fl_break function is required 1352 + * The (input) flp->fl_lmops->lm_break function is required 1332 1353 * by break_lease(). 1333 1354 * 1334 1355 * Called with file_lock_lock held. ··· 1354 1375 1355 1376 time_out_leases(inode); 1356 1377 1357 - BUG_ON(!(*flp)->fl_lmops->fl_break); 1378 + BUG_ON(!(*flp)->fl_lmops->lm_break); 1358 1379 1359 1380 if (arg != F_UNLCK) { 1360 1381 error = -EAGAIN; ··· 1396 1417 goto out; 1397 1418 1398 1419 if (my_before != NULL) { 1399 - error = lease->fl_lmops->fl_change(my_before, arg); 1420 + error = lease->fl_lmops->lm_change(my_before, arg); 1400 1421 if (!error) 1401 1422 *flp = *my_before; 1402 1423 goto out; ··· 1432 1453 * @lease: file_lock to use 1433 1454 * 1434 1455 * Call this to establish a lease on the file. 1435 - * The (*lease)->fl_lmops->fl_break operation must be set; if not, 1456 + * The (*lease)->fl_lmops->lm_break operation must be set; if not, 1436 1457 * break_lease will oops! 1437 1458 * 1438 1459 * This will call the filesystem's setlease file method, if ··· 1730 1751 * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX 1731 1752 * locks, the ->lock() interface may return asynchronously, before the lock has 1732 1753 * been granted or denied by the underlying filesystem, if (and only if) 1733 - * fl_grant is set. Callers expecting ->lock() to return asynchronously 1754 + * lm_grant is set. Callers expecting ->lock() to return asynchronously 1734 1755 * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if) 1735 1756 * the request is for a blocking lock. When ->lock() does return asynchronously, 1736 - * it must return FILE_LOCK_DEFERRED, and call ->fl_grant() when the lock 1757 + * it must return FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock 1737 1758 * request completes. 1738 1759 * If the request is for non-blocking lock the file system should return 1739 1760 * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine ··· 1743 1764 * grants a lock so the VFS can find out which locks are locally held and do 1744 1765 * the correct lock cleanup when required. 1745 1766 * The underlying filesystem must not drop the kernel lock or call 1746 - * ->fl_grant() before returning to the caller with a FILE_LOCK_DEFERRED 1767 + * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED 1747 1768 * return code. 1748 1769 */ 1749 1770 int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) ··· 2312 2333 static int __init filelock_init(void) 2313 2334 { 2314 2335 filelock_cache = kmem_cache_create("file_lock_cache", 2315 - sizeof(struct file_lock), 0, SLAB_PANIC, 2316 - init_once); 2336 + sizeof(struct file_lock), 0, SLAB_PANIC, NULL); 2337 + 2317 2338 return 0; 2318 2339 } 2319 2340
-100
fs/nfsctl.c
··· 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 - 23 - static 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 - 38 - static 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 - 73 - SYSCALL_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 - }
-12
fs/nfsd/Kconfig
··· 28 28 29 29 If unsure, say N. 30 30 31 - config 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 - 43 31 config NFSD_V2_ACL 44 32 bool 45 33 depends on NFSD
+1 -1
fs/nfsd/cache.h
··· 69 69 70 70 int nfsd_reply_cache_init(void); 71 71 void nfsd_reply_cache_shutdown(void); 72 - int nfsd_cache_lookup(struct svc_rqst *, int); 72 + int nfsd_cache_lookup(struct svc_rqst *); 73 73 void nfsd_cache_update(struct svc_rqst *, int, __be32 *); 74 74 75 75 #ifdef CONFIG_NFSD_V4
-418
fs/nfsd/export.c
··· 797 797 return ek; 798 798 } 799 799 800 - #ifdef CONFIG_NFSD_DEPRECATED 801 - static 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 - */ 826 - static inline struct svc_expkey * 827 - exp_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 - */ 842 - static inline struct svc_expkey * 843 - exp_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 853 801 static svc_export *exp_get_by_name(svc_client *clp, const struct path *path, 854 802 struct cache_req *reqp) ··· 838 890 return exp; 839 891 } 840 892 841 - #ifdef CONFIG_NFSD_DEPRECATED 842 - /* 843 - * Hashtable locking. Write locks are placed only by user processes 844 - * wanting to modify export information. 845 - * Write locking only done in this file. Read locking 846 - * needed externally. 847 - */ 848 893 849 - static DECLARE_RWSEM(hash_sem); 850 - 851 - void 852 - exp_readlock(void) 853 - { 854 - down_read(&hash_sem); 855 - } 856 - 857 - static inline void 858 - exp_writelock(void) 859 - { 860 - down_write(&hash_sem); 861 - } 862 - 863 - void 864 - exp_readunlock(void) 865 - { 866 - up_read(&hash_sem); 867 - } 868 - 869 - static inline void 870 - exp_writeunlock(void) 871 - { 872 - up_write(&hash_sem); 873 - } 874 - #else 875 - 876 - /* hash_sem not needed once deprecated interface is removed */ 877 - void exp_readlock(void) {} 878 - static inline void exp_writelock(void){} 879 - void exp_readunlock(void) {} 880 - static inline void exp_writeunlock(void){} 881 - 882 - #endif 883 - 884 - #ifdef CONFIG_NFSD_DEPRECATED 885 - static void exp_do_unexport(svc_export *unexp); 886 - static int exp_verify_string(char *cp, int max); 887 - 888 - static void exp_fsid_unhash(struct svc_export *exp) 889 - { 890 - struct svc_expkey *ek; 891 - 892 - if ((exp->ex_flags & NFSEXP_FSID) == 0) 893 - return; 894 - 895 - ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid); 896 - if (!IS_ERR(ek)) { 897 - sunrpc_invalidate(&ek->h, &svc_expkey_cache); 898 - cache_put(&ek->h, &svc_expkey_cache); 899 - } 900 - } 901 - 902 - static int exp_fsid_hash(svc_client *clp, struct svc_export *exp) 903 - { 904 - u32 fsid[2]; 905 - 906 - if ((exp->ex_flags & NFSEXP_FSID) == 0) 907 - return 0; 908 - 909 - mk_fsid(FSID_NUM, fsid, 0, 0, exp->ex_fsid, NULL); 910 - return exp_set_key(clp, FSID_NUM, fsid, exp); 911 - } 912 - 913 - static int exp_hash(struct auth_domain *clp, struct svc_export *exp) 914 - { 915 - u32 fsid[2]; 916 - struct inode *inode = exp->ex_path.dentry->d_inode; 917 - dev_t dev = inode->i_sb->s_dev; 918 - 919 - if (old_valid_dev(dev)) { 920 - mk_fsid(FSID_DEV, fsid, dev, inode->i_ino, 0, NULL); 921 - return exp_set_key(clp, FSID_DEV, fsid, exp); 922 - } 923 - mk_fsid(FSID_ENCODE_DEV, fsid, dev, inode->i_ino, 0, NULL); 924 - return exp_set_key(clp, FSID_ENCODE_DEV, fsid, exp); 925 - } 926 - 927 - static void exp_unhash(struct svc_export *exp) 928 - { 929 - struct svc_expkey *ek; 930 - struct inode *inode = exp->ex_path.dentry->d_inode; 931 - 932 - ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); 933 - if (!IS_ERR(ek)) { 934 - sunrpc_invalidate(&ek->h, &svc_expkey_cache); 935 - cache_put(&ek->h, &svc_expkey_cache); 936 - } 937 - } 938 - 939 - /* 940 - * Export a file system. 941 - */ 942 - int 943 - exp_export(struct nfsctl_export *nxp) 944 - { 945 - svc_client *clp; 946 - struct svc_export *exp = NULL; 947 - struct svc_export new; 948 - struct svc_expkey *fsid_key = NULL; 949 - struct path path; 950 - int err; 951 - 952 - /* Consistency check */ 953 - err = -EINVAL; 954 - if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) || 955 - !exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX)) 956 - goto out; 957 - 958 - dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n", 959 - nxp->ex_client, nxp->ex_path, 960 - (unsigned)nxp->ex_dev, (long)nxp->ex_ino, 961 - nxp->ex_flags); 962 - 963 - /* Try to lock the export table for update */ 964 - exp_writelock(); 965 - 966 - /* Look up client info */ 967 - if (!(clp = auth_domain_find(nxp->ex_client))) 968 - goto out_unlock; 969 - 970 - 971 - /* Look up the dentry */ 972 - err = kern_path(nxp->ex_path, 0, &path); 973 - if (err) 974 - goto out_put_clp; 975 - err = -EINVAL; 976 - 977 - exp = exp_get_by_name(clp, &path, NULL); 978 - 979 - memset(&new, 0, sizeof(new)); 980 - 981 - /* must make sure there won't be an ex_fsid clash */ 982 - if ((nxp->ex_flags & NFSEXP_FSID) && 983 - (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) && 984 - fsid_key->ek_path.mnt && 985 - (fsid_key->ek_path.mnt != path.mnt || 986 - fsid_key->ek_path.dentry != path.dentry)) 987 - goto finish; 988 - 989 - if (!IS_ERR(exp)) { 990 - /* just a flags/id/fsid update */ 991 - 992 - exp_fsid_unhash(exp); 993 - exp->ex_flags = nxp->ex_flags; 994 - exp->ex_anon_uid = nxp->ex_anon_uid; 995 - exp->ex_anon_gid = nxp->ex_anon_gid; 996 - exp->ex_fsid = nxp->ex_dev; 997 - 998 - err = exp_fsid_hash(clp, exp); 999 - goto finish; 1000 - } 1001 - 1002 - err = check_export(path.dentry->d_inode, &nxp->ex_flags, NULL); 1003 - if (err) goto finish; 1004 - 1005 - err = -ENOMEM; 1006 - 1007 - dprintk("nfsd: creating export entry %p for client %p\n", exp, clp); 1008 - 1009 - new.h.expiry_time = NEVER; 1010 - new.h.flags = 0; 1011 - new.ex_pathname = kstrdup(nxp->ex_path, GFP_KERNEL); 1012 - if (!new.ex_pathname) 1013 - goto finish; 1014 - new.ex_client = clp; 1015 - new.ex_path = path; 1016 - new.ex_flags = nxp->ex_flags; 1017 - new.ex_anon_uid = nxp->ex_anon_uid; 1018 - new.ex_anon_gid = nxp->ex_anon_gid; 1019 - new.ex_fsid = nxp->ex_dev; 1020 - 1021 - exp = svc_export_lookup(&new); 1022 - if (exp) 1023 - exp = svc_export_update(&new, exp); 1024 - 1025 - if (!exp) 1026 - goto finish; 1027 - 1028 - if (exp_hash(clp, exp) || 1029 - exp_fsid_hash(clp, exp)) { 1030 - /* failed to create at least one index */ 1031 - exp_do_unexport(exp); 1032 - cache_flush(); 1033 - } else 1034 - err = 0; 1035 - finish: 1036 - kfree(new.ex_pathname); 1037 - if (!IS_ERR_OR_NULL(exp)) 1038 - exp_put(exp); 1039 - if (!IS_ERR_OR_NULL(fsid_key)) 1040 - cache_put(&fsid_key->h, &svc_expkey_cache); 1041 - path_put(&path); 1042 - out_put_clp: 1043 - auth_domain_put(clp); 1044 - out_unlock: 1045 - exp_writeunlock(); 1046 - out: 1047 - return err; 1048 - } 1049 - 1050 - /* 1051 - * Unexport a file system. The export entry has already 1052 - * been removed from the client's list of exported fs's. 1053 - */ 1054 - static void 1055 - exp_do_unexport(svc_export *unexp) 1056 - { 1057 - sunrpc_invalidate(&unexp->h, &svc_export_cache); 1058 - exp_unhash(unexp); 1059 - exp_fsid_unhash(unexp); 1060 - } 1061 - 1062 - 1063 - /* 1064 - * unexport syscall. 1065 - */ 1066 - int 1067 - exp_unexport(struct nfsctl_export *nxp) 1068 - { 1069 - struct auth_domain *dom; 1070 - svc_export *exp; 1071 - struct path path; 1072 - int err; 1073 - 1074 - /* Consistency check */ 1075 - if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) || 1076 - !exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX)) 1077 - return -EINVAL; 1078 - 1079 - exp_writelock(); 1080 - 1081 - err = -EINVAL; 1082 - dom = auth_domain_find(nxp->ex_client); 1083 - if (!dom) { 1084 - dprintk("nfsd: unexport couldn't find %s\n", nxp->ex_client); 1085 - goto out_unlock; 1086 - } 1087 - 1088 - err = kern_path(nxp->ex_path, 0, &path); 1089 - if (err) 1090 - goto out_domain; 1091 - 1092 - err = -EINVAL; 1093 - exp = exp_get_by_name(dom, &path, NULL); 1094 - path_put(&path); 1095 - if (IS_ERR(exp)) 1096 - goto out_domain; 1097 - 1098 - exp_do_unexport(exp); 1099 - exp_put(exp); 1100 - err = 0; 1101 - 1102 - out_domain: 1103 - auth_domain_put(dom); 1104 - cache_flush(); 1105 - out_unlock: 1106 - exp_writeunlock(); 1107 - return err; 1108 - } 1109 - #endif /* CONFIG_NFSD_DEPRECATED */ 1110 894 1111 895 /* 1112 896 * Obtain the root fh on behalf of a client. ··· 1047 1367 unsigned hash, export; 1048 1368 struct cache_head *ch; 1049 1369 1050 - exp_readlock(); 1051 1370 read_lock(&svc_export_cache.hash_lock); 1052 1371 if (!n--) 1053 1372 return SEQ_START_TOKEN; ··· 1097 1418 __releases(svc_export_cache.hash_lock) 1098 1419 { 1099 1420 read_unlock(&svc_export_cache.hash_lock); 1100 - exp_readunlock(); 1101 1421 } 1102 1422 1103 1423 static struct flags { ··· 1228 1550 .show = e_show, 1229 1551 }; 1230 1552 1231 - #ifdef CONFIG_NFSD_DEPRECATED 1232 - /* 1233 - * Add or modify a client. 1234 - * Change requests may involve the list of host addresses. The list of 1235 - * exports and possibly existing uid maps are left untouched. 1236 - */ 1237 - int 1238 - exp_addclient(struct nfsctl_client *ncp) 1239 - { 1240 - struct auth_domain *dom; 1241 - int i, err; 1242 - struct in6_addr addr6; 1243 - 1244 - /* First, consistency check. */ 1245 - err = -EINVAL; 1246 - if (! exp_verify_string(ncp->cl_ident, NFSCLNT_IDMAX)) 1247 - goto out; 1248 - if (ncp->cl_naddr > NFSCLNT_ADDRMAX) 1249 - goto out; 1250 - 1251 - /* Lock the hashtable */ 1252 - exp_writelock(); 1253 - 1254 - dom = unix_domain_find(ncp->cl_ident); 1255 - 1256 - err = -ENOMEM; 1257 - if (!dom) 1258 - goto out_unlock; 1259 - 1260 - /* Insert client into hashtable. */ 1261 - for (i = 0; i < ncp->cl_naddr; i++) { 1262 - ipv6_addr_set_v4mapped(ncp->cl_addrlist[i].s_addr, &addr6); 1263 - auth_unix_add_addr(&init_net, &addr6, dom); 1264 - } 1265 - auth_unix_forget_old(dom); 1266 - auth_domain_put(dom); 1267 - 1268 - err = 0; 1269 - 1270 - out_unlock: 1271 - exp_writeunlock(); 1272 - out: 1273 - return err; 1274 - } 1275 - 1276 - /* 1277 - * Delete a client given an identifier. 1278 - */ 1279 - int 1280 - exp_delclient(struct nfsctl_client *ncp) 1281 - { 1282 - int err; 1283 - struct auth_domain *dom; 1284 - 1285 - err = -EINVAL; 1286 - if (!exp_verify_string(ncp->cl_ident, NFSCLNT_IDMAX)) 1287 - goto out; 1288 - 1289 - /* Lock the hashtable */ 1290 - exp_writelock(); 1291 - 1292 - dom = auth_domain_find(ncp->cl_ident); 1293 - /* just make sure that no addresses work 1294 - * and that it will expire soon 1295 - */ 1296 - if (dom) { 1297 - err = auth_unix_forget_old(dom); 1298 - auth_domain_put(dom); 1299 - } 1300 - 1301 - exp_writeunlock(); 1302 - out: 1303 - return err; 1304 - } 1305 - 1306 - /* 1307 - * Verify that string is non-empty and does not exceed max length. 1308 - */ 1309 - static int 1310 - exp_verify_string(char *cp, int max) 1311 - { 1312 - int i; 1313 - 1314 - for (i = 0; i < max; i++) 1315 - if (!cp[i]) 1316 - return i; 1317 - cp[i] = 0; 1318 - printk(KERN_NOTICE "nfsd: couldn't validate string %s\n", cp); 1319 - return 0; 1320 - } 1321 - #endif /* CONFIG_NFSD_DEPRECATED */ 1322 1553 1323 1554 /* 1324 1555 * Initialize the exports module. ··· 1254 1667 void 1255 1668 nfsd_export_flush(void) 1256 1669 { 1257 - exp_writelock(); 1258 1670 cache_purge(&svc_expkey_cache); 1259 1671 cache_purge(&svc_export_cache); 1260 - exp_writeunlock(); 1261 1672 } 1262 1673 1263 1674 /* ··· 1267 1682 1268 1683 dprintk("nfsd: shutting down export module.\n"); 1269 1684 1270 - exp_writelock(); 1271 - 1272 1685 cache_unregister(&svc_expkey_cache); 1273 1686 cache_unregister(&svc_export_cache); 1274 1687 svcauth_unix_purge(); 1275 1688 1276 - exp_writeunlock(); 1277 1689 dprintk("nfsd: export shutdown complete.\n"); 1278 1690 }
-2
fs/nfsd/lockd.c
··· 35 35 memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size); 36 36 fh.fh_export = NULL; 37 37 38 - exp_readlock(); 39 38 nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp); 40 39 fh_put(&fh); 41 - exp_readunlock(); 42 40 /* We return nlm error codes as nlm doesn't know 43 41 * about nfsd, but nfsd does know about nlm.. 44 42 */
+47 -11
fs/nfsd/nfs4proc.c
··· 291 291 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 292 292 return nfserr_inval; 293 293 294 + /* 295 + * RFC5661 18.51.3 296 + * Before RECLAIM_COMPLETE done, server should deny new lock 297 + */ 298 + if (nfsd4_has_session(cstate) && 299 + !cstate->session->se_client->cl_firststate && 300 + open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 301 + return nfserr_grace; 302 + 294 303 if (nfsd4_has_session(cstate)) 295 304 copy_clientid(&open->op_clientid, cstate->session); 296 305 ··· 1007 998 nfsd4op_func op_func; 1008 999 u32 op_flags; 1009 1000 char *op_name; 1001 + /* 1002 + * We use the DRC for compounds containing non-idempotent 1003 + * operations, *except* those that are 4.1-specific (since 1004 + * sessions provide their own EOS), and except for stateful 1005 + * operations other than setclientid and setclientid_confirm 1006 + * (since sequence numbers provide EOS for open, lock, etc in 1007 + * the v4.0 case). 1008 + */ 1009 + bool op_cacheresult; 1010 1010 }; 1011 1011 1012 1012 static struct nfsd4_operation nfsd4_ops[]; ··· 1058 1040 static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op) 1059 1041 { 1060 1042 return &nfsd4_ops[op->opnum]; 1043 + } 1044 + 1045 + bool nfsd4_cache_this_op(struct nfsd4_op *op) 1046 + { 1047 + return OPDESC(op)->op_cacheresult; 1061 1048 } 1062 1049 1063 1050 static bool need_wrongsec_check(struct svc_rqst *rqstp) ··· 1232 1209 fh_put(&resp->cstate.save_fh); 1233 1210 BUG_ON(resp->cstate.replay_owner); 1234 1211 out: 1235 - nfsd4_release_compoundargs(args); 1236 1212 /* Reset deferral mechanism for RPC deferrals */ 1237 1213 rqstp->rq_usedeferral = 1; 1238 1214 dprintk("nfsv4 compound returned %d\n", ntohl(status)); ··· 1254 1232 [OP_CREATE] = { 1255 1233 .op_func = (nfsd4op_func)nfsd4_create, 1256 1234 .op_name = "OP_CREATE", 1235 + .op_cacheresult = true, 1257 1236 }, 1258 1237 [OP_DELEGRETURN] = { 1259 1238 .op_func = (nfsd4op_func)nfsd4_delegreturn, ··· 1272 1249 [OP_LINK] = { 1273 1250 .op_func = (nfsd4op_func)nfsd4_link, 1274 1251 .op_name = "OP_LINK", 1252 + .op_cacheresult = true, 1275 1253 }, 1276 1254 [OP_LOCK] = { 1277 1255 .op_func = (nfsd4op_func)nfsd4_lock, ··· 1346 1322 [OP_REMOVE] = { 1347 1323 .op_func = (nfsd4op_func)nfsd4_remove, 1348 1324 .op_name = "OP_REMOVE", 1325 + .op_cacheresult = true, 1349 1326 }, 1350 1327 [OP_RENAME] = { 1351 1328 .op_name = "OP_RENAME", 1352 1329 .op_func = (nfsd4op_func)nfsd4_rename, 1330 + .op_cacheresult = true, 1353 1331 }, 1354 1332 [OP_RENEW] = { 1355 1333 .op_func = (nfsd4op_func)nfsd4_renew, ··· 1377 1351 [OP_SETATTR] = { 1378 1352 .op_func = (nfsd4op_func)nfsd4_setattr, 1379 1353 .op_name = "OP_SETATTR", 1354 + .op_cacheresult = true, 1380 1355 }, 1381 1356 [OP_SETCLIENTID] = { 1382 1357 .op_func = (nfsd4op_func)nfsd4_setclientid, 1383 1358 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1384 1359 .op_name = "OP_SETCLIENTID", 1360 + .op_cacheresult = true, 1385 1361 }, 1386 1362 [OP_SETCLIENTID_CONFIRM] = { 1387 1363 .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, 1388 1364 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1389 1365 .op_name = "OP_SETCLIENTID_CONFIRM", 1366 + .op_cacheresult = true, 1390 1367 }, 1391 1368 [OP_VERIFY] = { 1392 1369 .op_func = (nfsd4op_func)nfsd4_verify, ··· 1398 1369 [OP_WRITE] = { 1399 1370 .op_func = (nfsd4op_func)nfsd4_write, 1400 1371 .op_name = "OP_WRITE", 1372 + .op_cacheresult = true, 1401 1373 }, 1402 1374 [OP_RELEASE_LOCKOWNER] = { 1403 1375 .op_func = (nfsd4op_func)nfsd4_release_lockowner, ··· 1432 1402 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1433 1403 .op_name = "OP_SEQUENCE", 1434 1404 }, 1405 + [OP_DESTROY_CLIENTID] = { 1406 + .op_func = NULL, 1407 + .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1408 + .op_name = "OP_DESTROY_CLIENTID", 1409 + }, 1435 1410 [OP_RECLAIM_COMPLETE] = { 1436 1411 .op_func = (nfsd4op_func)nfsd4_reclaim_complete, 1437 1412 .op_flags = ALLOWED_WITHOUT_FH, ··· 1446 1411 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, 1447 1412 .op_flags = OP_HANDLES_WRONGSEC, 1448 1413 .op_name = "OP_SECINFO_NO_NAME", 1414 + }, 1415 + [OP_TEST_STATEID] = { 1416 + .op_func = (nfsd4op_func)nfsd4_test_stateid, 1417 + .op_flags = ALLOWED_WITHOUT_FH, 1418 + .op_name = "OP_TEST_STATEID", 1419 + }, 1420 + [OP_FREE_STATEID] = { 1421 + .op_func = (nfsd4op_func)nfsd4_free_stateid, 1422 + .op_flags = ALLOWED_WITHOUT_FH, 1423 + .op_name = "OP_FREE_STATEID", 1449 1424 }, 1450 1425 }; 1451 1426 ··· 1469 1424 #define nfsd4_voidres nfsd4_voidargs 1470 1425 struct nfsd4_voidargs { int dummy; }; 1471 1426 1472 - /* 1473 - * TODO: At the present time, the NFSv4 server does not do XID caching 1474 - * of requests. Implementing XID caching would not be a serious problem, 1475 - * although it would require a mild change in interfaces since one 1476 - * doesn't know whether an NFSv4 request is idempotent until after the 1477 - * XDR decode. However, XID caching totally confuses pynfs (Peter 1478 - * Astrand's regression testsuite for NFSv4 servers), which reuses 1479 - * XID's liberally, so I've left it unimplemented until pynfs generates 1480 - * better XID's. 1481 - */ 1482 1427 static struct svc_procedure nfsd_procedures4[2] = { 1483 1428 [NFSPROC4_NULL] = { 1484 1429 .pc_func = (svc_procfunc) nfsd4_proc_null, ··· 1484 1449 .pc_encode = (kxdrproc_t) nfs4svc_encode_compoundres, 1485 1450 .pc_argsize = sizeof(struct nfsd4_compoundargs), 1486 1451 .pc_ressize = sizeof(struct nfsd4_compoundres), 1452 + .pc_release = nfsd4_release_compoundargs, 1487 1453 .pc_cachetype = RC_NOCACHE, 1488 1454 .pc_xdrressize = NFSD_BUFSIZE/4, 1489 1455 },
+223 -42
fs/nfsd/nfs4state.c
··· 37 37 #include <linux/slab.h> 38 38 #include <linux/namei.h> 39 39 #include <linux/swap.h> 40 + #include <linux/pagemap.h> 40 41 #include <linux/sunrpc/svcauth_gss.h> 41 42 #include <linux/sunrpc/clnt.h> 42 43 #include "xdr4.h" ··· 61 60 62 61 /* forward declarations */ 63 62 static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); 63 + static struct nfs4_stateid * search_for_stateid(stateid_t *stid); 64 + static struct nfs4_delegation * search_for_delegation(stateid_t *stid); 64 65 static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); 65 66 static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery"; 66 67 static void nfs4_set_recdir(char *recdir); 68 + static int check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner); 67 69 68 70 /* Locking: */ 69 71 ··· 385 381 BUG(); 386 382 } 387 383 388 - static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp) 389 - { 390 - unsigned int access; 391 - 392 - set_access(&access, stp->st_access_bmap); 393 - return nfs4_access_to_omode(access); 394 - } 395 - 396 384 static void unhash_generic_stateid(struct nfs4_stateid *stp) 397 385 { 398 386 list_del(&stp->st_hash); ··· 394 398 395 399 static void free_generic_stateid(struct nfs4_stateid *stp) 396 400 { 397 - int oflag; 401 + int i; 398 402 399 403 if (stp->st_access_bmap) { 400 - oflag = nfs4_access_bmap_to_omode(stp); 401 - nfs4_file_put_access(stp->st_file, oflag); 404 + for (i = 1; i < 4; i++) { 405 + if (test_bit(i, &stp->st_access_bmap)) 406 + nfs4_file_put_access(stp->st_file, 407 + nfs4_access_to_omode(i)); 408 + } 402 409 } 403 410 put_nfs4_file(stp->st_file); 404 411 kmem_cache_free(stateid_slab, stp); ··· 1506 1507 return slot->sl_status; 1507 1508 } 1508 1509 1510 + #define NFSD_MIN_REQ_HDR_SEQ_SZ ((\ 1511 + 2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \ 1512 + 1 + /* MIN tag is length with zero, only length */ \ 1513 + 3 + /* version, opcount, opcode */ \ 1514 + XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ 1515 + /* seqid, slotID, slotID, cache */ \ 1516 + 4 ) * sizeof(__be32)) 1517 + 1518 + #define NFSD_MIN_RESP_HDR_SEQ_SZ ((\ 1519 + 2 + /* verifier: AUTH_NULL, length 0 */\ 1520 + 1 + /* status */ \ 1521 + 1 + /* MIN tag is length with zero, only length */ \ 1522 + 3 + /* opcount, opcode, opstatus*/ \ 1523 + XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ 1524 + /* seqid, slotID, slotID, slotID, status */ \ 1525 + 5 ) * sizeof(__be32)) 1526 + 1527 + static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel) 1528 + { 1529 + return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ 1530 + || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ; 1531 + } 1532 + 1509 1533 __be32 1510 1534 nfsd4_create_session(struct svc_rqst *rqstp, 1511 1535 struct nfsd4_compound_state *cstate, ··· 1596 1574 */ 1597 1575 cr_ses->flags &= ~SESSION4_PERSIST; 1598 1576 cr_ses->flags &= ~SESSION4_RDMA; 1577 + 1578 + status = nfserr_toosmall; 1579 + if (check_forechannel_attrs(cr_ses->fore_channel)) 1580 + goto out; 1599 1581 1600 1582 status = nfserr_jukebox; 1601 1583 new = alloc_init_session(rqstp, conf, cr_ses); ··· 1762 1736 return args->opcnt > session->se_fchannel.maxops; 1763 1737 } 1764 1738 1739 + static bool nfsd4_request_too_big(struct svc_rqst *rqstp, 1740 + struct nfsd4_session *session) 1741 + { 1742 + struct xdr_buf *xb = &rqstp->rq_arg; 1743 + 1744 + return xb->len > session->se_fchannel.maxreq_sz; 1745 + } 1746 + 1765 1747 __be32 1766 1748 nfsd4_sequence(struct svc_rqst *rqstp, 1767 1749 struct nfsd4_compound_state *cstate, ··· 1800 1766 1801 1767 status = nfserr_too_many_ops; 1802 1768 if (nfsd4_session_too_many_ops(rqstp, session)) 1769 + goto out; 1770 + 1771 + status = nfserr_req_too_big; 1772 + if (nfsd4_request_too_big(rqstp, session)) 1803 1773 goto out; 1804 1774 1805 1775 status = nfserr_badslot; ··· 2375 2337 return ret; 2376 2338 } 2377 2339 2378 - static inline void 2379 - nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access) 2380 - { 2381 - if (share_access & NFS4_SHARE_ACCESS_WRITE) 2382 - nfs4_file_put_access(fp, O_WRONLY); 2383 - if (share_access & NFS4_SHARE_ACCESS_READ) 2384 - nfs4_file_put_access(fp, O_RDONLY); 2385 - } 2386 - 2387 2340 static void nfsd_break_one_deleg(struct nfs4_delegation *dp) 2388 2341 { 2389 2342 /* We're assuming the state code never drops its reference ··· 2425 2396 } 2426 2397 2427 2398 static const struct lock_manager_operations nfsd_lease_mng_ops = { 2428 - .fl_break = nfsd_break_deleg_cb, 2429 - .fl_change = nfsd_change_deleg_cb, 2399 + .lm_break = nfsd_break_deleg_cb, 2400 + .lm_change = nfsd_change_deleg_cb, 2430 2401 }; 2431 2402 2432 2403 ··· 2585 2556 return flags; 2586 2557 } 2587 2558 2588 - static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file 2589 - *fp, struct svc_fh *cur_fh, u32 nfs4_access) 2559 + static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, 2560 + struct svc_fh *cur_fh, struct nfsd4_open *open) 2590 2561 { 2591 2562 __be32 status; 2592 - int oflag = nfs4_access_to_omode(nfs4_access); 2593 - int access = nfs4_access_to_access(nfs4_access); 2563 + int oflag = nfs4_access_to_omode(open->op_share_access); 2564 + int access = nfs4_access_to_access(open->op_share_access); 2565 + 2566 + /* CLAIM_DELEGATE_CUR is used in response to a broken lease; 2567 + * allowing it to break the lease and return EAGAIN leaves the 2568 + * client unable to make progress in returning the delegation */ 2569 + if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) 2570 + access |= NFSD_MAY_NOT_BREAK_LEASE; 2594 2571 2595 2572 if (!fp->fi_fds[oflag]) { 2596 2573 status = nfsd_open(rqstp, cur_fh, S_IFREG, access, ··· 2621 2586 if (stp == NULL) 2622 2587 return nfserr_resource; 2623 2588 2624 - status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access); 2589 + status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); 2625 2590 if (status) { 2626 2591 kmem_cache_free(stateid_slab, stp); 2627 2592 return status; ··· 2654 2619 2655 2620 new_access = !test_bit(op_share_access, &stp->st_access_bmap); 2656 2621 if (new_access) { 2657 - status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access); 2622 + status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); 2658 2623 if (status) 2659 2624 return status; 2660 2625 } 2661 2626 status = nfsd4_truncate(rqstp, cur_fh, open); 2662 2627 if (status) { 2663 2628 if (new_access) { 2664 - int oflag = nfs4_access_to_omode(new_access); 2629 + int oflag = nfs4_access_to_omode(op_share_access); 2665 2630 nfs4_file_put_access(fp, oflag); 2666 2631 } 2667 2632 return status; ··· 3172 3137 return stateid->si_fileid == 0; 3173 3138 } 3174 3139 3140 + static int is_open_stateid(struct nfs4_stateid *stateid) 3141 + { 3142 + return stateid->st_openstp == NULL; 3143 + } 3144 + 3145 + __be32 nfs4_validate_stateid(stateid_t *stateid, int flags) 3146 + { 3147 + struct nfs4_stateid *stp = NULL; 3148 + __be32 status = nfserr_stale_stateid; 3149 + 3150 + if (STALE_STATEID(stateid)) 3151 + goto out; 3152 + 3153 + status = nfserr_expired; 3154 + stp = search_for_stateid(stateid); 3155 + if (!stp) 3156 + goto out; 3157 + status = nfserr_bad_stateid; 3158 + 3159 + if (!stp->st_stateowner->so_confirmed) 3160 + goto out; 3161 + 3162 + status = check_stateid_generation(stateid, &stp->st_stateid, flags); 3163 + if (status) 3164 + goto out; 3165 + 3166 + status = nfs_ok; 3167 + out: 3168 + return status; 3169 + } 3170 + 3175 3171 /* 3176 3172 * Checks for stateid operations 3177 3173 */ ··· 3280 3214 status = nfs_ok; 3281 3215 out: 3282 3216 return status; 3217 + } 3218 + 3219 + static __be32 3220 + nfsd4_free_delegation_stateid(stateid_t *stateid) 3221 + { 3222 + struct nfs4_delegation *dp = search_for_delegation(stateid); 3223 + if (dp) 3224 + return nfserr_locks_held; 3225 + return nfserr_bad_stateid; 3226 + } 3227 + 3228 + static __be32 3229 + nfsd4_free_lock_stateid(struct nfs4_stateid *stp) 3230 + { 3231 + if (check_for_locks(stp->st_file, stp->st_stateowner)) 3232 + return nfserr_locks_held; 3233 + release_lock_stateid(stp); 3234 + return nfs_ok; 3235 + } 3236 + 3237 + /* 3238 + * Test if the stateid is valid 3239 + */ 3240 + __be32 3241 + nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3242 + struct nfsd4_test_stateid *test_stateid) 3243 + { 3244 + test_stateid->ts_has_session = nfsd4_has_session(cstate); 3245 + return nfs_ok; 3246 + } 3247 + 3248 + /* 3249 + * Free a state id 3250 + */ 3251 + __be32 3252 + nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3253 + struct nfsd4_free_stateid *free_stateid) 3254 + { 3255 + stateid_t *stateid = &free_stateid->fr_stateid; 3256 + struct nfs4_stateid *stp; 3257 + __be32 ret; 3258 + 3259 + nfs4_lock_state(); 3260 + if (is_delegation_stateid(stateid)) { 3261 + ret = nfsd4_free_delegation_stateid(stateid); 3262 + goto out; 3263 + } 3264 + 3265 + stp = search_for_stateid(stateid); 3266 + if (!stp) { 3267 + ret = nfserr_bad_stateid; 3268 + goto out; 3269 + } 3270 + if (stateid->si_generation != 0) { 3271 + if (stateid->si_generation < stp->st_stateid.si_generation) { 3272 + ret = nfserr_old_stateid; 3273 + goto out; 3274 + } 3275 + if (stateid->si_generation > stp->st_stateid.si_generation) { 3276 + ret = nfserr_bad_stateid; 3277 + goto out; 3278 + } 3279 + } 3280 + 3281 + if (is_open_stateid(stp)) { 3282 + ret = nfserr_locks_held; 3283 + goto out; 3284 + } else { 3285 + ret = nfsd4_free_lock_stateid(stp); 3286 + goto out; 3287 + } 3288 + 3289 + out: 3290 + nfs4_unlock_state(); 3291 + return ret; 3283 3292 } 3284 3293 3285 3294 static inline int ··· 3525 3384 return status; 3526 3385 } 3527 3386 3528 - 3529 - /* 3530 - * unset all bits in union bitmap (bmap) that 3531 - * do not exist in share (from successful OPEN_DOWNGRADE) 3532 - */ 3533 - static void 3534 - reset_union_bmap_access(unsigned long access, unsigned long *bmap) 3387 + static inline void nfs4_file_downgrade(struct nfs4_stateid *stp, unsigned int to_access) 3535 3388 { 3536 3389 int i; 3390 + 3537 3391 for (i = 1; i < 4; i++) { 3538 - if ((i & access) != i) 3539 - __clear_bit(i, bmap); 3392 + if (test_bit(i, &stp->st_access_bmap) && !(i & to_access)) { 3393 + nfs4_file_put_access(stp->st_file, i); 3394 + __clear_bit(i, &stp->st_access_bmap); 3395 + } 3540 3396 } 3541 3397 } 3542 3398 ··· 3554 3416 { 3555 3417 __be32 status; 3556 3418 struct nfs4_stateid *stp; 3557 - unsigned int share_access; 3558 3419 3559 3420 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 3560 3421 (int)cstate->current_fh.fh_dentry->d_name.len, ··· 3582 3445 stp->st_deny_bmap, od->od_share_deny); 3583 3446 goto out; 3584 3447 } 3585 - set_access(&share_access, stp->st_access_bmap); 3586 - nfs4_file_downgrade(stp->st_file, share_access & ~od->od_share_access); 3448 + nfs4_file_downgrade(stp, od->od_share_access); 3587 3449 3588 - reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap); 3589 3450 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3590 3451 3591 3452 update_stateid(&stp->st_stateid); ··· 3729 3594 static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE]; 3730 3595 static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE]; 3731 3596 3597 + static int 3598 + same_stateid(stateid_t *id_one, stateid_t *id_two) 3599 + { 3600 + if (id_one->si_stateownerid != id_two->si_stateownerid) 3601 + return 0; 3602 + return id_one->si_fileid == id_two->si_fileid; 3603 + } 3604 + 3732 3605 static struct nfs4_stateid * 3733 3606 find_stateid(stateid_t *stid, int flags) 3734 3607 { ··· 3761 3618 if ((local->st_stateid.si_stateownerid == st_id) && 3762 3619 (local->st_stateid.si_fileid == f_id)) 3763 3620 return local; 3621 + } 3622 + } 3623 + return NULL; 3624 + } 3625 + 3626 + static struct nfs4_stateid * 3627 + search_for_stateid(stateid_t *stid) 3628 + { 3629 + struct nfs4_stateid *local; 3630 + unsigned int hashval = stateid_hashval(stid->si_stateownerid, stid->si_fileid); 3631 + 3632 + list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) { 3633 + if (same_stateid(&local->st_stateid, stid)) 3634 + return local; 3635 + } 3636 + 3637 + list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) { 3638 + if (same_stateid(&local->st_stateid, stid)) 3639 + return local; 3640 + } 3641 + return NULL; 3642 + } 3643 + 3644 + static struct nfs4_delegation * 3645 + search_for_delegation(stateid_t *stid) 3646 + { 3647 + struct nfs4_file *fp; 3648 + struct nfs4_delegation *dp; 3649 + struct list_head *pos; 3650 + int i; 3651 + 3652 + for (i = 0; i < FILE_HASH_SIZE; i++) { 3653 + list_for_each_entry(fp, &file_hashtbl[i], fi_hash) { 3654 + list_for_each(pos, &fp->fi_delegations) { 3655 + dp = list_entry(pos, struct nfs4_delegation, dl_perfile); 3656 + if (same_stateid(&dp->dl_stateid, stid)) 3657 + return dp; 3658 + } 3764 3659 } 3765 3660 } 3766 3661 return NULL;
+131 -13
fs/nfsd/nfs4xdr.c
··· 44 44 #include <linux/namei.h> 45 45 #include <linux/statfs.h> 46 46 #include <linux/utsname.h> 47 + #include <linux/pagemap.h> 47 48 #include <linux/sunrpc/svcauth_gss.h> 48 49 49 50 #include "idmap.h" 50 51 #include "acl.h" 51 52 #include "xdr4.h" 52 53 #include "vfs.h" 53 - 54 + #include "state.h" 55 + #include "cache.h" 54 56 55 57 #define NFSDDBG_FACILITY NFSDDBG_XDR 56 58 ··· 132 130 goto xdr_error; \ 133 131 } \ 134 132 } while (0) 133 + 134 + static void save_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep) 135 + { 136 + savep->p = argp->p; 137 + savep->end = argp->end; 138 + savep->pagelen = argp->pagelen; 139 + savep->pagelist = argp->pagelist; 140 + } 141 + 142 + static void restore_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep) 143 + { 144 + argp->p = savep->p; 145 + argp->end = savep->end; 146 + argp->pagelen = savep->pagelen; 147 + argp->pagelist = savep->pagelist; 148 + } 135 149 136 150 static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) 137 151 { ··· 1264 1246 } 1265 1247 1266 1248 static __be32 1249 + nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp, 1250 + struct nfsd4_free_stateid *free_stateid) 1251 + { 1252 + DECODE_HEAD; 1253 + 1254 + READ_BUF(sizeof(stateid_t)); 1255 + READ32(free_stateid->fr_stateid.si_generation); 1256 + COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t)); 1257 + 1258 + DECODE_TAIL; 1259 + } 1260 + 1261 + static __be32 1267 1262 nfsd4_decode_sequence(struct nfsd4_compoundargs *argp, 1268 1263 struct nfsd4_sequence *seq) 1269 1264 { ··· 1290 1259 READ32(seq->cachethis); 1291 1260 1292 1261 DECODE_TAIL; 1262 + } 1263 + 1264 + static __be32 1265 + nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid) 1266 + { 1267 + unsigned int nbytes; 1268 + stateid_t si; 1269 + int i; 1270 + __be32 *p; 1271 + __be32 status; 1272 + 1273 + READ_BUF(4); 1274 + test_stateid->ts_num_ids = ntohl(*p++); 1275 + 1276 + nbytes = test_stateid->ts_num_ids * sizeof(stateid_t); 1277 + if (nbytes > (u32)((char *)argp->end - (char *)argp->p)) 1278 + goto xdr_error; 1279 + 1280 + test_stateid->ts_saved_args = argp; 1281 + save_buf(argp, &test_stateid->ts_savedp); 1282 + 1283 + for (i = 0; i < test_stateid->ts_num_ids; i++) { 1284 + status = nfsd4_decode_stateid(argp, &si); 1285 + if (status) 1286 + return status; 1287 + } 1288 + 1289 + status = 0; 1290 + out: 1291 + return status; 1292 + xdr_error: 1293 + dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__); 1294 + status = nfserr_bad_xdr; 1295 + goto out; 1293 1296 } 1294 1297 1295 1298 static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc) ··· 1435 1370 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, 1436 1371 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, 1437 1372 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, 1438 - [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, 1373 + [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_free_stateid, 1439 1374 [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, 1440 1375 [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp, 1441 1376 [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp, ··· 1445 1380 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name, 1446 1381 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, 1447 1382 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, 1448 - [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, 1383 + [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid, 1449 1384 [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, 1450 1385 [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, 1451 1386 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, ··· 1467 1402 DECODE_HEAD; 1468 1403 struct nfsd4_op *op; 1469 1404 struct nfsd4_minorversion_ops *ops; 1405 + bool cachethis = false; 1470 1406 int i; 1471 1407 1472 1408 /* ··· 1549 1483 argp->opcnt = i+1; 1550 1484 break; 1551 1485 } 1486 + /* 1487 + * We'll try to cache the result in the DRC if any one 1488 + * op in the compound wants to be cached: 1489 + */ 1490 + cachethis |= nfsd4_cache_this_op(op); 1552 1491 } 1492 + /* Sessions make the DRC unnecessary: */ 1493 + if (argp->minorversion) 1494 + cachethis = false; 1495 + argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; 1553 1496 1554 1497 DECODE_TAIL; 1555 1498 } ··· 3191 3116 } 3192 3117 3193 3118 static __be32 3119 + nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr, 3120 + struct nfsd4_free_stateid *free_stateid) 3121 + { 3122 + __be32 *p; 3123 + 3124 + if (nfserr) 3125 + return nfserr; 3126 + 3127 + RESERVE_SPACE(4); 3128 + WRITE32(nfserr); 3129 + ADJUST_ARGS(); 3130 + return nfserr; 3131 + } 3132 + 3133 + static __be32 3194 3134 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, 3195 3135 struct nfsd4_sequence *seq) 3196 3136 { ··· 3226 3136 ADJUST_ARGS(); 3227 3137 resp->cstate.datap = p; /* DRC cache data pointer */ 3228 3138 return 0; 3139 + } 3140 + 3141 + __be32 3142 + nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, 3143 + struct nfsd4_test_stateid *test_stateid) 3144 + { 3145 + struct nfsd4_compoundargs *argp; 3146 + stateid_t si; 3147 + __be32 *p; 3148 + int i; 3149 + int valid; 3150 + 3151 + restore_buf(test_stateid->ts_saved_args, &test_stateid->ts_savedp); 3152 + argp = test_stateid->ts_saved_args; 3153 + 3154 + RESERVE_SPACE(4); 3155 + *p++ = htonl(test_stateid->ts_num_ids); 3156 + resp->p = p; 3157 + 3158 + nfs4_lock_state(); 3159 + for (i = 0; i < test_stateid->ts_num_ids; i++) { 3160 + nfsd4_decode_stateid(argp, &si); 3161 + valid = nfs4_validate_stateid(&si, test_stateid->ts_has_session); 3162 + RESERVE_SPACE(4); 3163 + *p++ = htonl(valid); 3164 + resp->p = p; 3165 + } 3166 + nfs4_unlock_state(); 3167 + 3168 + return nfserr; 3229 3169 } 3230 3170 3231 3171 static __be32 ··· 3316 3196 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, 3317 3197 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, 3318 3198 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, 3319 - [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop, 3199 + [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_free_stateid, 3320 3200 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3321 3201 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop, 3322 3202 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, ··· 3326 3206 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name, 3327 3207 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, 3328 3208 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, 3329 - [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, 3209 + [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_test_stateid, 3330 3210 [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3331 3211 [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop, 3332 3212 [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop, ··· 3439 3319 return xdr_ressize_check(rqstp, p); 3440 3320 } 3441 3321 3442 - void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args) 3322 + int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) 3443 3323 { 3324 + struct svc_rqst *rqstp = rq; 3325 + struct nfsd4_compoundargs *args = rqstp->rq_argp; 3326 + 3444 3327 if (args->ops != args->iops) { 3445 3328 kfree(args->ops); 3446 3329 args->ops = args->iops; ··· 3456 3333 tb->release(tb->buf); 3457 3334 kfree(tb); 3458 3335 } 3336 + return 1; 3459 3337 } 3460 3338 3461 3339 int 3462 3340 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args) 3463 3341 { 3464 - __be32 status; 3465 - 3466 3342 args->p = p; 3467 3343 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; 3468 3344 args->pagelist = rqstp->rq_arg.pages; ··· 3471 3349 args->ops = args->iops; 3472 3350 args->rqstp = rqstp; 3473 3351 3474 - status = nfsd4_decode_compound(args); 3475 - if (status) { 3476 - nfsd4_release_compoundargs(args); 3477 - } 3478 - return !status; 3352 + return !nfsd4_decode_compound(args); 3479 3353 } 3480 3354 3481 3355 int
+2 -1
fs/nfsd/nfscache.c
··· 118 118 * Note that no operation within the loop may sleep. 119 119 */ 120 120 int 121 - nfsd_cache_lookup(struct svc_rqst *rqstp, int type) 121 + nfsd_cache_lookup(struct svc_rqst *rqstp) 122 122 { 123 123 struct hlist_node *hn; 124 124 struct hlist_head *rh; ··· 128 128 vers = rqstp->rq_vers, 129 129 proc = rqstp->rq_proc; 130 130 unsigned long age; 131 + int type = rqstp->rq_cachetype; 131 132 int rtn; 132 133 133 134 rqstp->rq_cacherep = NULL;
-343
fs/nfsd/nfsctl.c
··· 24 24 */ 25 25 enum { 26 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 27 NFSD_List, 37 28 NFSD_Export_features, 38 29 NFSD_Fh, ··· 50 59 /* 51 60 * write() for these nodes. 52 61 */ 53 - #ifdef CONFIG_NFSD_DEPRECATED 54 - static ssize_t write_svc(struct file *file, char *buf, size_t size); 55 - static ssize_t write_add(struct file *file, char *buf, size_t size); 56 - static ssize_t write_del(struct file *file, char *buf, size_t size); 57 - static ssize_t write_export(struct file *file, char *buf, size_t size); 58 - static ssize_t write_unexport(struct file *file, char *buf, size_t size); 59 - static ssize_t write_getfd(struct file *file, char *buf, size_t size); 60 - static ssize_t write_getfs(struct file *file, char *buf, size_t size); 61 - #endif 62 62 static ssize_t write_filehandle(struct file *file, char *buf, size_t size); 63 63 static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size); 64 64 static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size); ··· 65 83 #endif 66 84 67 85 static ssize_t (*write_op[])(struct file *, char *, size_t) = { 68 - #ifdef CONFIG_NFSD_DEPRECATED 69 - [NFSD_Svc] = write_svc, 70 - [NFSD_Add] = write_add, 71 - [NFSD_Del] = write_del, 72 - [NFSD_Export] = write_export, 73 - [NFSD_Unexport] = write_unexport, 74 - [NFSD_Getfd] = write_getfd, 75 - [NFSD_Getfs] = write_getfs, 76 - #endif 77 86 [NFSD_Fh] = write_filehandle, 78 87 [NFSD_FO_UnlockIP] = write_unlock_ip, 79 88 [NFSD_FO_UnlockFS] = write_unlock_fs, ··· 103 130 104 131 static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos) 105 132 { 106 - #ifdef CONFIG_NFSD_DEPRECATED 107 - static int warned; 108 - if (file->f_dentry->d_name.name[0] == '.' && !warned) { 109 - printk(KERN_INFO 110 - "Warning: \"%s\" uses deprecated NFSD interface: %s." 111 - " This will be removed in 2.6.40\n", 112 - current->comm, file->f_dentry->d_name.name); 113 - warned = 1; 114 - } 115 - #endif 116 133 if (! file->private_data) { 117 134 /* An attempt to read a transaction file without writing 118 135 * causes a 0-byte write so that the file can return ··· 189 226 * payload - write methods 190 227 */ 191 228 192 - #ifdef CONFIG_NFSD_DEPRECATED 193 - /** 194 - * write_svc - Start kernel's NFSD server 195 - * 196 - * Deprecated. /proc/fs/nfsd/threads is preferred. 197 - * Function remains to support old versions of nfs-utils. 198 - * 199 - * Input: 200 - * buf: struct nfsctl_svc 201 - * svc_port: port number of this 202 - * server's listener 203 - * svc_nthreads: number of threads to start 204 - * size: size in bytes of passed in nfsctl_svc 205 - * Output: 206 - * On success: returns zero 207 - * On error: return code is negative errno value 208 - */ 209 - static ssize_t write_svc(struct file *file, char *buf, size_t size) 210 - { 211 - struct nfsctl_svc *data; 212 - int err; 213 - if (size < sizeof(*data)) 214 - return -EINVAL; 215 - data = (struct nfsctl_svc*) buf; 216 - err = nfsd_svc(data->svc_port, data->svc_nthreads); 217 - if (err < 0) 218 - return err; 219 - return 0; 220 - } 221 - 222 - /** 223 - * write_add - Add or modify client entry in auth unix cache 224 - * 225 - * Deprecated. /proc/net/rpc/auth.unix.ip is preferred. 226 - * Function remains to support old versions of nfs-utils. 227 - * 228 - * Input: 229 - * buf: struct nfsctl_client 230 - * cl_ident: '\0'-terminated C string 231 - * containing domain name 232 - * of client 233 - * cl_naddr: no. of items in cl_addrlist 234 - * cl_addrlist: array of client addresses 235 - * cl_fhkeytype: ignored 236 - * cl_fhkeylen: ignored 237 - * cl_fhkey: ignored 238 - * size: size in bytes of passed in nfsctl_client 239 - * Output: 240 - * On success: returns zero 241 - * On error: return code is negative errno value 242 - * 243 - * Note: Only AF_INET client addresses are passed in, since 244 - * nfsctl_client.cl_addrlist contains only in_addr fields for addresses. 245 - */ 246 - static ssize_t write_add(struct file *file, char *buf, size_t size) 247 - { 248 - struct nfsctl_client *data; 249 - if (size < sizeof(*data)) 250 - return -EINVAL; 251 - data = (struct nfsctl_client *)buf; 252 - return exp_addclient(data); 253 - } 254 - 255 - /** 256 - * write_del - Remove client from auth unix cache 257 - * 258 - * Deprecated. /proc/net/rpc/auth.unix.ip is preferred. 259 - * Function remains to support old versions of nfs-utils. 260 - * 261 - * Input: 262 - * buf: struct nfsctl_client 263 - * cl_ident: '\0'-terminated C string 264 - * containing domain name 265 - * of client 266 - * cl_naddr: ignored 267 - * cl_addrlist: ignored 268 - * cl_fhkeytype: ignored 269 - * cl_fhkeylen: ignored 270 - * cl_fhkey: ignored 271 - * size: size in bytes of passed in nfsctl_client 272 - * Output: 273 - * On success: returns zero 274 - * On error: return code is negative errno value 275 - * 276 - * Note: Only AF_INET client addresses are passed in, since 277 - * nfsctl_client.cl_addrlist contains only in_addr fields for addresses. 278 - */ 279 - static ssize_t write_del(struct file *file, char *buf, size_t size) 280 - { 281 - struct nfsctl_client *data; 282 - if (size < sizeof(*data)) 283 - return -EINVAL; 284 - data = (struct nfsctl_client *)buf; 285 - return exp_delclient(data); 286 - } 287 - 288 - /** 289 - * write_export - Export part or all of a local file system 290 - * 291 - * Deprecated. /proc/net/rpc/{nfsd.export,nfsd.fh} are preferred. 292 - * Function remains to support old versions of nfs-utils. 293 - * 294 - * Input: 295 - * buf: struct nfsctl_export 296 - * ex_client: '\0'-terminated C string 297 - * containing domain name 298 - * of client allowed to access 299 - * this export 300 - * ex_path: '\0'-terminated C string 301 - * containing pathname of 302 - * directory in local file system 303 - * ex_dev: fsid to use for this export 304 - * ex_ino: ignored 305 - * ex_flags: export flags for this export 306 - * ex_anon_uid: UID to use for anonymous 307 - * requests 308 - * ex_anon_gid: GID to use for anonymous 309 - * requests 310 - * size: size in bytes of passed in nfsctl_export 311 - * Output: 312 - * On success: returns zero 313 - * On error: return code is negative errno value 314 - */ 315 - static ssize_t write_export(struct file *file, char *buf, size_t size) 316 - { 317 - struct nfsctl_export *data; 318 - if (size < sizeof(*data)) 319 - return -EINVAL; 320 - data = (struct nfsctl_export*)buf; 321 - return exp_export(data); 322 - } 323 - 324 - /** 325 - * write_unexport - Unexport a previously exported file system 326 - * 327 - * Deprecated. /proc/net/rpc/{nfsd.export,nfsd.fh} are preferred. 328 - * Function remains to support old versions of nfs-utils. 329 - * 330 - * Input: 331 - * buf: struct nfsctl_export 332 - * ex_client: '\0'-terminated C string 333 - * containing domain name 334 - * of client no longer allowed 335 - * to access this export 336 - * ex_path: '\0'-terminated C string 337 - * containing pathname of 338 - * directory in local file system 339 - * ex_dev: ignored 340 - * ex_ino: ignored 341 - * ex_flags: ignored 342 - * ex_anon_uid: ignored 343 - * ex_anon_gid: ignored 344 - * size: size in bytes of passed in nfsctl_export 345 - * Output: 346 - * On success: returns zero 347 - * On error: return code is negative errno value 348 - */ 349 - static ssize_t write_unexport(struct file *file, char *buf, size_t size) 350 - { 351 - struct nfsctl_export *data; 352 - 353 - if (size < sizeof(*data)) 354 - return -EINVAL; 355 - data = (struct nfsctl_export*)buf; 356 - return exp_unexport(data); 357 - } 358 - 359 - /** 360 - * write_getfs - Get a variable-length NFS file handle by path 361 - * 362 - * Deprecated. /proc/fs/nfsd/filehandle is preferred. 363 - * Function remains to support old versions of nfs-utils. 364 - * 365 - * Input: 366 - * buf: struct nfsctl_fsparm 367 - * gd_addr: socket address of client 368 - * gd_path: '\0'-terminated C string 369 - * containing pathname of 370 - * directory in local file system 371 - * gd_maxlen: maximum size of returned file 372 - * handle 373 - * size: size in bytes of passed in nfsctl_fsparm 374 - * Output: 375 - * On success: passed-in buffer filled with a knfsd_fh structure 376 - * (a variable-length raw NFS file handle); 377 - * return code is the size in bytes of the file handle 378 - * On error: return code is negative errno value 379 - * 380 - * Note: Only AF_INET client addresses are passed in, since gd_addr 381 - * is the same size as a struct sockaddr_in. 382 - */ 383 - static ssize_t write_getfs(struct file *file, char *buf, size_t size) 384 - { 385 - struct nfsctl_fsparm *data; 386 - struct sockaddr_in *sin; 387 - struct auth_domain *clp; 388 - int err = 0; 389 - struct knfsd_fh *res; 390 - struct in6_addr in6; 391 - 392 - if (size < sizeof(*data)) 393 - return -EINVAL; 394 - data = (struct nfsctl_fsparm*)buf; 395 - err = -EPROTONOSUPPORT; 396 - if (data->gd_addr.sa_family != AF_INET) 397 - goto out; 398 - sin = (struct sockaddr_in *)&data->gd_addr; 399 - if (data->gd_maxlen > NFS3_FHSIZE) 400 - data->gd_maxlen = NFS3_FHSIZE; 401 - 402 - res = (struct knfsd_fh*)buf; 403 - 404 - exp_readlock(); 405 - 406 - ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); 407 - 408 - clp = auth_unix_lookup(&init_net, &in6); 409 - if (!clp) 410 - err = -EPERM; 411 - else { 412 - err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); 413 - auth_domain_put(clp); 414 - } 415 - exp_readunlock(); 416 - if (err == 0) 417 - err = res->fh_size + offsetof(struct knfsd_fh, fh_base); 418 - out: 419 - return err; 420 - } 421 - 422 - /** 423 - * write_getfd - Get a fixed-length NFS file handle by path (used by mountd) 424 - * 425 - * Deprecated. /proc/fs/nfsd/filehandle is preferred. 426 - * Function remains to support old versions of nfs-utils. 427 - * 428 - * Input: 429 - * buf: struct nfsctl_fdparm 430 - * gd_addr: socket address of client 431 - * gd_path: '\0'-terminated C string 432 - * containing pathname of 433 - * directory in local file system 434 - * gd_version: fdparm structure version 435 - * size: size in bytes of passed in nfsctl_fdparm 436 - * Output: 437 - * On success: passed-in buffer filled with nfsctl_res 438 - * (a fixed-length raw NFS file handle); 439 - * return code is the size in bytes of the file handle 440 - * On error: return code is negative errno value 441 - * 442 - * Note: Only AF_INET client addresses are passed in, since gd_addr 443 - * is the same size as a struct sockaddr_in. 444 - */ 445 - static ssize_t write_getfd(struct file *file, char *buf, size_t size) 446 - { 447 - struct nfsctl_fdparm *data; 448 - struct sockaddr_in *sin; 449 - struct auth_domain *clp; 450 - int err = 0; 451 - struct knfsd_fh fh; 452 - char *res; 453 - struct in6_addr in6; 454 - 455 - if (size < sizeof(*data)) 456 - return -EINVAL; 457 - data = (struct nfsctl_fdparm*)buf; 458 - err = -EPROTONOSUPPORT; 459 - if (data->gd_addr.sa_family != AF_INET) 460 - goto out; 461 - err = -EINVAL; 462 - if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) 463 - goto out; 464 - 465 - res = buf; 466 - sin = (struct sockaddr_in *)&data->gd_addr; 467 - exp_readlock(); 468 - 469 - ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); 470 - 471 - clp = auth_unix_lookup(&init_net, &in6); 472 - if (!clp) 473 - err = -EPERM; 474 - else { 475 - err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); 476 - auth_domain_put(clp); 477 - } 478 - exp_readunlock(); 479 - 480 - if (err == 0) { 481 - memset(res,0, NFS_FHSIZE); 482 - memcpy(res, &fh.fh_base, fh.fh_size); 483 - err = NFS_FHSIZE; 484 - } 485 - out: 486 - return err; 487 - } 488 - #endif /* CONFIG_NFSD_DEPRECATED */ 489 229 490 230 /** 491 231 * write_unlock_ip - Release all locks used by a client ··· 1063 1397 static int nfsd_fill_super(struct super_block * sb, void * data, int silent) 1064 1398 { 1065 1399 static struct tree_descr nfsd_files[] = { 1066 - #ifdef CONFIG_NFSD_DEPRECATED 1067 - [NFSD_Svc] = {".svc", &transaction_ops, S_IWUSR}, 1068 - [NFSD_Add] = {".add", &transaction_ops, S_IWUSR}, 1069 - [NFSD_Del] = {".del", &transaction_ops, S_IWUSR}, 1070 - [NFSD_Export] = {".export", &transaction_ops, S_IWUSR}, 1071 - [NFSD_Unexport] = {".unexport", &transaction_ops, S_IWUSR}, 1072 - [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR}, 1073 - [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR}, 1074 - #endif 1075 1400 [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, 1076 1401 [NFSD_Export_features] = {"export_features", 1077 1402 &export_features_operations, S_IRUGO},
+15 -18
fs/nfsd/nfssvc.c
··· 528 528 continue; 529 529 } 530 530 531 - 532 - /* Lock the export hash tables for reading. */ 533 - exp_readlock(); 534 - 535 531 validate_process_creds(); 536 532 svc_process(rqstp); 537 533 validate_process_creds(); 538 - 539 - /* Unlock export hash tables */ 540 - exp_readunlock(); 541 534 } 542 535 543 536 /* Clear signals before calling svc_exit_thread() */ ··· 570 577 rqstp->rq_vers, rqstp->rq_proc); 571 578 proc = rqstp->rq_procinfo; 572 579 580 + /* 581 + * Give the xdr decoder a chance to change this if it wants 582 + * (necessary in the NFSv4.0 compound case) 583 + */ 584 + rqstp->rq_cachetype = proc->pc_cachetype; 585 + /* Decode arguments */ 586 + xdr = proc->pc_decode; 587 + if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base, 588 + rqstp->rq_argp)) { 589 + dprintk("nfsd: failed to decode arguments!\n"); 590 + *statp = rpc_garbage_args; 591 + return 1; 592 + } 593 + 573 594 /* Check whether we have this call in the cache. */ 574 - switch (nfsd_cache_lookup(rqstp, proc->pc_cachetype)) { 595 + switch (nfsd_cache_lookup(rqstp)) { 575 596 case RC_INTR: 576 597 case RC_DROPIT: 577 598 return 0; ··· 593 586 return 1; 594 587 case RC_DOIT:; 595 588 /* do it */ 596 - } 597 - 598 - /* Decode arguments */ 599 - xdr = proc->pc_decode; 600 - if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base, 601 - rqstp->rq_argp)) { 602 - dprintk("nfsd: failed to decode arguments!\n"); 603 - nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 604 - *statp = rpc_garbage_args; 605 - return 1; 606 589 } 607 590 608 591 /* need to grab the location to store the status, as
+1
fs/nfsd/state.h
··· 482 482 extern int nfsd4_create_clid_dir(struct nfs4_client *clp); 483 483 extern void nfsd4_remove_clid_dir(struct nfs4_client *clp); 484 484 extern void release_session_client(struct nfsd4_session *); 485 + extern __be32 nfs4_validate_stateid(stateid_t *, int); 485 486 486 487 static inline void 487 488 nfs4_put_stateowner(struct nfs4_stateowner *so)
+29 -1
fs/nfsd/xdr4.h
··· 342 342 nfs4_verifier sc_confirm; 343 343 }; 344 344 345 + struct nfsd4_saved_compoundargs { 346 + __be32 *p; 347 + __be32 *end; 348 + int pagelen; 349 + struct page **pagelist; 350 + }; 351 + 352 + struct nfsd4_test_stateid { 353 + __be32 ts_num_ids; 354 + __be32 ts_has_session; 355 + struct nfsd4_compoundargs *ts_saved_args; 356 + struct nfsd4_saved_compoundargs ts_savedp; 357 + }; 358 + 359 + struct nfsd4_free_stateid { 360 + stateid_t fr_stateid; /* request */ 361 + __be32 fr_status; /* response */ 362 + }; 363 + 345 364 /* also used for NVERIFY */ 346 365 struct nfsd4_verify { 347 366 u32 ve_bmval[3]; /* request */ ··· 451 432 struct nfsd4_destroy_session destroy_session; 452 433 struct nfsd4_sequence sequence; 453 434 struct nfsd4_reclaim_complete reclaim_complete; 435 + struct nfsd4_test_stateid test_stateid; 436 + struct nfsd4_free_stateid free_stateid; 454 437 } u; 455 438 struct nfs4_replay * replay; 456 439 }; 440 + 441 + bool nfsd4_cache_this_op(struct nfsd4_op *); 457 442 458 443 struct nfsd4_compoundargs { 459 444 /* scratch variables for XDR decode */ ··· 481 458 u32 opcnt; 482 459 struct nfsd4_op *ops; 483 460 struct nfsd4_op iops[8]; 461 + int cachetype; 484 462 }; 485 463 486 464 struct nfsd4_compoundres { ··· 583 559 nfsd4_release_lockowner(struct svc_rqst *rqstp, 584 560 struct nfsd4_compound_state *, 585 561 struct nfsd4_release_lockowner *rlockowner); 586 - extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); 562 + extern int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp); 587 563 extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, 588 564 struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); 589 565 extern __be32 nfsd4_renew(struct svc_rqst *rqstp, 590 566 struct nfsd4_compound_state *, clientid_t *clid); 567 + extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp, 568 + struct nfsd4_compound_state *, struct nfsd4_test_stateid *test_stateid); 569 + extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp, 570 + struct nfsd4_compound_state *, struct nfsd4_free_stateid *free_stateid); 591 571 #endif 592 572 593 573 /*
-9
include/linux/compat.h
··· 438 438 struct compat_timespec __user *tsp, 439 439 const compat_sigset_t __user *sigmask, 440 440 compat_size_t sigsetsize); 441 - #if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && \ 442 - !defined(CONFIG_NFSD_DEPRECATED) 443 - union compat_nfsctl_res; 444 - struct compat_nfsctl_arg; 445 - asmlinkage long compat_sys_nfsservctl(int cmd, 446 - struct compat_nfsctl_arg __user *arg, 447 - union compat_nfsctl_res __user *res); 448 - #else 449 441 asmlinkage long compat_sys_nfsservctl(int cmd, void *notused, void *notused2); 450 - #endif 451 442 asmlinkage long compat_sys_signalfd4(int ufd, 452 443 const compat_sigset_t __user *sigmask, 453 444 compat_size_t sigsetsize, int flags);
+6 -6
include/linux/fs.h
··· 1072 1072 }; 1073 1073 1074 1074 struct lock_manager_operations { 1075 - int (*fl_compare_owner)(struct file_lock *, struct file_lock *); 1076 - void (*fl_notify)(struct file_lock *); /* unblock callback */ 1077 - int (*fl_grant)(struct file_lock *, struct file_lock *, int); 1078 - void (*fl_release_private)(struct file_lock *); 1079 - void (*fl_break)(struct file_lock *); 1080 - int (*fl_change)(struct file_lock **, int); 1075 + int (*lm_compare_owner)(struct file_lock *, struct file_lock *); 1076 + void (*lm_notify)(struct file_lock *); /* unblock callback */ 1077 + int (*lm_grant)(struct file_lock *, struct file_lock *, int); 1078 + void (*lm_release_private)(struct file_lock *); 1079 + void (*lm_break)(struct file_lock *); 1080 + int (*lm_change)(struct file_lock **, int); 1081 1081 }; 1082 1082 1083 1083 struct lock_manager {
-2
include/linux/nfsd/export.h
··· 133 133 int nfsd_export_init(void); 134 134 void nfsd_export_shutdown(void); 135 135 void nfsd_export_flush(void); 136 - void exp_readlock(void); 137 - void exp_readunlock(void); 138 136 struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, 139 137 struct path *); 140 138 struct svc_export * rqst_exp_parent(struct svc_rqst *,
-9
include/linux/sunrpc/cache.h
··· 256 256 return rv - boot.tv_sec; 257 257 } 258 258 259 - #ifdef CONFIG_NFSD_DEPRECATED 260 - static 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 259 #endif /* _LINUX_SUNRPC_CACHE_H_ */
+1
include/linux/sunrpc/svc.h
··· 273 273 /* Catering to nfsd */ 274 274 struct auth_domain * rq_client; /* RPC peer info */ 275 275 struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ 276 + int rq_cachetype; 276 277 struct svc_cacherep * rq_cacherep; /* cache info */ 277 278 int rq_splice_ok; /* turned off in gss privacy 278 279 * to prevent encrypting page
+7
net/sunrpc/auth_gss/gss_krb5_mech.c
··· 744 744 }, 745 745 }; 746 746 747 + MODULE_ALIAS("rpc-auth-gss-krb5"); 748 + MODULE_ALIAS("rpc-auth-gss-krb5i"); 749 + MODULE_ALIAS("rpc-auth-gss-krb5p"); 750 + MODULE_ALIAS("rpc-auth-gss-390003"); 751 + MODULE_ALIAS("rpc-auth-gss-390004"); 752 + MODULE_ALIAS("rpc-auth-gss-390005"); 753 + 747 754 static struct gss_api_mech gss_kerberos_mech = { 748 755 .gm_name = "krb5", 749 756 .gm_owner = THIS_MODULE,
+28 -4
net/sunrpc/auth_gss/gss_mech_switch.c
··· 141 141 EXPORT_SYMBOL_GPL(gss_mech_get); 142 142 143 143 struct gss_api_mech * 144 - gss_mech_get_by_name(const char *name) 144 + _gss_mech_get_by_name(const char *name) 145 145 { 146 146 struct gss_api_mech *pos, *gm = NULL; 147 147 ··· 158 158 159 159 } 160 160 161 + struct gss_api_mech * gss_mech_get_by_name(const char *name) 162 + { 163 + struct gss_api_mech *gm = NULL; 164 + 165 + gm = _gss_mech_get_by_name(name); 166 + if (!gm) { 167 + request_module("rpc-auth-gss-%s", name); 168 + gm = _gss_mech_get_by_name(name); 169 + } 170 + return gm; 171 + } 161 172 EXPORT_SYMBOL_GPL(gss_mech_get_by_name); 162 173 163 174 struct gss_api_mech * ··· 205 194 return 0; 206 195 } 207 196 208 - struct gss_api_mech * 209 - gss_mech_get_by_pseudoflavor(u32 pseudoflavor) 197 + struct gss_api_mech *_gss_mech_get_by_pseudoflavor(u32 pseudoflavor) 210 198 { 211 - struct gss_api_mech *pos, *gm = NULL; 199 + struct gss_api_mech *gm = NULL, *pos; 212 200 213 201 spin_lock(&registered_mechs_lock); 214 202 list_for_each_entry(pos, &registered_mechs, gm_list) { ··· 220 210 break; 221 211 } 222 212 spin_unlock(&registered_mechs_lock); 213 + return gm; 214 + } 215 + 216 + struct gss_api_mech * 217 + gss_mech_get_by_pseudoflavor(u32 pseudoflavor) 218 + { 219 + struct gss_api_mech *gm; 220 + 221 + gm = _gss_mech_get_by_pseudoflavor(pseudoflavor); 222 + 223 + if (!gm) { 224 + request_module("rpc-auth-gss-%u", pseudoflavor); 225 + gm = _gss_mech_get_by_pseudoflavor(pseudoflavor); 226 + } 223 227 return gm; 224 228 } 225 229
+6 -5
net/sunrpc/svc_xprt.c
··· 902 902 if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) 903 903 list_del_init(&xprt->xpt_list); 904 904 /* 905 - * We used to delete the transport from whichever list 906 - * it's sk_xprt.xpt_ready node was on, but we don't actually 907 - * need to. This is because the only time we're called 908 - * while still attached to a queue, the queue itself 909 - * is about to be destroyed (in svc_destroy). 905 + * The only time we're called while xpt_ready is still on a list 906 + * is while the list itself is about to be destroyed (in 907 + * svc_destroy). BUT svc_xprt_enqueue could still be attempting 908 + * to add new entries to the sp_sockets list, so we can't leave 909 + * a freed xprt on it. 910 910 */ 911 + list_del_init(&xprt->xpt_ready); 911 912 if (test_bit(XPT_TEMP, &xprt->xpt_flags)) 912 913 serv->sv_tmpcnt--; 913 914 spin_unlock_bh(&serv->sv_lock);
+1 -78
net/sunrpc/svcauth_unix.c
··· 30 30 31 31 struct unix_domain { 32 32 struct auth_domain h; 33 - #ifdef CONFIG_NFSD_DEPRECATED 34 - int addr_changes; 35 - #endif /* CONFIG_NFSD_DEPRECATED */ 36 33 /* other stuff later */ 37 34 }; 38 35 36 + extern struct auth_ops svcauth_null; 39 37 extern struct auth_ops svcauth_unix; 40 38 41 39 static void svcauth_unix_domain_release(struct auth_domain *dom) ··· 72 74 return NULL; 73 75 } 74 76 new->h.flavour = &svcauth_unix; 75 - #ifdef CONFIG_NFSD_DEPRECATED 76 - new->addr_changes = 0; 77 - #endif /* CONFIG_NFSD_DEPRECATED */ 78 77 rv = auth_domain_lookup(name, &new->h); 79 78 } 80 79 } ··· 90 95 char m_class[8]; /* e.g. "nfsd" */ 91 96 struct in6_addr m_addr; 92 97 struct unix_domain *m_client; 93 - #ifdef CONFIG_NFSD_DEPRECATED 94 - int m_add_change; 95 - #endif /* CONFIG_NFSD_DEPRECATED */ 96 98 }; 97 99 98 100 static void ip_map_put(struct kref *kref) ··· 143 151 144 152 kref_get(&item->m_client->h.ref); 145 153 new->m_client = item->m_client; 146 - #ifdef CONFIG_NFSD_DEPRECATED 147 - new->m_add_change = item->m_add_change; 148 - #endif /* CONFIG_NFSD_DEPRECATED */ 149 154 } 150 155 static struct cache_head *ip_map_alloc(void) 151 156 { ··· 327 338 ip.h.flags = 0; 328 339 if (!udom) 329 340 set_bit(CACHE_NEGATIVE, &ip.h.flags); 330 - #ifdef CONFIG_NFSD_DEPRECATED 331 - else { 332 - ip.m_add_change = udom->addr_changes; 333 - /* if this is from the legacy set_client system call, 334 - * we need m_add_change to be one higher 335 - */ 336 - if (expiry == NEVER) 337 - ip.m_add_change++; 338 - } 339 - #endif /* CONFIG_NFSD_DEPRECATED */ 340 341 ip.h.expiry_time = expiry; 341 342 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, 342 343 hash_str(ipm->m_class, IP_HASHBITS) ^ ··· 346 367 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); 347 368 } 348 369 349 - #ifdef CONFIG_NFSD_DEPRECATED 350 - int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) 351 - { 352 - struct unix_domain *udom; 353 - struct ip_map *ipmp; 354 - 355 - if (dom->flavour != &svcauth_unix) 356 - return -EINVAL; 357 - udom = container_of(dom, struct unix_domain, h); 358 - ipmp = ip_map_lookup(net, "nfsd", addr); 359 - 360 - if (ipmp) 361 - return ip_map_update(net, ipmp, udom, NEVER); 362 - else 363 - return -ENOMEM; 364 - } 365 - EXPORT_SYMBOL_GPL(auth_unix_add_addr); 366 - 367 - int auth_unix_forget_old(struct auth_domain *dom) 368 - { 369 - struct unix_domain *udom; 370 - 371 - if (dom->flavour != &svcauth_unix) 372 - return -EINVAL; 373 - udom = container_of(dom, struct unix_domain, h); 374 - udom->addr_changes++; 375 - return 0; 376 - } 377 - EXPORT_SYMBOL_GPL(auth_unix_forget_old); 378 - 379 - struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr) 380 - { 381 - struct ip_map *ipm; 382 - struct auth_domain *rv; 383 - struct sunrpc_net *sn; 384 - 385 - sn = net_generic(net, sunrpc_net_id); 386 - ipm = ip_map_lookup(net, "nfsd", addr); 387 - 388 - if (!ipm) 389 - return NULL; 390 - if (cache_check(sn->ip_map_cache, &ipm->h, NULL)) 391 - return NULL; 392 - 393 - if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { 394 - sunrpc_invalidate(&ipm->h, sn->ip_map_cache); 395 - rv = NULL; 396 - } else { 397 - rv = &ipm->m_client->h; 398 - kref_get(&rv->ref); 399 - } 400 - cache_put(&ipm->h, sn->ip_map_cache); 401 - return rv; 402 - } 403 - EXPORT_SYMBOL_GPL(auth_unix_lookup); 404 - #endif /* CONFIG_NFSD_DEPRECATED */ 405 370 406 371 void svcauth_unix_purge(void) 407 372 {
+2
net/sunrpc/svcsock.c
··· 51 51 #include <linux/sunrpc/stats.h> 52 52 #include <linux/sunrpc/xprt.h> 53 53 54 + #include "sunrpc.h" 55 + 54 56 #define RPCDBG_FACILITY RPCDBG_SVCXPRT 55 57 56 58