Pull NFS client updates from Trond Myklebust: "Bugfixes: - Fix 'nlink' attribute update races when unlinking a file - Add missing initialisers for the directory verifier in various places - Don't regress the NFSv4 open state due to misordered racing replies - Ensure the NFSv4.x callback server uses the correct transport connection - Fix potential use-after-free races when shutting down the NFSv4.x callback server - Fix a pNFS layout commit crash - Assorted fixes to ensure correct propagation of mount options when the client crosses a filesystem boundary and triggers the VFS automount code - More localio fixes Features and cleanups: - Add initial support for basic directory delegations - SunRPC back channel code cleanups" * tag 'nfs-for-6.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (24 commits) NFSv4: Handle NFS4ERR_NOTSUPP errors for directory delegations nfs/localio: remove 61 byte hole from needless ____cacheline_aligned nfs/localio: remove alignment size checking in nfs_is_local_dio_possible NFS: Fix up the automount fs_context to use the correct cred NFS: Fix inheritance of the block sizes when automounting NFS: Automounted filesystems should inherit ro,noexec,nodev,sync flags Revert "nfs: ignore SB_RDONLY when mounting nfs" Revert "nfs: clear SB_RDONLY before getting superblock" Revert "nfs: ignore SB_RDONLY when remounting nfs" NFS: Add a module option to disable directory delegations NFS: Shortcut lookup revalidations if we have a directory delegation NFS: Request a directory delegation during RENAME NFS: Request a directory delegation on ACCESS, CREATE, and UNLINK NFS: Add support for sending GDD_GETATTR NFSv4/pNFS: Clear NFS_INO_LAYOUTCOMMIT in pnfs_mark_layout_stateid_invalid NFSv4.1: protect destroying and nullifying bc_serv structure SUNRPC: new helper function for stopping backchannel server SUNRPC: cleanup common code in backchannel request NFSv4.1: pass transport for callback shutdown NFSv4: ensure the open stateid seqid doesn't go backwards ...
Unified · Split
| @@ -258,7 +258,7 @@ err_start: · 257 unmodified lines | |||
| 258 | /* | 258 | /* |
| 259 | * Kill the callback thread if it's no longer being used. | 259 | * Kill the callback thread if it's no longer being used. |
| 260 | */ | 260 | */ |
| 261 | void nfs_callback_down(int minorversion, struct net *net) | 261 | void nfs_callback_down(int minorversion, struct net *net, struct rpc_xprt *xprt) |
| 262 | { | 262 | { |
| 263 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; | 263 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; |
| 264 | struct svc_serv *serv; | 264 | struct svc_serv *serv; |
| @@ -270,7 +270,7 @@ void nfs_callback_down(int minorversion, struct net *net) · 5 unmodified lines | |||
| 270 | if (cb_info->users == 0) { | 270 | if (cb_info->users == 0) { |
| 271 | svc_set_num_threads(serv, NULL, 0); | 271 | svc_set_num_threads(serv, NULL, 0); |
| 272 | dprintk("nfs_callback_down: service destroyed\n"); | 272 | dprintk("nfs_callback_down: service destroyed\n"); |
| 273 | svc_destroy(&cb_info->serv); | 273 | xprt_svc_destroy_nullify_bc(xprt, &cb_info->serv); |
| 274 | } | 274 | } |
| 275 | mutex_unlock(&nfs_callback_mutex); | 275 | mutex_unlock(&nfs_callback_mutex); |
| 276 | } | 276 | } |
| @@ -188,7 +188,8 @@ extern __be32 nfs4_callback_recall(void *argp, void *resp, · 187 unmodified lines | |||
| 188 | struct cb_process_state *cps); | 188 | struct cb_process_state *cps); |
| 189 | #if IS_ENABLED(CONFIG_NFS_V4) | 189 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 190 | extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); | 190 | extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); |
| 191 | extern void nfs_callback_down(int minorversion, struct net *net); | 191 | extern void nfs_callback_down(int minorversion, struct net *net, |
| 192 | struct rpc_xprt *xprt); | ||
| 192 | #endif /* CONFIG_NFS_V4 */ | 193 | #endif /* CONFIG_NFS_V4 */ |
| 193 | /* | 194 | /* |
| 194 | * nfs41: Callbacks are expected to not cause substantial latency, | 195 | * nfs41: Callbacks are expected to not cause substantial latency, |
| @@ -784,10 +784,18 @@ static int nfs_init_server(struct nfs_server *server, · 783 unmodified lines | |||
| 784 | server->fattr_valid = NFS_ATTR_FATTR_V4; | 784 | server->fattr_valid = NFS_ATTR_FATTR_V4; |
| 785 | } | 785 | } |
| 786 | 786 | ||
| 787 | if (ctx->rsize) | 787 | if (ctx->bsize) { |
| 788 | server->bsize = ctx->bsize; | ||
| 789 | server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_BSIZE; | ||
| 790 | } | ||
| 791 | if (ctx->rsize) { | ||
| 788 | server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto); | 792 | server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto); |
| 789 | if (ctx->wsize) | 793 | server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_RSIZE; |
| 794 | } | ||
| 795 | if (ctx->wsize) { | ||
| 790 | server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto); | 796 | server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto); |
| 797 | server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_WSIZE; | ||
| 798 | } | ||
| 791 | 799 | ||
| 792 | server->acregmin = ctx->acregmin * HZ; | 800 | server->acregmin = ctx->acregmin * HZ; |
| 793 | server->acregmax = ctx->acregmax * HZ; | 801 | server->acregmax = ctx->acregmax * HZ; |
| @@ -977,8 +985,13 @@ EXPORT_SYMBOL_GPL(nfs_probe_server); · 183 unmodified lines | |||
| 977 | void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) | 985 | void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) |
| 978 | { | 986 | { |
| 979 | target->flags = source->flags; | 987 | target->flags = source->flags; |
| 980 | target->rsize = source->rsize; | 988 | target->automount_inherit = source->automount_inherit; |
| 981 | target->wsize = source->wsize; | 989 | if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_BSIZE) |
| 990 | target->bsize = source->bsize; | ||
| 991 | if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_RSIZE) | ||
| 992 | target->rsize = source->rsize; | ||
| 993 | if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_WSIZE) | ||
| 994 | target->wsize = source->wsize; | ||
| 982 | target->acregmin = source->acregmin; | 995 | target->acregmin = source->acregmin; |
| 983 | target->acregmax = source->acregmax; | 996 | target->acregmax = source->acregmax; |
| 984 | target->acdirmin = source->acdirmin; | 997 | target->acdirmin = source->acdirmin; |
| @@ -30,6 +30,11 @@ · 29 unmodified lines | |||
| 30 | static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK; | 30 | static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK; |
| 31 | module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644); | 31 | module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644); |
| 32 | 32 | ||
| 33 | bool directory_delegations = true; | ||
| 34 | module_param(directory_delegations, bool, 0644); | ||
| 35 | MODULE_PARM_DESC(directory_delegations, | ||
| 36 | "Enable the use of directory delegations, defaults to on."); | ||
| 37 | |||
| 33 | static struct hlist_head *nfs_delegation_hash(struct nfs_server *server, | 38 | static struct hlist_head *nfs_delegation_hash(struct nfs_server *server, |
| 34 | const struct nfs_fh *fhandle) | 39 | const struct nfs_fh *fhandle) |
| 35 | { | 40 | { |
| @@ -143,6 +148,8 @@ static int nfs4_do_check_delegation(struct inode *inode, fmode_t type, · 107 unmodified lines | |||
| 143 | */ | 148 | */ |
| 144 | int nfs4_have_delegation(struct inode *inode, fmode_t type, int flags) | 149 | int nfs4_have_delegation(struct inode *inode, fmode_t type, int flags) |
| 145 | { | 150 | { |
| 151 | if (S_ISDIR(inode->i_mode) && !directory_delegations) | ||
| 152 | nfs_inode_evict_delegation(inode); | ||
| 146 | return nfs4_do_check_delegation(inode, type, flags, true); | 153 | return nfs4_do_check_delegation(inode, type, flags, true); |
| 147 | } | 154 | } |
| 148 | 155 | ||
| @@ -379,6 +386,7 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi, · 230 unmodified lines | |||
| 379 | delegation->inode = NULL; | 386 | delegation->inode = NULL; |
| 380 | rcu_assign_pointer(nfsi->delegation, NULL); | 387 | rcu_assign_pointer(nfsi->delegation, NULL); |
| 381 | spin_unlock(&delegation->lock); | 388 | spin_unlock(&delegation->lock); |
| 389 | clear_bit(NFS_INO_REQ_DIR_DELEG, &nfsi->flags); | ||
| 382 | return delegation; | 390 | return delegation; |
| 383 | } | 391 | } |
| 384 | 392 | ||
| @@ -124,6 +124,19 @@ static inline int nfs_have_delegated_mtime(struct inode *inode) · 123 unmodified lines | |||
| 124 | NFS_DELEGATION_FLAG_TIME); | 124 | NFS_DELEGATION_FLAG_TIME); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | extern bool directory_delegations; | ||
| 128 | |||
| 129 | static inline void nfs_request_directory_delegation(struct inode *inode) | ||
| 130 | { | ||
| 131 | if (S_ISDIR(inode->i_mode)) | ||
| 132 | set_bit(NFS_INO_REQ_DIR_DELEG, &NFS_I(inode)->flags); | ||
| 133 | } | ||
| 134 | |||
| 135 | static inline bool nfs_have_directory_delegation(struct inode *inode) | ||
| 136 | { | ||
| 137 | return S_ISDIR(inode->i_mode) && nfs_have_delegated_attributes(inode); | ||
| 138 | } | ||
| 139 | |||
| 127 | int nfs4_delegation_hash_alloc(struct nfs_server *server); | 140 | int nfs4_delegation_hash_alloc(struct nfs_server *server); |
| 128 | 141 | ||
| 129 | #endif | 142 | #endif |
| @@ -789,16 +789,17 @@ again: · 788 unmodified lines | |||
| 789 | goto out; | 789 | goto out; |
| 790 | } | 790 | } |
| 791 | 791 | ||
| 792 | nfs_set_verifier(dentry, dir_verifier); | ||
| 792 | inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); | 793 | inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); |
| 793 | alias = d_splice_alias(inode, dentry); | 794 | alias = d_splice_alias(inode, dentry); |
| 794 | d_lookup_done(dentry); | 795 | d_lookup_done(dentry); |
| 795 | if (alias) { | 796 | if (alias) { |
| 796 | if (IS_ERR(alias)) | 797 | if (IS_ERR(alias)) |
| 797 | goto out; | 798 | goto out; |
| 799 | nfs_set_verifier(alias, dir_verifier); | ||
| 798 | dput(dentry); | 800 | dput(dentry); |
| 799 | dentry = alias; | 801 | dentry = alias; |
| 800 | } | 802 | } |
| 801 | nfs_set_verifier(dentry, dir_verifier); | ||
| 802 | trace_nfs_readdir_lookup(d_inode(parent), dentry, 0); | 803 | trace_nfs_readdir_lookup(d_inode(parent), dentry, 0); |
| 803 | out: | 804 | out: |
| 804 | dput(dentry); | 805 | dput(dentry); |
| @@ -1514,6 +1515,15 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry, · 709 unmodified lines | |||
| 1514 | return 0; | 1515 | return 0; |
| 1515 | if (!nfs_dentry_verify_change(dir, dentry)) | 1516 | if (!nfs_dentry_verify_change(dir, dentry)) |
| 1516 | return 0; | 1517 | return 0; |
| 1518 | |||
| 1519 | /* | ||
| 1520 | * If we have a directory delegation then we don't need to revalidate | ||
| 1521 | * the directory. The delegation will either get recalled or we will | ||
| 1522 | * receive a notification when it changes. | ||
| 1523 | */ | ||
| 1524 | if (nfs_have_directory_delegation(dir)) | ||
| 1525 | return 0; | ||
| 1526 | |||
| 1517 | /* Revalidate nfsi->cache_change_attribute before we declare a match */ | 1527 | /* Revalidate nfsi->cache_change_attribute before we declare a match */ |
| 1518 | if (nfs_mapping_need_revalidate_inode(dir)) { | 1528 | if (nfs_mapping_need_revalidate_inode(dir)) { |
| 1519 | if (rcu_walk) | 1529 | if (rcu_walk) |
| @@ -1894,13 +1904,15 @@ static int nfs_dentry_delete(const struct dentry *dentry) · 374 unmodified lines | |||
| 1894 | } | 1904 | } |
| 1895 | 1905 | ||
| 1896 | /* Ensure that we revalidate inode->i_nlink */ | 1906 | /* Ensure that we revalidate inode->i_nlink */ |
| 1897 | static void nfs_drop_nlink(struct inode *inode) | 1907 | static void nfs_drop_nlink(struct inode *inode, unsigned long gencount) |
| 1898 | { | 1908 | { |
| 1909 | struct nfs_inode *nfsi = NFS_I(inode); | ||
| 1910 | |||
| 1899 | spin_lock(&inode->i_lock); | 1911 | spin_lock(&inode->i_lock); |
| 1900 | /* drop the inode if we're reasonably sure this is the last link */ | 1912 | /* drop the inode if we're reasonably sure this is the last link */ |
| 1901 | if (inode->i_nlink > 0) | 1913 | if (inode->i_nlink > 0 && gencount == nfsi->attr_gencount) |
| 1902 | drop_nlink(inode); | 1914 | drop_nlink(inode); |
| 1903 | NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter(); | 1915 | nfsi->attr_gencount = nfs_inc_attr_generation_counter(); |
| 1904 | nfs_set_cache_invalid( | 1916 | nfs_set_cache_invalid( |
| 1905 | inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | | 1917 | inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | |
| 1906 | NFS_INO_INVALID_NLINK); | 1918 | NFS_INO_INVALID_NLINK); |
| @@ -1914,8 +1926,9 @@ static void nfs_drop_nlink(struct inode *inode) · 7 unmodified lines | |||
| 1914 | static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) | 1926 | static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) |
| 1915 | { | 1927 | { |
| 1916 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { | 1928 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { |
| 1929 | unsigned long gencount = READ_ONCE(NFS_I(inode)->attr_gencount); | ||
| 1917 | nfs_complete_unlink(dentry, inode); | 1930 | nfs_complete_unlink(dentry, inode); |
| 1918 | nfs_drop_nlink(inode); | 1931 | nfs_drop_nlink(inode, gencount); |
| 1919 | } | 1932 | } |
| 1920 | iput(inode); | 1933 | iput(inode); |
| 1921 | } | 1934 | } |
| @@ -1991,13 +2004,14 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in · 69 unmodified lines | |||
| 1991 | nfs_lookup_advise_force_readdirplus(dir, flags); | 2004 | nfs_lookup_advise_force_readdirplus(dir, flags); |
| 1992 | 2005 | ||
| 1993 | no_entry: | 2006 | no_entry: |
| 2007 | nfs_set_verifier(dentry, dir_verifier); | ||
| 1994 | res = d_splice_alias(inode, dentry); | 2008 | res = d_splice_alias(inode, dentry); |
| 1995 | if (res != NULL) { | 2009 | if (res != NULL) { |
| 1996 | if (IS_ERR(res)) | 2010 | if (IS_ERR(res)) |
| 1997 | goto out; | 2011 | goto out; |
| 2012 | nfs_set_verifier(res, dir_verifier); | ||
| 1998 | dentry = res; | 2013 | dentry = res; |
| 1999 | } | 2014 | } |
| 2000 | nfs_set_verifier(dentry, dir_verifier); | ||
| 2001 | out: | 2015 | out: |
| 2002 | trace_nfs_lookup_exit(dir, dentry, flags, PTR_ERR_OR_ZERO(res)); | 2016 | trace_nfs_lookup_exit(dir, dentry, flags, PTR_ERR_OR_ZERO(res)); |
| 2003 | nfs_free_fattr(fattr); | 2017 | nfs_free_fattr(fattr); |
| @@ -2139,12 +2153,12 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, · 135 unmodified lines | |||
| 2139 | d_drop(dentry); | 2153 | d_drop(dentry); |
| 2140 | switch (err) { | 2154 | switch (err) { |
| 2141 | case -ENOENT: | 2155 | case -ENOENT: |
| 2142 | d_splice_alias(NULL, dentry); | ||
| 2143 | if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE)) | 2156 | if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE)) |
| 2144 | dir_verifier = inode_peek_iversion_raw(dir); | 2157 | dir_verifier = inode_peek_iversion_raw(dir); |
| 2145 | else | 2158 | else |
| 2146 | dir_verifier = nfs_save_change_attribute(dir); | 2159 | dir_verifier = nfs_save_change_attribute(dir); |
| 2147 | nfs_set_verifier(dentry, dir_verifier); | 2160 | nfs_set_verifier(dentry, dir_verifier); |
| 2161 | d_splice_alias(NULL, dentry); | ||
| 2148 | break; | 2162 | break; |
| 2149 | case -EISDIR: | 2163 | case -EISDIR: |
| 2150 | case -ENOTDIR: | 2164 | case -ENOTDIR: |
| @@ -2202,6 +2216,13 @@ no_open: · 51 unmodified lines | |||
| 2202 | } | 2216 | } |
| 2203 | EXPORT_SYMBOL_GPL(nfs_atomic_open); | 2217 | EXPORT_SYMBOL_GPL(nfs_atomic_open); |
| 2204 | 2218 | ||
| 2219 | static int | ||
| 2220 | nfs_lookup_revalidate_delegated_parent(struct inode *dir, struct dentry *dentry, | ||
| 2221 | struct inode *inode) | ||
| 2222 | { | ||
| 2223 | return nfs_lookup_revalidate_done(dir, dentry, inode, 1); | ||
| 2224 | } | ||
| 2225 | |||
| 2205 | static int | 2226 | static int |
| 2206 | nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name, | 2227 | nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name, |
| 2207 | struct dentry *dentry, unsigned int flags) | 2228 | struct dentry *dentry, unsigned int flags) |
| @@ -2229,6 +2250,9 @@ nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name, · 21 unmodified lines | |||
| 2229 | if (nfs_verifier_is_delegated(dentry)) | 2250 | if (nfs_verifier_is_delegated(dentry)) |
| 2230 | return nfs_lookup_revalidate_delegated(dir, dentry, inode); | 2251 | return nfs_lookup_revalidate_delegated(dir, dentry, inode); |
| 2231 | 2252 | ||
| 2253 | if (nfs_have_directory_delegation(dir)) | ||
| 2254 | return nfs_lookup_revalidate_delegated_parent(dir, dentry, inode); | ||
| 2255 | |||
| 2232 | /* NFS only supports OPEN on regular files */ | 2256 | /* NFS only supports OPEN on regular files */ |
| 2233 | if (!S_ISREG(inode->i_mode)) | 2257 | if (!S_ISREG(inode->i_mode)) |
| 2234 | goto full_reval; | 2258 | goto full_reval; |
| @@ -2507,9 +2531,11 @@ static int nfs_safe_remove(struct dentry *dentry) · 272 unmodified lines | |||
| 2507 | 2531 | ||
| 2508 | trace_nfs_remove_enter(dir, dentry); | 2532 | trace_nfs_remove_enter(dir, dentry); |
| 2509 | if (inode != NULL) { | 2533 | if (inode != NULL) { |
| 2534 | unsigned long gencount = READ_ONCE(NFS_I(inode)->attr_gencount); | ||
| 2535 | |||
| 2510 | error = NFS_PROTO(dir)->remove(dir, dentry); | 2536 | error = NFS_PROTO(dir)->remove(dir, dentry); |
| 2511 | if (error == 0) | 2537 | if (error == 0) |
| 2512 | nfs_drop_nlink(inode); | 2538 | nfs_drop_nlink(inode, gencount); |
| 2513 | } else | 2539 | } else |
| 2514 | error = NFS_PROTO(dir)->remove(dir, dentry); | 2540 | error = NFS_PROTO(dir)->remove(dir, dentry); |
| 2515 | if (error == -ENOENT) | 2541 | if (error == -ENOENT) |
| @@ -2709,6 +2735,7 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, · 193 unmodified lines | |||
| 2709 | { | 2735 | { |
| 2710 | struct inode *old_inode = d_inode(old_dentry); | 2736 | struct inode *old_inode = d_inode(old_dentry); |
| 2711 | struct inode *new_inode = d_inode(new_dentry); | 2737 | struct inode *new_inode = d_inode(new_dentry); |
| 2738 | unsigned long new_gencount = 0; | ||
| 2712 | struct dentry *dentry = NULL; | 2739 | struct dentry *dentry = NULL; |
| 2713 | struct rpc_task *task; | 2740 | struct rpc_task *task; |
| 2714 | bool must_unblock = false; | 2741 | bool must_unblock = false; |
| @@ -2761,6 +2788,7 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, · 46 unmodified lines | |||
| 2761 | } else { | 2788 | } else { |
| 2762 | block_revalidate(new_dentry); | 2789 | block_revalidate(new_dentry); |
| 2763 | must_unblock = true; | 2790 | must_unblock = true; |
| 2791 | new_gencount = NFS_I(new_inode)->attr_gencount; | ||
| 2764 | spin_unlock(&new_dentry->d_lock); | 2792 | spin_unlock(&new_dentry->d_lock); |
| 2765 | } | 2793 | } |
| 2766 | 2794 | ||
| @@ -2800,7 +2828,7 @@ out: · 33 unmodified lines | |||
| 2800 | new_dir, new_dentry, error); | 2828 | new_dir, new_dentry, error); |
| 2801 | if (!error) { | 2829 | if (!error) { |
| 2802 | if (new_inode != NULL) | 2830 | if (new_inode != NULL) |
| 2803 | nfs_drop_nlink(new_inode); | 2831 | nfs_drop_nlink(new_inode, new_gencount); |
| 2804 | /* | 2832 | /* |
| 2805 | * The d_move() should be here instead of in an async RPC completion | 2833 | * The d_move() should be here instead of in an async RPC completion |
| 2806 | * handler because we need the proper locks to move the dentry. If | 2834 | * handler because we need the proper locks to move the dentry. If |
| @@ -1389,6 +1389,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) · 1388 unmodified lines | |||
| 1389 | status = pnfs_sync_inode(inode, false); | 1389 | status = pnfs_sync_inode(inode, false); |
| 1390 | if (status) | 1390 | if (status) |
| 1391 | goto out; | 1391 | goto out; |
| 1392 | } else if (nfs_have_directory_delegation(inode)) { | ||
| 1393 | status = 0; | ||
| 1394 | goto out; | ||
| 1392 | } | 1395 | } |
| 1393 | 1396 | ||
| 1394 | status = -ENOMEM; | 1397 | status = -ENOMEM; |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/nfslocalio.h> | 13 | #include <linux/nfslocalio.h> |
| 14 | #include <linux/wait_bit.h> | 14 | #include <linux/wait_bit.h> |
| 15 | 15 | ||
| 16 | #define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) | 16 | #define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) |
| 17 | 17 | ||
| 18 | extern const struct export_operations nfs_export_ops; | 18 | extern const struct export_operations nfs_export_ops; |
| 19 | 19 | ||
| @@ -152,7 +152,6 @@ struct nfs_fs_context { · 132 unmodified lines | |||
| 152 | struct super_block *sb; | 152 | struct super_block *sb; |
| 153 | struct dentry *dentry; | 153 | struct dentry *dentry; |
| 154 | struct nfs_fattr *fattr; | 154 | struct nfs_fattr *fattr; |
| 155 | unsigned int inherited_bsize; | ||
| 156 | } clone_data; | 155 | } clone_data; |
| 157 | }; | 156 | }; |
| 158 | 157 | ||
| @@ -43,8 +43,8 @@ struct nfs_local_kiocb { · 42 unmodified lines | |||
| 43 | size_t end_len; | 43 | size_t end_len; |
| 44 | short int end_iter_index; | 44 | short int end_iter_index; |
| 45 | atomic_t n_iters; | 45 | atomic_t n_iters; |
| 46 | struct iov_iter iters[NFSLOCAL_MAX_IOS]; | ||
| 46 | bool iter_is_dio_aligned[NFSLOCAL_MAX_IOS]; | 47 | bool iter_is_dio_aligned[NFSLOCAL_MAX_IOS]; |
| 47 | struct iov_iter iters[NFSLOCAL_MAX_IOS] ____cacheline_aligned; | ||
| 48 | /* End mostly DIO-specific members */ | 48 | /* End mostly DIO-specific members */ |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| @@ -339,8 +339,6 @@ nfs_is_local_dio_possible(struct nfs_local_kiocb *iocb, int rw, · 288 unmodified lines | |||
| 339 | 339 | ||
| 340 | if (unlikely(!nf_dio_mem_align || !nf_dio_offset_align)) | 340 | if (unlikely(!nf_dio_mem_align || !nf_dio_offset_align)) |
| 341 | return false; | 341 | return false; |
| 342 | if (unlikely(nf_dio_offset_align > PAGE_SIZE)) | ||
| 343 | return false; | ||
| 344 | if (unlikely(len < nf_dio_offset_align)) | 342 | if (unlikely(len < nf_dio_offset_align)) |
| 345 | return false; | 343 | return false; |
| 346 | 344 | ||
| @@ -149,6 +149,7 @@ struct vfsmount *nfs_d_automount(struct path *path) · 148 unmodified lines | |||
| 149 | struct vfsmount *mnt = ERR_PTR(-ENOMEM); | 149 | struct vfsmount *mnt = ERR_PTR(-ENOMEM); |
| 150 | struct nfs_server *server = NFS_SB(path->dentry->d_sb); | 150 | struct nfs_server *server = NFS_SB(path->dentry->d_sb); |
| 151 | struct nfs_client *client = server->nfs_client; | 151 | struct nfs_client *client = server->nfs_client; |
| 152 | unsigned long s_flags = path->dentry->d_sb->s_flags; | ||
| 152 | int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout); | 153 | int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout); |
| 153 | int ret; | 154 | int ret; |
| 154 | 155 | ||
| @@ -169,11 +170,21 @@ struct vfsmount *nfs_d_automount(struct path *path) · 14 unmodified lines | |||
| 169 | if (!ctx->clone_data.fattr) | 170 | if (!ctx->clone_data.fattr) |
| 170 | goto out_fc; | 171 | goto out_fc; |
| 171 | 172 | ||
| 173 | if (fc->cred != server->cred) { | ||
| 174 | put_cred(fc->cred); | ||
| 175 | fc->cred = get_cred(server->cred); | ||
| 176 | } | ||
| 177 | |||
| 172 | if (fc->net_ns != client->cl_net) { | 178 | if (fc->net_ns != client->cl_net) { |
| 173 | put_net(fc->net_ns); | 179 | put_net(fc->net_ns); |
| 174 | fc->net_ns = get_net(client->cl_net); | 180 | fc->net_ns = get_net(client->cl_net); |
| 175 | } | 181 | } |
| 176 | 182 | ||
| 183 | /* Inherit the flags covered by NFS_SB_MASK */ | ||
| 184 | fc->sb_flags_mask |= NFS_SB_MASK; | ||
| 185 | fc->sb_flags &= ~NFS_SB_MASK; | ||
| 186 | fc->sb_flags |= s_flags & NFS_SB_MASK; | ||
| 187 | |||
| 177 | /* for submounts we want the same server; referrals will reassign */ | 188 | /* for submounts we want the same server; referrals will reassign */ |
| 178 | memcpy(&ctx->nfs_server._address, &client->cl_addr, client->cl_addrlen); | 189 | memcpy(&ctx->nfs_server._address, &client->cl_addr, client->cl_addrlen); |
| 179 | ctx->nfs_server.addrlen = client->cl_addrlen; | 190 | ctx->nfs_server.addrlen = client->cl_addrlen; |
| @@ -184,6 +195,10 @@ struct vfsmount *nfs_d_automount(struct path *path) · 4 unmodified lines | |||
| 184 | ctx->nfs_mod = client->cl_nfs_mod; | 195 | ctx->nfs_mod = client->cl_nfs_mod; |
| 185 | get_nfs_version(ctx->nfs_mod); | 196 | get_nfs_version(ctx->nfs_mod); |
| 186 | 197 | ||
| 198 | /* Inherit block sizes if they were specified as mount parameters */ | ||
| 199 | if (server->automount_inherit & NFS_AUTOMOUNT_INHERIT_BSIZE) | ||
| 200 | ctx->bsize = server->bsize; | ||
| 201 | |||
| 187 | ret = client->rpc_ops->submount(fc, server); | 202 | ret = client->rpc_ops->submount(fc, server); |
| 188 | if (ret < 0) { | 203 | if (ret < 0) { |
| 189 | mnt = ERR_PTR(ret); | 204 | mnt = ERR_PTR(ret); |
| @@ -283,7 +298,6 @@ int nfs_do_submount(struct fs_context *fc) · 93 unmodified lines | |||
| 283 | return -ENOMEM; | 298 | return -ENOMEM; |
| 284 | 299 | ||
| 285 | ctx->internal = true; | 300 | ctx->internal = true; |
| 286 | ctx->clone_data.inherited_bsize = ctx->clone_data.sb->s_blocksize_bits; | ||
| 287 | 301 | ||
| 288 | p = nfs_devname(dentry, buffer, 4096); | 302 | p = nfs_devname(dentry, buffer, 4096); |
| 289 | if (IS_ERR(p)) { | 303 | if (IS_ERR(p)) { |
| @@ -483,7 +483,8 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir) · 482 unmodified lines | |||
| 483 | static void | 483 | static void |
| 484 | nfs3_proc_rename_setup(struct rpc_message *msg, | 484 | nfs3_proc_rename_setup(struct rpc_message *msg, |
| 485 | struct dentry *old_dentry, | 485 | struct dentry *old_dentry, |
| 486 | struct dentry *new_dentry) | 486 | struct dentry *new_dentry, |
| 487 | struct inode *same_parent) | ||
| 487 | { | 488 | { |
| 488 | msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME]; | 489 | msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME]; |
| 489 | } | 490 | } |
| @@ -281,8 +281,13 @@ error: · 280 unmodified lines | |||
| 281 | */ | 281 | */ |
| 282 | static void nfs4_destroy_callback(struct nfs_client *clp) | 282 | static void nfs4_destroy_callback(struct nfs_client *clp) |
| 283 | { | 283 | { |
| 284 | if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) | 284 | if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) { |
| 285 | nfs_callback_down(clp->cl_mvops->minor_version, clp->cl_net); | 285 | struct rpc_xprt *xprt; |
| 286 | |||
| 287 | xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt); | ||
| 288 | nfs_callback_down(clp->cl_mvops->minor_version, clp->cl_net, | ||
| 289 | xprt); | ||
| 290 | } | ||
| 286 | } | 291 | } |
| 287 | 292 | ||
| 288 | static void nfs4_shutdown_client(struct nfs_client *clp) | 293 | static void nfs4_shutdown_client(struct nfs_client *clp) |
| @@ -1174,10 +1179,20 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc) · 885 unmodified lines | |||
| 1174 | if (error < 0) | 1179 | if (error < 0) |
| 1175 | return error; | 1180 | return error; |
| 1176 | 1181 | ||
| 1177 | if (ctx->rsize) | 1182 | if (ctx->bsize) { |
| 1178 | server->rsize = nfs_io_size(ctx->rsize, server->nfs_client->cl_proto); | 1183 | server->bsize = ctx->bsize; |
| 1179 | if (ctx->wsize) | 1184 | server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_BSIZE; |
| 1180 | server->wsize = nfs_io_size(ctx->wsize, server->nfs_client->cl_proto); | 1185 | } |
| 1186 | if (ctx->rsize) { | ||
| 1187 | server->rsize = | ||
| 1188 | nfs_io_size(ctx->rsize, server->nfs_client->cl_proto); | ||
| 1189 | server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_RSIZE; | ||
| 1190 | } | ||
| 1191 | if (ctx->wsize) { | ||
| 1192 | server->wsize = | ||
| 1193 | nfs_io_size(ctx->wsize, server->nfs_client->cl_proto); | ||
| 1194 | server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_WSIZE; | ||
| 1195 | } | ||
| 1181 | 1196 | ||
| 1182 | server->acregmin = ctx->acregmin * HZ; | 1197 | server->acregmin = ctx->acregmin * HZ; |
| 1183 | server->acregmax = ctx->acregmax * HZ; | 1198 | server->acregmax = ctx->acregmax * HZ; |
| @@ -1780,8 +1780,17 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, · 1779 unmodified lines | |||
| 1780 | if (nfs_stateid_is_sequential(state, stateid)) | 1780 | if (nfs_stateid_is_sequential(state, stateid)) |
| 1781 | break; | 1781 | break; |
| 1782 | 1782 | ||
| 1783 | if (status) | 1783 | if (status) { |
| 1784 | break; | 1784 | if (nfs4_stateid_match_other(stateid, &state->open_stateid) && |
| 1785 | !nfs4_stateid_is_newer(stateid, &state->open_stateid)) { | ||
| 1786 | trace_nfs4_open_stateid_update_skip(state->inode, | ||
| 1787 | stateid, status); | ||
| 1788 | return; | ||
| 1789 | } else { | ||
| 1790 | break; | ||
| 1791 | } | ||
| 1792 | } | ||
| 1793 | |||
| 1785 | /* Rely on seqids for serialisation with NFSv4.0 */ | 1794 | /* Rely on seqids for serialisation with NFSv4.0 */ |
| 1786 | if (!nfs4_has_session(NFS_SERVER(state->inode)->nfs_client)) | 1795 | if (!nfs4_has_session(NFS_SERVER(state->inode)->nfs_client)) |
| 1787 | break; | 1796 | break; |
| @@ -3174,18 +3183,6 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, · 1386 unmodified lines | |||
| 3174 | if (opendata->o_res.rflags & NFS4_OPEN_RESULT_PRESERVE_UNLINKED) | 3183 | if (opendata->o_res.rflags & NFS4_OPEN_RESULT_PRESERVE_UNLINKED) |
| 3175 | set_bit(NFS_INO_PRESERVE_UNLINKED, &NFS_I(state->inode)->flags); | 3184 | set_bit(NFS_INO_PRESERVE_UNLINKED, &NFS_I(state->inode)->flags); |
| 3176 | 3185 | ||
| 3177 | dentry = opendata->dentry; | ||
| 3178 | if (d_really_is_negative(dentry)) { | ||
| 3179 | struct dentry *alias; | ||
| 3180 | d_drop(dentry); | ||
| 3181 | alias = d_splice_alias(igrab(state->inode), dentry); | ||
| 3182 | /* d_splice_alias() can't fail here - it's a non-directory */ | ||
| 3183 | if (alias) { | ||
| 3184 | dput(ctx->dentry); | ||
| 3185 | ctx->dentry = dentry = alias; | ||
| 3186 | } | ||
| 3187 | } | ||
| 3188 | |||
| 3189 | switch(opendata->o_arg.claim) { | 3186 | switch(opendata->o_arg.claim) { |
| 3190 | default: | 3187 | default: |
| 3191 | break; | 3188 | break; |
| @@ -3196,7 +3193,20 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, · 4 unmodified lines | |||
| 3196 | break; | 3193 | break; |
| 3197 | if (opendata->o_res.delegation.type != 0) | 3194 | if (opendata->o_res.delegation.type != 0) |
| 3198 | dir_verifier = nfs_save_change_attribute(dir); | 3195 | dir_verifier = nfs_save_change_attribute(dir); |
| 3199 | nfs_set_verifier(dentry, dir_verifier); | 3196 | } |
| 3197 | |||
| 3198 | dentry = opendata->dentry; | ||
| 3199 | nfs_set_verifier(dentry, dir_verifier); | ||
| 3200 | if (d_really_is_negative(dentry)) { | ||
| 3201 | struct dentry *alias; | ||
| 3202 | d_drop(dentry); | ||
| 3203 | alias = d_splice_alias(igrab(state->inode), dentry); | ||
| 3204 | /* d_splice_alias() can't fail here - it's a non-directory */ | ||
| 3205 | if (alias) { | ||
| 3206 | dput(ctx->dentry); | ||
| 3207 | nfs_set_verifier(alias, dir_verifier); | ||
| 3208 | ctx->dentry = dentry = alias; | ||
| 3209 | } | ||
| 3200 | } | 3210 | } |
| 3201 | 3211 | ||
| 3202 | /* Parse layoutget results before we check for access */ | 3212 | /* Parse layoutget results before we check for access */ |
| @@ -4460,6 +4470,30 @@ out: · 1257 unmodified lines | |||
| 4460 | return status; | 4470 | return status; |
| 4461 | } | 4471 | } |
| 4462 | 4472 | ||
| 4473 | #if IS_ENABLED(CONFIG_NFS_V4_1) | ||
| 4474 | static bool should_request_dir_deleg(struct inode *inode) | ||
| 4475 | { | ||
| 4476 | if (!directory_delegations) | ||
| 4477 | return false; | ||
| 4478 | if (!inode) | ||
| 4479 | return false; | ||
| 4480 | if (!S_ISDIR(inode->i_mode)) | ||
| 4481 | return false; | ||
| 4482 | if (!nfs_server_capable(inode, NFS_CAP_DIR_DELEG)) | ||
| 4483 | return false; | ||
| 4484 | if (!test_and_clear_bit(NFS_INO_REQ_DIR_DELEG, &(NFS_I(inode)->flags))) | ||
| 4485 | return false; | ||
| 4486 | if (nfs4_have_delegation(inode, FMODE_READ, 0)) | ||
| 4487 | return false; | ||
| 4488 | return true; | ||
| 4489 | } | ||
| 4490 | #else | ||
| 4491 | static bool should_request_dir_deleg(struct inode *inode) | ||
| 4492 | { | ||
| 4493 | return false; | ||
| 4494 | } | ||
| 4495 | #endif /* CONFIG_NFS_V4_1 */ | ||
| 4496 | |||
| 4463 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, | 4497 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, |
| 4464 | struct nfs_fattr *fattr, struct inode *inode) | 4498 | struct nfs_fattr *fattr, struct inode *inode) |
| 4465 | { | 4499 | { |
| @@ -4477,7 +4511,9 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, · 11 unmodified lines | |||
| 4477 | .rpc_argp = &args, | 4511 | .rpc_argp = &args, |
| 4478 | .rpc_resp = &res, | 4512 | .rpc_resp = &res, |
| 4479 | }; | 4513 | }; |
| 4514 | struct nfs4_gdd_res gdd_res; | ||
| 4480 | unsigned short task_flags = 0; | 4515 | unsigned short task_flags = 0; |
| 4516 | int status; | ||
| 4481 | 4517 | ||
| 4482 | if (nfs4_has_session(server->nfs_client)) | 4518 | if (nfs4_has_session(server->nfs_client)) |
| 4483 | task_flags = RPC_TASK_MOVEABLE; | 4519 | task_flags = RPC_TASK_MOVEABLE; |
| @@ -4486,11 +4522,31 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, · 2 unmodified lines | |||
| 4486 | if (inode && (server->flags & NFS_MOUNT_SOFTREVAL)) | 4522 | if (inode && (server->flags & NFS_MOUNT_SOFTREVAL)) |
| 4487 | task_flags |= RPC_TASK_TIMEOUT; | 4523 | task_flags |= RPC_TASK_TIMEOUT; |
| 4488 | 4524 | ||
| 4525 | args.get_dir_deleg = should_request_dir_deleg(inode); | ||
| 4526 | if (args.get_dir_deleg) | ||
| 4527 | res.gdd_res = &gdd_res; | ||
| 4528 | |||
| 4489 | nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label), inode, 0); | 4529 | nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label), inode, 0); |
| 4490 | nfs_fattr_init(fattr); | 4530 | nfs_fattr_init(fattr); |
| 4491 | nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0); | 4531 | nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0); |
| 4492 | return nfs4_do_call_sync(server->client, server, &msg, | 4532 | |
| 4493 | &args.seq_args, &res.seq_res, task_flags); | 4533 | status = nfs4_do_call_sync(server->client, server, &msg, |
| 4534 | &args.seq_args, &res.seq_res, task_flags); | ||
| 4535 | if (args.get_dir_deleg) { | ||
| 4536 | switch (status) { | ||
| 4537 | case 0: | ||
| 4538 | if (gdd_res.status != GDD4_OK) | ||
| 4539 | break; | ||
| 4540 | status = nfs_inode_set_delegation( | ||
| 4541 | inode, current_cred(), FMODE_READ, | ||
| 4542 | &gdd_res.deleg, 0, NFS4_OPEN_DELEGATE_READ); | ||
| 4543 | break; | ||
| 4544 | case -ENOTSUPP: | ||
| 4545 | case -EOPNOTSUPP: | ||
| 4546 | server->caps &= ~NFS_CAP_DIR_DELEG; | ||
| 4547 | } | ||
| 4548 | } | ||
| 4549 | return status; | ||
| 4494 | } | 4550 | } |
| 4495 | 4551 | ||
| 4496 | int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, | 4552 | int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, |
| @@ -4503,8 +4559,14 @@ int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, · 6 unmodified lines | |||
| 4503 | do { | 4559 | do { |
| 4504 | err = _nfs4_proc_getattr(server, fhandle, fattr, inode); | 4560 | err = _nfs4_proc_getattr(server, fhandle, fattr, inode); |
| 4505 | trace_nfs4_getattr(server, fhandle, fattr, err); | 4561 | trace_nfs4_getattr(server, fhandle, fattr, err); |
| 4506 | err = nfs4_handle_exception(server, err, | 4562 | switch (err) { |
| 4507 | &exception); | 4563 | default: |
| 4564 | err = nfs4_handle_exception(server, err, &exception); | ||
| 4565 | break; | ||
| 4566 | case -ENOTSUPP: | ||
| 4567 | case -EOPNOTSUPP: | ||
| 4568 | exception.retry = true; | ||
| 4569 | } | ||
| 4508 | } while (exception.retry); | 4570 | } while (exception.retry); |
| 4509 | return err; | 4571 | return err; |
| 4510 | } | 4572 | } |
| @@ -4768,6 +4830,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry · 257 unmodified lines | |||
| 4768 | int status = 0; | 4830 | int status = 0; |
| 4769 | 4831 | ||
| 4770 | if (!nfs4_have_delegation(inode, FMODE_READ, 0)) { | 4832 | if (!nfs4_have_delegation(inode, FMODE_READ, 0)) { |
| 4833 | nfs_request_directory_delegation(inode); | ||
| 4771 | res.fattr = nfs_alloc_fattr(); | 4834 | res.fattr = nfs_alloc_fattr(); |
| 4772 | if (res.fattr == NULL) | 4835 | if (res.fattr == NULL) |
| 4773 | return -ENOMEM; | 4836 | return -ENOMEM; |
| @@ -4875,6 +4938,8 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, · 101 unmodified lines | |||
| 4875 | 4938 | ||
| 4876 | ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); | 4939 | ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); |
| 4877 | 4940 | ||
| 4941 | nfs_request_directory_delegation(dir); | ||
| 4942 | |||
| 4878 | if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) | 4943 | if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK)) |
| 4879 | sattr->ia_mode &= ~current_umask(); | 4944 | sattr->ia_mode &= ~current_umask(); |
| 4880 | state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); | 4945 | state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL); |
| @@ -4971,6 +5036,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, · 90 unmodified lines | |||
| 4971 | nfs4_init_sequence(&args->seq_args, &res->seq_res, 1, 0); | 5036 | nfs4_init_sequence(&args->seq_args, &res->seq_res, 1, 0); |
| 4972 | 5037 | ||
| 4973 | nfs_fattr_init(res->dir_attr); | 5038 | nfs_fattr_init(res->dir_attr); |
| 5039 | nfs_request_directory_delegation(d_inode(dentry->d_parent)); | ||
| 4974 | 5040 | ||
| 4975 | if (inode) { | 5041 | if (inode) { |
| 4976 | nfs4_inode_return_delegation(inode); | 5042 | nfs4_inode_return_delegation(inode); |
| @@ -5005,7 +5071,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) · 28 unmodified lines | |||
| 5005 | 5071 | ||
| 5006 | static void nfs4_proc_rename_setup(struct rpc_message *msg, | 5072 | static void nfs4_proc_rename_setup(struct rpc_message *msg, |
| 5007 | struct dentry *old_dentry, | 5073 | struct dentry *old_dentry, |
| 5008 | struct dentry *new_dentry) | 5074 | struct dentry *new_dentry, |
| 5075 | struct inode *same_parent) | ||
| 5009 | { | 5076 | { |
| 5010 | struct nfs_renameargs *arg = msg->rpc_argp; | 5077 | struct nfs_renameargs *arg = msg->rpc_argp; |
| 5011 | struct nfs_renameres *res = msg->rpc_resp; | 5078 | struct nfs_renameres *res = msg->rpc_resp; |
| @@ -5016,6 +5083,8 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, · 4 unmodified lines | |||
| 5016 | nfs4_inode_make_writeable(old_inode); | 5083 | nfs4_inode_make_writeable(old_inode); |
| 5017 | if (new_inode) | 5084 | if (new_inode) |
| 5018 | nfs4_inode_return_delegation(new_inode); | 5085 | nfs4_inode_return_delegation(new_inode); |
| 5086 | if (same_parent) | ||
| 5087 | nfs_request_directory_delegation(same_parent); | ||
| 5019 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME]; | 5088 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME]; |
| 5020 | res->server = NFS_SB(old_dentry->d_sb); | 5089 | res->server = NFS_SB(old_dentry->d_sb); |
| 5021 | nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1, 0); | 5090 | nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1, 0); |
| @@ -10822,6 +10891,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { · 5800 unmodified lines | |||
| 10822 | .minor_version = 1, | 10891 | .minor_version = 1, |
| 10823 | .init_caps = NFS_CAP_READDIRPLUS | 10892 | .init_caps = NFS_CAP_READDIRPLUS |
| 10824 | | NFS_CAP_ATOMIC_OPEN | 10893 | | NFS_CAP_ATOMIC_OPEN |
| 10894 | | NFS_CAP_DIR_DELEG | ||
| 10825 | | NFS_CAP_POSIX_LOCK | 10895 | | NFS_CAP_POSIX_LOCK |
| 10826 | | NFS_CAP_STATEID_NFSV41 | 10896 | | NFS_CAP_STATEID_NFSV41 |
| 10827 | | NFS_CAP_ATOMIC_OPEN_V1 | 10897 | | NFS_CAP_ATOMIC_OPEN_V1 |
| @@ -10848,6 +10918,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { · 20 unmodified lines | |||
| 10848 | .minor_version = 2, | 10918 | .minor_version = 2, |
| 10849 | .init_caps = NFS_CAP_READDIRPLUS | 10919 | .init_caps = NFS_CAP_READDIRPLUS |
| 10850 | | NFS_CAP_ATOMIC_OPEN | 10920 | | NFS_CAP_ATOMIC_OPEN |
| 10921 | | NFS_CAP_DIR_DELEG | ||
| 10851 | | NFS_CAP_POSIX_LOCK | 10922 | | NFS_CAP_POSIX_LOCK |
| 10852 | | NFS_CAP_STATEID_NFSV41 | 10923 | | NFS_CAP_STATEID_NFSV41 |
| 10853 | | NFS_CAP_ATOMIC_OPEN_V1 | 10924 | | NFS_CAP_ATOMIC_OPEN_V1 |
| @@ -1353,6 +1353,7 @@ DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_setattr); · 1352 unmodified lines | |||
| 1353 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_delegreturn); | 1353 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_delegreturn); |
| 1354 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update); | 1354 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update); |
| 1355 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_wait); | 1355 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_wait); |
| 1356 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_skip); | ||
| 1356 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_close_stateid_update_wait); | 1357 | DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_close_stateid_update_wait); |
| 1357 | 1358 | ||
| 1358 | DECLARE_EVENT_CLASS(nfs4_getattr_event, | 1359 | DECLARE_EVENT_CLASS(nfs4_getattr_event, |
| @@ -393,6 +393,20 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, · 392 unmodified lines | |||
| 393 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) | 393 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) |
| 394 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) | 394 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) |
| 395 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) | 395 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) |
| 396 | #define encode_get_dir_deleg_maxsz (op_encode_hdr_maxsz + \ | ||
| 397 | 4 /* gdda_signal_deleg_avail */ + \ | ||
| 398 | 8 /* gdda_notification_types */ + \ | ||
| 399 | nfstime4_maxsz /* gdda_child_attr_delay */ + \ | ||
| 400 | nfstime4_maxsz /* gdda_dir_attr_delay */ + \ | ||
| 401 | nfs4_fattr_bitmap_maxsz /* gdda_child_attributes */ + \ | ||
| 402 | nfs4_fattr_bitmap_maxsz /* gdda_dir_attributes */) | ||
| 403 | #define decode_get_dir_deleg_maxsz (op_decode_hdr_maxsz + \ | ||
| 404 | 4 /* gddrnf_status */ + \ | ||
| 405 | encode_verifier_maxsz /* gddr_cookieverf */ + \ | ||
| 406 | encode_stateid_maxsz /* gddr_stateid */ + \ | ||
| 407 | 8 /* gddr_notification */ + \ | ||
| 408 | nfs4_fattr_maxsz /* gddr_child_attributes */ + \ | ||
| 409 | nfs4_fattr_maxsz /* gddr_dir_attributes */) | ||
| 396 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \ | 410 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \ |
| 397 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ | 411 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ |
| 398 | 1 /* layout type */ + \ | 412 | 1 /* layout type */ + \ |
| @@ -444,6 +458,8 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, · 45 unmodified lines | |||
| 444 | #else /* CONFIG_NFS_V4_1 */ | 458 | #else /* CONFIG_NFS_V4_1 */ |
| 445 | #define encode_sequence_maxsz 0 | 459 | #define encode_sequence_maxsz 0 |
| 446 | #define decode_sequence_maxsz 0 | 460 | #define decode_sequence_maxsz 0 |
| 461 | #define encode_get_dir_deleg_maxsz 0 | ||
| 462 | #define decode_get_dir_deleg_maxsz 0 | ||
| 447 | #define encode_layoutreturn_maxsz 0 | 463 | #define encode_layoutreturn_maxsz 0 |
| 448 | #define decode_layoutreturn_maxsz 0 | 464 | #define decode_layoutreturn_maxsz 0 |
| 449 | #define encode_layoutget_maxsz 0 | 465 | #define encode_layoutget_maxsz 0 |
| @@ -631,11 +647,13 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, · 181 unmodified lines | |||
| 631 | #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ | 647 | #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ |
| 632 | encode_sequence_maxsz + \ | 648 | encode_sequence_maxsz + \ |
| 633 | encode_putfh_maxsz + \ | 649 | encode_putfh_maxsz + \ |
| 650 | encode_get_dir_deleg_maxsz + \ | ||
| 634 | encode_getattr_maxsz + \ | 651 | encode_getattr_maxsz + \ |
| 635 | encode_renew_maxsz) | 652 | encode_renew_maxsz) |
| 636 | #define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ | 653 | #define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ |
| 637 | decode_sequence_maxsz + \ | 654 | decode_sequence_maxsz + \ |
| 638 | decode_putfh_maxsz + \ | 655 | decode_putfh_maxsz + \ |
| 656 | decode_get_dir_deleg_maxsz + \ | ||
| 639 | decode_getattr_maxsz + \ | 657 | decode_getattr_maxsz + \ |
| 640 | decode_renew_maxsz) | 658 | decode_renew_maxsz) |
| 641 | #define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ | 659 | #define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ |
| @@ -2007,6 +2025,33 @@ static void encode_sequence(struct xdr_stream *xdr, · 1365 unmodified lines | |||
| 2007 | } | 2025 | } |
| 2008 | 2026 | ||
| 2009 | #ifdef CONFIG_NFS_V4_1 | 2027 | #ifdef CONFIG_NFS_V4_1 |
| 2028 | static void | ||
| 2029 | encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr) | ||
| 2030 | { | ||
| 2031 | struct timespec64 ts = { 0, 0 }; | ||
| 2032 | u32 notifications[1] = { 0 }; | ||
| 2033 | u32 attributes[1] = { 0 }; | ||
| 2034 | __be32 *p; | ||
| 2035 | |||
| 2036 | encode_op_hdr(xdr, OP_GET_DIR_DELEGATION, decode_get_dir_deleg_maxsz, hdr); | ||
| 2037 | |||
| 2038 | /* We don't handle CB_RECALLABLE_OBJ_AVAIL yet. */ | ||
| 2039 | xdr_stream_encode_bool(xdr, false); | ||
| 2040 | |||
| 2041 | xdr_encode_bitmap4(xdr, notifications, ARRAY_SIZE(notifications)); | ||
| 2042 | |||
| 2043 | /* Request no delay on attribute updates */ | ||
| 2044 | p = reserve_space(xdr, 12 + 12); | ||
| 2045 | p = xdr_encode_nfstime4(p, &ts); | ||
| 2046 | xdr_encode_nfstime4(p, &ts); | ||
| 2047 | |||
| 2048 | /* Requested child attributes */ | ||
| 2049 | xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes)); | ||
| 2050 | |||
| 2051 | /* Requested dir attributes */ | ||
| 2052 | xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes)); | ||
| 2053 | } | ||
| 2054 | |||
| 2010 | static void | 2055 | static void |
| 2011 | encode_getdeviceinfo(struct xdr_stream *xdr, | 2056 | encode_getdeviceinfo(struct xdr_stream *xdr, |
| 2012 | const struct nfs4_getdeviceinfo_args *args, | 2057 | const struct nfs4_getdeviceinfo_args *args, |
| @@ -2142,6 +2187,11 @@ static void encode_free_stateid(struct xdr_stream *xdr, · 129 unmodified lines | |||
| 2142 | encode_nfs4_stateid(xdr, &args->stateid); | 2187 | encode_nfs4_stateid(xdr, &args->stateid); |
| 2143 | } | 2188 | } |
| 2144 | #else | 2189 | #else |
| 2190 | static inline void | ||
| 2191 | encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr) | ||
| 2192 | { | ||
| 2193 | } | ||
| 2194 | |||
| 2145 | static inline void | 2195 | static inline void |
| 2146 | encode_layoutreturn(struct xdr_stream *xdr, | 2196 | encode_layoutreturn(struct xdr_stream *xdr, |
| 2147 | const struct nfs4_layoutreturn_args *args, | 2197 | const struct nfs4_layoutreturn_args *args, |
| @@ -2356,6 +2406,8 @@ static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr, · 208 unmodified lines | |||
| 2356 | encode_compound_hdr(xdr, req, &hdr); | 2406 | encode_compound_hdr(xdr, req, &hdr); |
| 2357 | encode_sequence(xdr, &args->seq_args, &hdr); | 2407 | encode_sequence(xdr, &args->seq_args, &hdr); |
| 2358 | encode_putfh(xdr, args->fh, &hdr); | 2408 | encode_putfh(xdr, args->fh, &hdr); |
| 2409 | if (args->get_dir_deleg) | ||
| 2410 | encode_get_dir_delegation(xdr, &hdr); | ||
| 2359 | encode_getfattr(xdr, args->bitmask, &hdr); | 2411 | encode_getfattr(xdr, args->bitmask, &hdr); |
| 2360 | encode_nops(&hdr); | 2412 | encode_nops(&hdr); |
| 2361 | } | 2413 | } |
| @@ -5994,6 +6046,49 @@ static int decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) · 3632 unmodified lines | |||
| 5994 | return decode_stateid(xdr, stateid); | 6046 | return decode_stateid(xdr, stateid); |
| 5995 | } | 6047 | } |
| 5996 | 6048 | ||
| 6049 | static int decode_get_dir_delegation(struct xdr_stream *xdr, | ||
| 6050 | struct nfs4_getattr_res *res) | ||
| 6051 | { | ||
| 6052 | struct nfs4_gdd_res *gdd_res = res->gdd_res; | ||
| 6053 | nfs4_verifier cookieverf; | ||
| 6054 | u32 bitmap[1]; | ||
| 6055 | int status; | ||
| 6056 | |||
| 6057 | status = decode_op_hdr(xdr, OP_GET_DIR_DELEGATION); | ||
| 6058 | if (status) | ||
| 6059 | return status; | ||
| 6060 | |||
| 6061 | if (xdr_stream_decode_u32(xdr, &gdd_res->status)) | ||
| 6062 | return -EIO; | ||
| 6063 | |||
| 6064 | if (gdd_res->status == GDD4_UNAVAIL) | ||
| 6065 | return xdr_inline_decode(xdr, 4) ? 0 : -EIO; | ||
| 6066 | |||
| 6067 | status = decode_verifier(xdr, &cookieverf); | ||
| 6068 | if (status) | ||
| 6069 | return status; | ||
| 6070 | |||
| 6071 | status = decode_delegation_stateid(xdr, &gdd_res->deleg); | ||
| 6072 | if (status) | ||
| 6073 | return status; | ||
| 6074 | |||
| 6075 | /* Decode supported notification types. */ | ||
| 6076 | status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap)); | ||
| 6077 | if (status < 0) | ||
| 6078 | return status; | ||
| 6079 | |||
| 6080 | /* Decode supported child attributes. */ | ||
| 6081 | status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap)); | ||
| 6082 | if (status < 0) | ||
| 6083 | return status; | ||
| 6084 | |||
| 6085 | /* Decode supported attributes. */ | ||
| 6086 | status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap)); | ||
| 6087 | if (status < 0) | ||
| 6088 | return status; | ||
| 6089 | return 0; | ||
| 6090 | } | ||
| 6091 | |||
| 5997 | static int decode_getdeviceinfo(struct xdr_stream *xdr, | 6092 | static int decode_getdeviceinfo(struct xdr_stream *xdr, |
| 5998 | struct nfs4_getdeviceinfo_res *res) | 6093 | struct nfs4_getdeviceinfo_res *res) |
| 5999 | { | 6094 | { |
| @@ -6208,6 +6303,12 @@ static int decode_free_stateid(struct xdr_stream *xdr, · 208 unmodified lines | |||
| 6208 | return res->status; | 6303 | return res->status; |
| 6209 | } | 6304 | } |
| 6210 | #else | 6305 | #else |
| 6306 | static int decode_get_dir_delegation(struct xdr_stream *xdr, | ||
| 6307 | struct nfs4_getattr_res *res) | ||
| 6308 | { | ||
| 6309 | return 0; | ||
| 6310 | } | ||
| 6311 | |||
| 6211 | static inline | 6312 | static inline |
| 6212 | int decode_layoutreturn(struct xdr_stream *xdr, | 6313 | int decode_layoutreturn(struct xdr_stream *xdr, |
| 6213 | struct nfs4_layoutreturn_res *res) | 6314 | struct nfs4_layoutreturn_res *res) |
| @@ -6525,6 +6626,11 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, · 311 unmodified lines | |||
| 6525 | status = decode_putfh(xdr); | 6626 | status = decode_putfh(xdr); |
| 6526 | if (status) | 6627 | if (status) |
| 6527 | goto out; | 6628 | goto out; |
| 6629 | if (res->gdd_res) { | ||
| 6630 | status = decode_get_dir_delegation(xdr, res); | ||
| 6631 | if (status) | ||
| 6632 | goto out; | ||
| 6633 | } | ||
| 6528 | status = decode_getfattr(xdr, res->fattr, res->server); | 6634 | status = decode_getfattr(xdr, res->fattr, res->server); |
| 6529 | out: | 6635 | out: |
| 6530 | return status; | 6636 | return status; |
| @@ -464,6 +464,7 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo, · 463 unmodified lines | |||
| 464 | struct pnfs_layout_segment *lseg, *next; | 464 | struct pnfs_layout_segment *lseg, *next; |
| 465 | 465 | ||
| 466 | set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | 466 | set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); |
| 467 | clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(lo->plh_inode)->flags); | ||
| 467 | list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) | 468 | list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) |
| 468 | pnfs_clear_lseg_state(lseg, lseg_list); | 469 | pnfs_clear_lseg_state(lseg, lseg_list); |
| 469 | pnfs_clear_layoutreturn_info(lo); | 470 | pnfs_clear_layoutreturn_info(lo); |
| @@ -353,7 +353,8 @@ static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) · 352 unmodified lines | |||
| 353 | static void | 353 | static void |
| 354 | nfs_proc_rename_setup(struct rpc_message *msg, | 354 | nfs_proc_rename_setup(struct rpc_message *msg, |
| 355 | struct dentry *old_dentry, | 355 | struct dentry *old_dentry, |
| 356 | struct dentry *new_dentry) | 356 | struct dentry *new_dentry, |
| 357 | struct inode *same_parent) | ||
| 357 | { | 358 | { |
| 358 | msg->rpc_proc = &nfs_procedures[NFSPROC_RENAME]; | 359 | msg->rpc_proc = &nfs_procedures[NFSPROC_RENAME]; |
| 359 | } | 360 | } |
| @@ -1051,16 +1051,6 @@ int nfs_reconfigure(struct fs_context *fc) · 1050 unmodified lines | |||
| 1051 | 1051 | ||
| 1052 | sync_filesystem(sb); | 1052 | sync_filesystem(sb); |
| 1053 | 1053 | ||
| 1054 | /* | ||
| 1055 | * The SB_RDONLY flag has been removed from the superblock during | ||
| 1056 | * mounts to prevent interference between different filesystems. | ||
| 1057 | * Similarly, it is also necessary to ignore the SB_RDONLY flag | ||
| 1058 | * during reconfiguration; otherwise, it may also result in the | ||
| 1059 | * creation of redundant superblocks when mounting a directory with | ||
| 1060 | * different rw and ro flags multiple times. | ||
| 1061 | */ | ||
| 1062 | fc->sb_flags_mask &= ~SB_RDONLY; | ||
| 1063 | |||
| 1064 | /* | 1054 | /* |
| 1065 | * Userspace mount programs that send binary options generally send | 1055 | * Userspace mount programs that send binary options generally send |
| 1066 | * them populated with default values. We have no way to know which | 1056 | * them populated with default values. We have no way to know which |
| @@ -1101,8 +1091,9 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx) · 34 unmodified lines | |||
| 1101 | sb->s_blocksize = 0; | 1091 | sb->s_blocksize = 0; |
| 1102 | sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr; | 1092 | sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr; |
| 1103 | sb->s_op = server->nfs_client->cl_nfs_mod->sops; | 1093 | sb->s_op = server->nfs_client->cl_nfs_mod->sops; |
| 1104 | if (ctx->bsize) | 1094 | if (server->bsize) |
| 1105 | sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits); | 1095 | sb->s_blocksize = |
| 1096 | nfs_block_size(server->bsize, &sb->s_blocksize_bits); | ||
| 1106 | 1097 | ||
| 1107 | switch (server->nfs_client->rpc_ops->version) { | 1098 | switch (server->nfs_client->rpc_ops->version) { |
| 1108 | case 2: | 1099 | case 2: |
| @@ -1318,26 +1309,13 @@ int nfs_get_tree_common(struct fs_context *fc) · 209 unmodified lines | |||
| 1318 | if (IS_ERR(server)) | 1309 | if (IS_ERR(server)) |
| 1319 | return PTR_ERR(server); | 1310 | return PTR_ERR(server); |
| 1320 | 1311 | ||
| 1321 | /* | ||
| 1322 | * When NFS_MOUNT_UNSHARED is not set, NFS forces the sharing of a | ||
| 1323 | * superblock among each filesystem that mounts sub-directories | ||
| 1324 | * belonging to a single exported root path. | ||
| 1325 | * To prevent interference between different filesystems, the | ||
| 1326 | * SB_RDONLY flag should be removed from the superblock. | ||
| 1327 | */ | ||
| 1328 | if (server->flags & NFS_MOUNT_UNSHARED) | 1312 | if (server->flags & NFS_MOUNT_UNSHARED) |
| 1329 | compare_super = NULL; | 1313 | compare_super = NULL; |
| 1330 | else | ||
| 1331 | fc->sb_flags &= ~SB_RDONLY; | ||
| 1332 | 1314 | ||
| 1333 | /* -o noac implies -o sync */ | 1315 | /* -o noac implies -o sync */ |
| 1334 | if (server->flags & NFS_MOUNT_NOAC) | 1316 | if (server->flags & NFS_MOUNT_NOAC) |
| 1335 | fc->sb_flags |= SB_SYNCHRONOUS; | 1317 | fc->sb_flags |= SB_SYNCHRONOUS; |
| 1336 | 1318 | ||
| 1337 | if (ctx->clone_data.sb) | ||
| 1338 | if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS) | ||
| 1339 | fc->sb_flags |= SB_SYNCHRONOUS; | ||
| 1340 | |||
| 1341 | /* Get a superblock - note that we may end up sharing one that already exists */ | 1319 | /* Get a superblock - note that we may end up sharing one that already exists */ |
| 1342 | fc->s_fs_info = server; | 1320 | fc->s_fs_info = server; |
| 1343 | s = sget_fc(fc, compare_super, nfs_set_super); | 1321 | s = sget_fc(fc, compare_super, nfs_set_super); |
| @@ -1361,13 +1339,8 @@ int nfs_get_tree_common(struct fs_context *fc) · 17 unmodified lines | |||
| 1361 | } | 1339 | } |
| 1362 | 1340 | ||
| 1363 | if (!s->s_root) { | 1341 | if (!s->s_root) { |
| 1364 | unsigned bsize = ctx->clone_data.inherited_bsize; | ||
| 1365 | /* initial superblock/root creation */ | 1342 | /* initial superblock/root creation */ |
| 1366 | nfs_fill_super(s, ctx); | 1343 | nfs_fill_super(s, ctx); |
| 1367 | if (bsize) { | ||
| 1368 | s->s_blocksize_bits = bsize; | ||
| 1369 | s->s_blocksize = 1U << bsize; | ||
| 1370 | } | ||
| 1371 | error = nfs_get_cache_cookie(s, ctx); | 1344 | error = nfs_get_cache_cookie(s, ctx); |
| 1372 | if (error < 0) | 1345 | if (error < 0) |
| 1373 | goto error_splat_super; | 1346 | goto error_splat_super; |
| @@ -390,7 +390,8 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, · 389 unmodified lines | |||
| 390 | 390 | ||
| 391 | nfs_sb_active(old_dir->i_sb); | 391 | nfs_sb_active(old_dir->i_sb); |
| 392 | 392 | ||
| 393 | NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry); | 393 | NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry, |
| 394 | old_dir == new_dir ? old_dir : NULL); | ||
| 394 | 395 | ||
| 395 | return rpc_run_task(&task_setup_data); | 396 | return rpc_run_task(&task_setup_data); |
| 396 | } | 397 | } |
| @@ -344,6 +344,7 @@ struct nfs4_copy_state { · 343 unmodified lines | |||
| 344 | #define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */ | 344 | #define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */ |
| 345 | #define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */ | 345 | #define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */ |
| 346 | #define NFS_INO_ODIRECT (12) /* I/O setting is O_DIRECT */ | 346 | #define NFS_INO_ODIRECT (12) /* I/O setting is O_DIRECT */ |
| 347 | #define NFS_INO_REQ_DIR_DELEG (13) /* Request a directory delegation */ | ||
| 347 | 348 | ||
| 348 | static inline struct nfs_inode *NFS_I(const struct inode *inode) | 349 | static inline struct nfs_inode *NFS_I(const struct inode *inode) |
| 349 | { | 350 | { |
| @@ -172,6 +172,11 @@ struct nfs_server { · 171 unmodified lines | |||
| 172 | #define NFS_MOUNT_FORCE_RDIRPLUS 0x20000000 | 172 | #define NFS_MOUNT_FORCE_RDIRPLUS 0x20000000 |
| 173 | #define NFS_MOUNT_NETUNREACH_FATAL 0x40000000 | 173 | #define NFS_MOUNT_NETUNREACH_FATAL 0x40000000 |
| 174 | 174 | ||
| 175 | unsigned int automount_inherit; /* Properties inherited by automount */ | ||
| 176 | #define NFS_AUTOMOUNT_INHERIT_BSIZE 0x0001 | ||
| 177 | #define NFS_AUTOMOUNT_INHERIT_RSIZE 0x0002 | ||
| 178 | #define NFS_AUTOMOUNT_INHERIT_WSIZE 0x0004 | ||
| 179 | |||
| 175 | unsigned int caps; /* server capabilities */ | 180 | unsigned int caps; /* server capabilities */ |
| 176 | __u64 fattr_valid; /* Valid attributes */ | 181 | __u64 fattr_valid; /* Valid attributes */ |
| 177 | unsigned int rsize; /* read size */ | 182 | unsigned int rsize; /* read size */ |
| @@ -305,6 +310,7 @@ struct nfs_server { · 127 unmodified lines | |||
| 305 | #define NFS_CAP_REBOOT_LAYOUTRETURN (1U << 8) | 310 | #define NFS_CAP_REBOOT_LAYOUTRETURN (1U << 8) |
| 306 | #define NFS_CAP_OFFLOAD_STATUS (1U << 9) | 311 | #define NFS_CAP_OFFLOAD_STATUS (1U << 9) |
| 307 | #define NFS_CAP_ZERO_RANGE (1U << 10) | 312 | #define NFS_CAP_ZERO_RANGE (1U << 10) |
| 313 | #define NFS_CAP_DIR_DELEG (1U << 11) | ||
| 308 | #define NFS_CAP_OPEN_XOR (1U << 12) | 314 | #define NFS_CAP_OPEN_XOR (1U << 12) |
| 309 | #define NFS_CAP_DELEGTIME (1U << 13) | 315 | #define NFS_CAP_DELEGTIME (1U << 13) |
| 310 | #define NFS_CAP_POSIX_LOCK (1U << 14) | 316 | #define NFS_CAP_POSIX_LOCK (1U << 14) |
| @@ -1092,12 +1092,19 @@ struct nfs4_getattr_arg { · 1091 unmodified lines | |||
| 1092 | struct nfs4_sequence_args seq_args; | 1092 | struct nfs4_sequence_args seq_args; |
| 1093 | const struct nfs_fh * fh; | 1093 | const struct nfs_fh * fh; |
| 1094 | const u32 * bitmask; | 1094 | const u32 * bitmask; |
| 1095 | bool get_dir_deleg; | ||
| 1096 | }; | ||
| 1097 | |||
| 1098 | struct nfs4_gdd_res { | ||
| 1099 | u32 status; | ||
| 1100 | nfs4_stateid deleg; | ||
| 1095 | }; | 1101 | }; |
| 1096 | 1102 | ||
| 1097 | struct nfs4_getattr_res { | 1103 | struct nfs4_getattr_res { |
| 1098 | struct nfs4_sequence_res seq_res; | 1104 | struct nfs4_sequence_res seq_res; |
| 1099 | const struct nfs_server * server; | 1105 | const struct nfs_server * server; |
| 1100 | struct nfs_fattr * fattr; | 1106 | struct nfs_fattr * fattr; |
| 1107 | struct nfs4_gdd_res * gdd_res; | ||
| 1101 | }; | 1108 | }; |
| 1102 | 1109 | ||
| 1103 | struct nfs4_link_arg { | 1110 | struct nfs4_link_arg { |
| @@ -1801,7 +1808,8 @@ struct nfs_rpc_ops { · 697 unmodified lines | |||
| 1801 | int (*unlink_done) (struct rpc_task *, struct inode *); | 1808 | int (*unlink_done) (struct rpc_task *, struct inode *); |
| 1802 | void (*rename_setup) (struct rpc_message *msg, | 1809 | void (*rename_setup) (struct rpc_message *msg, |
| 1803 | struct dentry *old_dentry, | 1810 | struct dentry *old_dentry, |
| 1804 | struct dentry *new_dentry); | 1811 | struct dentry *new_dentry, |
| 1812 | struct inode *same_parent); | ||
| 1805 | void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *); | 1813 | void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *); |
| 1806 | int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir); | 1814 | int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir); |
| 1807 | int (*link) (struct inode *, struct inode *, const struct qstr *); | 1815 | int (*link) (struct inode *, struct inode *, const struct qstr *); |
| @@ -25,12 +25,14 @@ void xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task, · 24 unmodified lines | |||
| 25 | void xprt_free_bc_request(struct rpc_rqst *req); | 25 | void xprt_free_bc_request(struct rpc_rqst *req); |
| 26 | int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs); | 26 | int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs); |
| 27 | void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs); | 27 | void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs); |
| 28 | void xprt_enqueue_bc_request(struct rpc_rqst *req); | ||
| 28 | 29 | ||
| 29 | /* Socket backchannel transport methods */ | 30 | /* Socket backchannel transport methods */ |
| 30 | int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs); | 31 | int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs); |
| 31 | void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs); | 32 | void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs); |
| 32 | void xprt_free_bc_rqst(struct rpc_rqst *req); | 33 | void xprt_free_bc_rqst(struct rpc_rqst *req); |
| 33 | unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt); | 34 | unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt); |
| 35 | void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv); | ||
| 34 | 36 | ||
| 35 | /* | 37 | /* |
| 36 | * Determine if a shared backchannel is in use | 38 | * Determine if a shared backchannel is in use |
| @@ -68,5 +70,10 @@ static inline void set_bc_enabled(struct svc_serv *serv) · 31 unmodified lines | |||
| 68 | static inline void xprt_free_bc_request(struct rpc_rqst *req) | 70 | static inline void xprt_free_bc_request(struct rpc_rqst *req) |
| 69 | { | 71 | { |
| 70 | } | 72 | } |
| 73 | |||
| 74 | static inline void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv) | ||
| 75 | { | ||
| 76 | svc_destroy(serv); | ||
| 77 | } | ||
| 71 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ | 78 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
| 72 | #endif /* _LINUX_SUNRPC_BC_XPRT_H */ | 79 | #endif /* _LINUX_SUNRPC_BC_XPRT_H */ |
| @@ -24,6 +24,22 @@ unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt) · 23 unmodified lines | |||
| 24 | return BC_MAX_SLOTS; | 24 | return BC_MAX_SLOTS; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | /* | ||
| 28 | * Helper function to nullify backchannel server pointer in transport. | ||
| 29 | * We need to synchronize setting the pointer to NULL (done so after | ||
| 30 | * the backchannel server is shutdown) with the usage of that pointer | ||
| 31 | * by the backchannel request processing routines | ||
| 32 | * xprt_complete_bc_request() and rpcrdma_bc_receive_call(). | ||
| 33 | */ | ||
| 34 | void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv) | ||
| 35 | { | ||
| 36 | spin_lock(&xprt->bc_pa_lock); | ||
| 37 | svc_destroy(serv); | ||
| 38 | xprt->bc_serv = NULL; | ||
| 39 | spin_unlock(&xprt->bc_pa_lock); | ||
| 40 | } | ||
| 41 | EXPORT_SYMBOL_GPL(xprt_svc_destroy_nullify_bc); | ||
| 42 | |||
| 27 | /* | 43 | /* |
| 28 | * Helper routines that track the number of preallocation elements | 44 | * Helper routines that track the number of preallocation elements |
| 29 | * on the transport. | 45 | * on the transport. |
| @@ -354,7 +370,6 @@ found: · 324 unmodified lines | |||
| 354 | void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) | 370 | void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) |
| 355 | { | 371 | { |
| 356 | struct rpc_xprt *xprt = req->rq_xprt; | 372 | struct rpc_xprt *xprt = req->rq_xprt; |
| 357 | struct svc_serv *bc_serv = xprt->bc_serv; | ||
| 358 | 373 | ||
| 359 | spin_lock(&xprt->bc_pa_lock); | 374 | spin_lock(&xprt->bc_pa_lock); |
| 360 | list_del(&req->rq_bc_pa_list); | 375 | list_del(&req->rq_bc_pa_list); |
| @@ -365,7 +380,21 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) · 4 unmodified lines | |||
| 365 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); | 380 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); |
| 366 | 381 | ||
| 367 | dprintk("RPC: add callback request to list\n"); | 382 | dprintk("RPC: add callback request to list\n"); |
| 383 | xprt_enqueue_bc_request(req); | ||
| 384 | } | ||
| 385 | |||
| 386 | void xprt_enqueue_bc_request(struct rpc_rqst *req) | ||
| 387 | { | ||
| 388 | struct rpc_xprt *xprt = req->rq_xprt; | ||
| 389 | struct svc_serv *bc_serv; | ||
| 390 | |||
| 368 | xprt_get(xprt); | 391 | xprt_get(xprt); |
| 369 | lwq_enqueue(&req->rq_bc_list, &bc_serv->sv_cb_list); | 392 | spin_lock(&xprt->bc_pa_lock); |
| 370 | svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]); | 393 | bc_serv = xprt->bc_serv; |
| 394 | if (bc_serv) { | ||
| 395 | lwq_enqueue(&req->rq_bc_list, &bc_serv->sv_cb_list); | ||
| 396 | svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]); | ||
| 397 | } | ||
| 398 | spin_unlock(&xprt->bc_pa_lock); | ||
| 371 | } | 399 | } |
| 400 | EXPORT_SYMBOL_GPL(xprt_enqueue_bc_request); | ||
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/sunrpc/svc.h> | 9 | #include <linux/sunrpc/svc.h> |
| 10 | #include <linux/sunrpc/svc_xprt.h> | 10 | #include <linux/sunrpc/svc_xprt.h> |
| 11 | #include <linux/sunrpc/svc_rdma.h> | 11 | #include <linux/sunrpc/svc_rdma.h> |
| 12 | #include <linux/sunrpc/bc_xprt.h> | ||
| 12 | 13 | ||
| 13 | #include "xprt_rdma.h" | 14 | #include "xprt_rdma.h" |
| 14 | #include <trace/events/rpcrdma.h> | 15 | #include <trace/events/rpcrdma.h> |
| @@ -220,7 +221,6 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, · 205 unmodified lines | |||
| 220 | struct rpcrdma_rep *rep) | 221 | struct rpcrdma_rep *rep) |
| 221 | { | 222 | { |
| 222 | struct rpc_xprt *xprt = &r_xprt->rx_xprt; | 223 | struct rpc_xprt *xprt = &r_xprt->rx_xprt; |
| 223 | struct svc_serv *bc_serv; | ||
| 224 | struct rpcrdma_req *req; | 224 | struct rpcrdma_req *req; |
| 225 | struct rpc_rqst *rqst; | 225 | struct rpc_rqst *rqst; |
| 226 | struct xdr_buf *buf; | 226 | struct xdr_buf *buf; |
| @@ -261,11 +261,7 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, · 34 unmodified lines | |||
| 261 | trace_xprtrdma_cb_call(r_xprt, rqst); | 261 | trace_xprtrdma_cb_call(r_xprt, rqst); |
| 262 | 262 | ||
| 263 | /* Queue rqst for ULP's callback service */ | 263 | /* Queue rqst for ULP's callback service */ |
| 264 | bc_serv = xprt->bc_serv; | 264 | xprt_enqueue_bc_request(rqst); |
| 265 | xprt_get(xprt); | ||
| 266 | lwq_enqueue(&rqst->rq_bc_list, &bc_serv->sv_cb_list); | ||
| 267 | |||
| 268 | svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]); | ||
| 269 | 265 | ||
| 270 | r_xprt->rx_stats.bcall_count++; | 266 | r_xprt->rx_stats.bcall_count++; |
| 271 | return; | 267 | return; |