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

Merge tag 'nfsd-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull nfsd updates from Chuck Lever:
"We introduce 'courteous server' in this release. Previously NFSD would
purge open and lock state for an unresponsive client after one lease
period (typically 90 seconds). Now, after one lease period, another
client can open and lock those files and the unresponsive client's
lease is purged; otherwise if the unresponsive client's open and lock
state is uncontended, the server retains that open and lock state for
up to 24 hours, allowing the client's workload to resume after a
lengthy network partition.

A longstanding issue with NFSv4 file creation is also addressed.
Previously a file creation can fail internally, returning an error to
the client, but leave the newly created file in place as an artifact.
The file creation code path has been reorganized so that internal
failures and race conditions are less likely to result in an unwanted
file creation.

A fault injector has been added to help exercise paths that are run
during kernel metadata cache invalidation. These caches contain
information maintained by user space about exported filesystems. Many
of our test workloads do not trigger cache invalidation.

There is one patch that is needed to support PREEMPT_RT and a fix for
an ancient 'sleep while spin-locked' splat that seems to have become
easier to hit since v5.18-rc3"

* tag 'nfsd-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (36 commits)
NFSD: nfsd_file_put() can sleep
NFSD: Add documenting comment for nfsd4_release_lockowner()
NFSD: Modernize nfsd4_release_lockowner()
NFSD: Fix possible sleep during nfsd4_release_lockowner()
nfsd: destroy percpu stats counters after reply cache shutdown
nfsd: Fix null-ptr-deref in nfsd_fill_super()
nfsd: Unregister the cld notifier when laundry_wq create failed
SUNRPC: Use RMW bitops in single-threaded hot paths
NFSD: Clean up the show_nf_flags() macro
NFSD: Trace filecache opens
NFSD: Move documenting comment for nfsd4_process_open2()
NFSD: Fix whitespace
NFSD: Remove dprintk call sites from tail of nfsd4_open()
NFSD: Instantiate a struct file when creating a regular NFSv4 file
NFSD: Clean up nfsd_open_verified()
NFSD: Remove do_nfsd_create()
NFSD: Refactor NFSv4 OPEN(CREATE)
NFSD: Refactor NFSv3 CREATE
NFSD: Refactor nfsd_create_setattr()
NFSD: Avoid calling fh_drop_write() twice in do_nfsd_create()
...

+986 -427
+4
Documentation/filesystems/locking.rst
··· 434 434 void (*lm_break)(struct file_lock *); /* break_lease callback */ 435 435 int (*lm_change)(struct file_lock **, int); 436 436 bool (*lm_breaker_owns_lease)(struct file_lock *); 437 + bool (*lm_lock_expirable)(struct file_lock *); 438 + void (*lm_expire_lock)(void); 437 439 438 440 locking rules: 439 441 ··· 447 445 lm_break: yes no no 448 446 lm_change yes no no 449 447 lm_breaker_owns_lease: yes no no 448 + lm_lock_expirable yes no no 449 + lm_expire_lock no no yes 450 450 ====================== ============= ================= ========= 451 451 452 452 buffer_head
+58 -3
fs/locks.c
··· 300 300 } 301 301 EXPORT_SYMBOL_GPL(locks_release_private); 302 302 303 + /** 304 + * locks_owner_has_blockers - Check for blocking lock requests 305 + * @flctx: file lock context 306 + * @owner: lock owner 307 + * 308 + * Return values: 309 + * %true: @owner has at least one blocker 310 + * %false: @owner has no blockers 311 + */ 312 + bool locks_owner_has_blockers(struct file_lock_context *flctx, 313 + fl_owner_t owner) 314 + { 315 + struct file_lock *fl; 316 + 317 + spin_lock(&flctx->flc_lock); 318 + list_for_each_entry(fl, &flctx->flc_posix, fl_list) { 319 + if (fl->fl_owner != owner) 320 + continue; 321 + if (!list_empty(&fl->fl_blocked_requests)) { 322 + spin_unlock(&flctx->flc_lock); 323 + return true; 324 + } 325 + } 326 + spin_unlock(&flctx->flc_lock); 327 + return false; 328 + } 329 + EXPORT_SYMBOL_GPL(locks_owner_has_blockers); 330 + 303 331 /* Free a lock which is not in use. */ 304 332 void locks_free_lock(struct file_lock *fl) 305 333 { ··· 902 874 struct file_lock *cfl; 903 875 struct file_lock_context *ctx; 904 876 struct inode *inode = locks_inode(filp); 877 + void *owner; 878 + void (*func)(void); 905 879 906 880 ctx = smp_load_acquire(&inode->i_flctx); 907 881 if (!ctx || list_empty_careful(&ctx->flc_posix)) { ··· 911 881 return; 912 882 } 913 883 884 + retry: 914 885 spin_lock(&ctx->flc_lock); 915 886 list_for_each_entry(cfl, &ctx->flc_posix, fl_list) { 916 - if (posix_locks_conflict(fl, cfl)) { 917 - locks_copy_conflock(fl, cfl); 918 - goto out; 887 + if (!posix_locks_conflict(fl, cfl)) 888 + continue; 889 + if (cfl->fl_lmops && cfl->fl_lmops->lm_lock_expirable 890 + && (*cfl->fl_lmops->lm_lock_expirable)(cfl)) { 891 + owner = cfl->fl_lmops->lm_mod_owner; 892 + func = cfl->fl_lmops->lm_expire_lock; 893 + __module_get(owner); 894 + spin_unlock(&ctx->flc_lock); 895 + (*func)(); 896 + module_put(owner); 897 + goto retry; 919 898 } 899 + locks_copy_conflock(fl, cfl); 900 + goto out; 920 901 } 921 902 fl->fl_type = F_UNLCK; 922 903 out: ··· 1101 1060 int error; 1102 1061 bool added = false; 1103 1062 LIST_HEAD(dispose); 1063 + void *owner; 1064 + void (*func)(void); 1104 1065 1105 1066 ctx = locks_get_lock_context(inode, request->fl_type); 1106 1067 if (!ctx) ··· 1121 1078 new_fl2 = locks_alloc_lock(); 1122 1079 } 1123 1080 1081 + retry: 1124 1082 percpu_down_read(&file_rwsem); 1125 1083 spin_lock(&ctx->flc_lock); 1126 1084 /* ··· 1133 1089 list_for_each_entry(fl, &ctx->flc_posix, fl_list) { 1134 1090 if (!posix_locks_conflict(request, fl)) 1135 1091 continue; 1092 + if (fl->fl_lmops && fl->fl_lmops->lm_lock_expirable 1093 + && (*fl->fl_lmops->lm_lock_expirable)(fl)) { 1094 + owner = fl->fl_lmops->lm_mod_owner; 1095 + func = fl->fl_lmops->lm_expire_lock; 1096 + __module_get(owner); 1097 + spin_unlock(&ctx->flc_lock); 1098 + percpu_up_read(&file_rwsem); 1099 + (*func)(); 1100 + module_put(owner); 1101 + goto retry; 1102 + } 1136 1103 if (conflock) 1137 1104 locks_copy_conflock(conflock, fl); 1138 1105 error = -EAGAIN;
+47 -7
fs/nfsd/filecache.c
··· 303 303 void 304 304 nfsd_file_put(struct nfsd_file *nf) 305 305 { 306 + might_sleep(); 307 + 306 308 set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); 307 309 if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) { 308 310 nfsd_file_flush(nf); ··· 901 899 return ret; 902 900 } 903 901 904 - __be32 905 - nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, 906 - unsigned int may_flags, struct nfsd_file **pnf) 902 + static __be32 903 + nfsd_do_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, 904 + unsigned int may_flags, struct nfsd_file **pnf, bool open) 907 905 { 908 906 __be32 status; 909 907 struct net *net = SVC_NET(rqstp); ··· 998 996 nfsd_file_gc(); 999 997 1000 998 nf->nf_mark = nfsd_file_mark_find_or_create(nf); 1001 - if (nf->nf_mark) 1002 - status = nfsd_open_verified(rqstp, fhp, S_IFREG, 1003 - may_flags, &nf->nf_file); 1004 - else 999 + if (nf->nf_mark) { 1000 + if (open) { 1001 + status = nfsd_open_verified(rqstp, fhp, may_flags, 1002 + &nf->nf_file); 1003 + trace_nfsd_file_open(nf, status); 1004 + } else 1005 + status = nfs_ok; 1006 + } else 1005 1007 status = nfserr_jukebox; 1006 1008 /* 1007 1009 * If construction failed, or we raced with a call to unlink() ··· 1023 1017 smp_mb__after_atomic(); 1024 1018 wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING); 1025 1019 goto out; 1020 + } 1021 + 1022 + /** 1023 + * nfsd_file_acquire - Get a struct nfsd_file with an open file 1024 + * @rqstp: the RPC transaction being executed 1025 + * @fhp: the NFS filehandle of the file to be opened 1026 + * @may_flags: NFSD_MAY_ settings for the file 1027 + * @pnf: OUT: new or found "struct nfsd_file" object 1028 + * 1029 + * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in 1030 + * network byte order is returned. 1031 + */ 1032 + __be32 1033 + nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, 1034 + unsigned int may_flags, struct nfsd_file **pnf) 1035 + { 1036 + return nfsd_do_file_acquire(rqstp, fhp, may_flags, pnf, true); 1037 + } 1038 + 1039 + /** 1040 + * nfsd_file_create - Get a struct nfsd_file, do not open 1041 + * @rqstp: the RPC transaction being executed 1042 + * @fhp: the NFS filehandle of the file just created 1043 + * @may_flags: NFSD_MAY_ settings for the file 1044 + * @pnf: OUT: new or found "struct nfsd_file" object 1045 + * 1046 + * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in 1047 + * network byte order is returned. 1048 + */ 1049 + __be32 1050 + nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp, 1051 + unsigned int may_flags, struct nfsd_file **pnf) 1052 + { 1053 + return nfsd_do_file_acquire(rqstp, fhp, may_flags, pnf, false); 1026 1054 } 1027 1055 1028 1056 /*
+2
fs/nfsd/filecache.h
··· 59 59 bool nfsd_file_is_cached(struct inode *inode); 60 60 __be32 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, 61 61 unsigned int may_flags, struct nfsd_file **nfp); 62 + __be32 nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp, 63 + unsigned int may_flags, struct nfsd_file **nfp); 62 64 int nfsd_file_cache_stats_open(struct inode *, struct file *); 63 65 #endif /* _FS_NFSD_FILECACHE_H */
+122 -19
fs/nfsd/nfs3proc.c
··· 8 8 #include <linux/fs.h> 9 9 #include <linux/ext2_fs.h> 10 10 #include <linux/magic.h> 11 + #include <linux/namei.h> 11 12 12 13 #include "cache.h" 13 14 #include "xdr3.h" ··· 221 220 } 222 221 223 222 /* 224 - * With NFSv3, CREATE processing is a lot easier than with NFSv2. 225 - * At least in theory; we'll see how it fares in practice when the 226 - * first reports about SunOS compatibility problems start to pour in... 223 + * Implement NFSv3's unchecked, guarded, and exclusive CREATE 224 + * semantics for regular files. Except for the created file, 225 + * this operation is stateless on the server. 226 + * 227 + * Upon return, caller must release @fhp and @resfhp. 227 228 */ 229 + static __be32 230 + nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, 231 + struct svc_fh *resfhp, struct nfsd3_createargs *argp) 232 + { 233 + struct iattr *iap = &argp->attrs; 234 + struct dentry *parent, *child; 235 + __u32 v_mtime, v_atime; 236 + struct inode *inode; 237 + __be32 status; 238 + int host_err; 239 + 240 + if (isdotent(argp->name, argp->len)) 241 + return nfserr_exist; 242 + if (!(iap->ia_valid & ATTR_MODE)) 243 + iap->ia_mode = 0; 244 + 245 + status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); 246 + if (status != nfs_ok) 247 + return status; 248 + 249 + parent = fhp->fh_dentry; 250 + inode = d_inode(parent); 251 + 252 + host_err = fh_want_write(fhp); 253 + if (host_err) 254 + return nfserrno(host_err); 255 + 256 + fh_lock_nested(fhp, I_MUTEX_PARENT); 257 + 258 + child = lookup_one_len(argp->name, parent, argp->len); 259 + if (IS_ERR(child)) { 260 + status = nfserrno(PTR_ERR(child)); 261 + goto out; 262 + } 263 + 264 + if (d_really_is_negative(child)) { 265 + status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); 266 + if (status != nfs_ok) 267 + goto out; 268 + } 269 + 270 + status = fh_compose(resfhp, fhp->fh_export, child, fhp); 271 + if (status != nfs_ok) 272 + goto out; 273 + 274 + v_mtime = 0; 275 + v_atime = 0; 276 + if (argp->createmode == NFS3_CREATE_EXCLUSIVE) { 277 + u32 *verifier = (u32 *)argp->verf; 278 + 279 + /* 280 + * Solaris 7 gets confused (bugid 4218508) if these have 281 + * the high bit set, as do xfs filesystems without the 282 + * "bigtime" feature. So just clear the high bits. 283 + */ 284 + v_mtime = verifier[0] & 0x7fffffff; 285 + v_atime = verifier[1] & 0x7fffffff; 286 + } 287 + 288 + if (d_really_is_positive(child)) { 289 + status = nfs_ok; 290 + 291 + switch (argp->createmode) { 292 + case NFS3_CREATE_UNCHECKED: 293 + if (!d_is_reg(child)) 294 + break; 295 + iap->ia_valid &= ATTR_SIZE; 296 + goto set_attr; 297 + case NFS3_CREATE_GUARDED: 298 + status = nfserr_exist; 299 + break; 300 + case NFS3_CREATE_EXCLUSIVE: 301 + if (d_inode(child)->i_mtime.tv_sec == v_mtime && 302 + d_inode(child)->i_atime.tv_sec == v_atime && 303 + d_inode(child)->i_size == 0) { 304 + break; 305 + } 306 + status = nfserr_exist; 307 + } 308 + goto out; 309 + } 310 + 311 + if (!IS_POSIXACL(inode)) 312 + iap->ia_mode &= ~current_umask(); 313 + 314 + host_err = vfs_create(&init_user_ns, inode, child, iap->ia_mode, true); 315 + if (host_err < 0) { 316 + status = nfserrno(host_err); 317 + goto out; 318 + } 319 + 320 + /* A newly created file already has a file size of zero. */ 321 + if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0)) 322 + iap->ia_valid &= ~ATTR_SIZE; 323 + if (argp->createmode == NFS3_CREATE_EXCLUSIVE) { 324 + iap->ia_valid = ATTR_MTIME | ATTR_ATIME | 325 + ATTR_MTIME_SET | ATTR_ATIME_SET; 326 + iap->ia_mtime.tv_sec = v_mtime; 327 + iap->ia_atime.tv_sec = v_atime; 328 + iap->ia_mtime.tv_nsec = 0; 329 + iap->ia_atime.tv_nsec = 0; 330 + } 331 + 332 + set_attr: 333 + status = nfsd_create_setattr(rqstp, fhp, resfhp, iap); 334 + 335 + out: 336 + fh_unlock(fhp); 337 + if (child && !IS_ERR(child)) 338 + dput(child); 339 + fh_drop_write(fhp); 340 + return status; 341 + } 342 + 228 343 static __be32 229 344 nfsd3_proc_create(struct svc_rqst *rqstp) 230 345 { 231 346 struct nfsd3_createargs *argp = rqstp->rq_argp; 232 347 struct nfsd3_diropres *resp = rqstp->rq_resp; 233 - svc_fh *dirfhp, *newfhp = NULL; 234 - struct iattr *attr; 348 + svc_fh *dirfhp, *newfhp; 235 349 236 350 dprintk("nfsd: CREATE(3) %s %.*s\n", 237 351 SVCFH_fmt(&argp->fh), ··· 355 239 356 240 dirfhp = fh_copy(&resp->dirfh, &argp->fh); 357 241 newfhp = fh_init(&resp->fh, NFS3_FHSIZE); 358 - attr = &argp->attrs; 359 242 360 - /* Unfudge the mode bits */ 361 - attr->ia_mode &= ~S_IFMT; 362 - if (!(attr->ia_valid & ATTR_MODE)) { 363 - attr->ia_valid |= ATTR_MODE; 364 - attr->ia_mode = S_IFREG; 365 - } else { 366 - attr->ia_mode = (attr->ia_mode & ~S_IFMT) | S_IFREG; 367 - } 368 - 369 - /* Now create the file and set attributes */ 370 - resp->status = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len, 371 - attr, newfhp, argp->createmode, 372 - (u32 *)argp->verf, NULL, NULL); 243 + resp->status = nfsd3_create_file(rqstp, dirfhp, newfhp, argp); 373 244 return rpc_success; 374 245 } 375 246
+217 -47
fs/nfsd/nfs4proc.c
··· 37 37 #include <linux/falloc.h> 38 38 #include <linux/slab.h> 39 39 #include <linux/kthread.h> 40 + #include <linux/namei.h> 41 + 40 42 #include <linux/sunrpc/addr.h> 41 43 #include <linux/nfs_ssc.h> 42 44 ··· 237 235 &resfh->fh_handle); 238 236 } 239 237 238 + static inline bool nfsd4_create_is_exclusive(int createmode) 239 + { 240 + return createmode == NFS4_CREATE_EXCLUSIVE || 241 + createmode == NFS4_CREATE_EXCLUSIVE4_1; 242 + } 243 + 244 + static __be32 245 + nfsd4_vfs_create(struct svc_fh *fhp, struct dentry *child, 246 + struct nfsd4_open *open) 247 + { 248 + struct file *filp; 249 + struct path path; 250 + int oflags; 251 + 252 + oflags = O_CREAT | O_LARGEFILE; 253 + switch (open->op_share_access & NFS4_SHARE_ACCESS_BOTH) { 254 + case NFS4_SHARE_ACCESS_WRITE: 255 + oflags |= O_WRONLY; 256 + break; 257 + case NFS4_SHARE_ACCESS_BOTH: 258 + oflags |= O_RDWR; 259 + break; 260 + default: 261 + oflags |= O_RDONLY; 262 + } 263 + 264 + path.mnt = fhp->fh_export->ex_path.mnt; 265 + path.dentry = child; 266 + filp = dentry_create(&path, oflags, open->op_iattr.ia_mode, 267 + current_cred()); 268 + if (IS_ERR(filp)) 269 + return nfserrno(PTR_ERR(filp)); 270 + 271 + open->op_filp = filp; 272 + return nfs_ok; 273 + } 274 + 275 + /* 276 + * Implement NFSv4's unchecked, guarded, and exclusive create 277 + * semantics for regular files. Open state for this new file is 278 + * subsequently fabricated in nfsd4_process_open2(). 279 + * 280 + * Upon return, caller must release @fhp and @resfhp. 281 + */ 282 + static __be32 283 + nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, 284 + struct svc_fh *resfhp, struct nfsd4_open *open) 285 + { 286 + struct iattr *iap = &open->op_iattr; 287 + struct dentry *parent, *child; 288 + __u32 v_mtime, v_atime; 289 + struct inode *inode; 290 + __be32 status; 291 + int host_err; 292 + 293 + if (isdotent(open->op_fname, open->op_fnamelen)) 294 + return nfserr_exist; 295 + if (!(iap->ia_valid & ATTR_MODE)) 296 + iap->ia_mode = 0; 297 + 298 + status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); 299 + if (status != nfs_ok) 300 + return status; 301 + parent = fhp->fh_dentry; 302 + inode = d_inode(parent); 303 + 304 + host_err = fh_want_write(fhp); 305 + if (host_err) 306 + return nfserrno(host_err); 307 + 308 + fh_lock_nested(fhp, I_MUTEX_PARENT); 309 + 310 + child = lookup_one_len(open->op_fname, parent, open->op_fnamelen); 311 + if (IS_ERR(child)) { 312 + status = nfserrno(PTR_ERR(child)); 313 + goto out; 314 + } 315 + 316 + if (d_really_is_negative(child)) { 317 + status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); 318 + if (status != nfs_ok) 319 + goto out; 320 + } 321 + 322 + status = fh_compose(resfhp, fhp->fh_export, child, fhp); 323 + if (status != nfs_ok) 324 + goto out; 325 + 326 + v_mtime = 0; 327 + v_atime = 0; 328 + if (nfsd4_create_is_exclusive(open->op_createmode)) { 329 + u32 *verifier = (u32 *)open->op_verf.data; 330 + 331 + /* 332 + * Solaris 7 gets confused (bugid 4218508) if these have 333 + * the high bit set, as do xfs filesystems without the 334 + * "bigtime" feature. So just clear the high bits. If this 335 + * is ever changed to use different attrs for storing the 336 + * verifier, then do_open_lookup() will also need to be 337 + * fixed accordingly. 338 + */ 339 + v_mtime = verifier[0] & 0x7fffffff; 340 + v_atime = verifier[1] & 0x7fffffff; 341 + } 342 + 343 + if (d_really_is_positive(child)) { 344 + status = nfs_ok; 345 + 346 + switch (open->op_createmode) { 347 + case NFS4_CREATE_UNCHECKED: 348 + if (!d_is_reg(child)) 349 + break; 350 + 351 + /* 352 + * In NFSv4, we don't want to truncate the file 353 + * now. This would be wrong if the OPEN fails for 354 + * some other reason. Furthermore, if the size is 355 + * nonzero, we should ignore it according to spec! 356 + */ 357 + open->op_truncate = (iap->ia_valid & ATTR_SIZE) && 358 + !iap->ia_size; 359 + break; 360 + case NFS4_CREATE_GUARDED: 361 + status = nfserr_exist; 362 + break; 363 + case NFS4_CREATE_EXCLUSIVE: 364 + if (d_inode(child)->i_mtime.tv_sec == v_mtime && 365 + d_inode(child)->i_atime.tv_sec == v_atime && 366 + d_inode(child)->i_size == 0) { 367 + open->op_created = true; 368 + break; /* subtle */ 369 + } 370 + status = nfserr_exist; 371 + break; 372 + case NFS4_CREATE_EXCLUSIVE4_1: 373 + if (d_inode(child)->i_mtime.tv_sec == v_mtime && 374 + d_inode(child)->i_atime.tv_sec == v_atime && 375 + d_inode(child)->i_size == 0) { 376 + open->op_created = true; 377 + goto set_attr; /* subtle */ 378 + } 379 + status = nfserr_exist; 380 + } 381 + goto out; 382 + } 383 + 384 + if (!IS_POSIXACL(inode)) 385 + iap->ia_mode &= ~current_umask(); 386 + 387 + status = nfsd4_vfs_create(fhp, child, open); 388 + if (status != nfs_ok) 389 + goto out; 390 + open->op_created = true; 391 + 392 + /* A newly created file already has a file size of zero. */ 393 + if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0)) 394 + iap->ia_valid &= ~ATTR_SIZE; 395 + if (nfsd4_create_is_exclusive(open->op_createmode)) { 396 + iap->ia_valid = ATTR_MTIME | ATTR_ATIME | 397 + ATTR_MTIME_SET|ATTR_ATIME_SET; 398 + iap->ia_mtime.tv_sec = v_mtime; 399 + iap->ia_atime.tv_sec = v_atime; 400 + iap->ia_mtime.tv_nsec = 0; 401 + iap->ia_atime.tv_nsec = 0; 402 + } 403 + 404 + set_attr: 405 + status = nfsd_create_setattr(rqstp, fhp, resfhp, iap); 406 + 407 + out: 408 + fh_unlock(fhp); 409 + if (child && !IS_ERR(child)) 410 + dput(child); 411 + fh_drop_write(fhp); 412 + return status; 413 + } 414 + 240 415 static __be32 241 416 do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh **resfh) 242 417 { ··· 443 264 * yes | yes | GUARDED4 | GUARDED4 444 265 */ 445 266 446 - /* 447 - * Note: create modes (UNCHECKED,GUARDED...) are the same 448 - * in NFSv4 as in v3 except EXCLUSIVE4_1. 449 - */ 450 267 current->fs->umask = open->op_umask; 451 - status = do_nfsd_create(rqstp, current_fh, open->op_fname, 452 - open->op_fnamelen, &open->op_iattr, 453 - *resfh, open->op_createmode, 454 - (u32 *)open->op_verf.data, 455 - &open->op_truncate, &open->op_created); 268 + status = nfsd4_create_file(rqstp, current_fh, *resfh, open); 456 269 current->fs->umask = 0; 457 270 458 271 if (!status && open->op_label.len) ··· 455 284 * use the returned bitmask to indicate which attributes 456 285 * we used to store the verifier: 457 286 */ 458 - if (nfsd_create_is_exclusive(open->op_createmode) && status == 0) 287 + if (nfsd4_create_is_exclusive(open->op_createmode) && status == 0) 459 288 open->op_bmval[1] |= (FATTR4_WORD1_TIME_ACCESS | 460 289 FATTR4_WORD1_TIME_MODIFY); 461 290 } else ··· 546 375 (int)open->op_fnamelen, open->op_fname, 547 376 open->op_openowner); 548 377 378 + open->op_filp = NULL; 379 + 549 380 /* This check required by spec. */ 550 381 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 551 382 return nfserr_inval; ··· 600 427 goto out; 601 428 602 429 switch (open->op_claim_type) { 603 - case NFS4_OPEN_CLAIM_DELEGATE_CUR: 604 - case NFS4_OPEN_CLAIM_NULL: 605 - status = do_open_lookup(rqstp, cstate, open, &resfh); 606 - if (status) 607 - goto out; 608 - break; 609 - case NFS4_OPEN_CLAIM_PREVIOUS: 610 - status = nfs4_check_open_reclaim(cstate->clp); 611 - if (status) 612 - goto out; 613 - open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 614 - reclaim = true; 615 - fallthrough; 616 - case NFS4_OPEN_CLAIM_FH: 617 - case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 618 - status = do_open_fhandle(rqstp, cstate, open); 619 - if (status) 620 - goto out; 621 - resfh = &cstate->current_fh; 622 - break; 623 - case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 624 - case NFS4_OPEN_CLAIM_DELEGATE_PREV: 625 - dprintk("NFSD: unsupported OPEN claim type %d\n", 626 - open->op_claim_type); 627 - status = nfserr_notsupp; 430 + case NFS4_OPEN_CLAIM_DELEGATE_CUR: 431 + case NFS4_OPEN_CLAIM_NULL: 432 + status = do_open_lookup(rqstp, cstate, open, &resfh); 433 + if (status) 628 434 goto out; 629 - default: 630 - dprintk("NFSD: Invalid OPEN claim type %d\n", 631 - open->op_claim_type); 632 - status = nfserr_inval; 435 + break; 436 + case NFS4_OPEN_CLAIM_PREVIOUS: 437 + status = nfs4_check_open_reclaim(cstate->clp); 438 + if (status) 633 439 goto out; 440 + open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 441 + reclaim = true; 442 + fallthrough; 443 + case NFS4_OPEN_CLAIM_FH: 444 + case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 445 + status = do_open_fhandle(rqstp, cstate, open); 446 + if (status) 447 + goto out; 448 + resfh = &cstate->current_fh; 449 + break; 450 + case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 451 + case NFS4_OPEN_CLAIM_DELEGATE_PREV: 452 + status = nfserr_notsupp; 453 + goto out; 454 + default: 455 + status = nfserr_inval; 456 + goto out; 634 457 } 635 - /* 636 - * nfsd4_process_open2() does the actual opening of the file. If 637 - * successful, it (1) truncates the file if open->op_truncate was 638 - * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 639 - */ 458 + 640 459 status = nfsd4_process_open2(rqstp, resfh, open); 641 460 WARN(status && open->op_created, 642 461 "nfsd4_process_open2 failed to open newly-created file! status=%u\n", ··· 636 471 if (reclaim && !status) 637 472 nn->somebody_reclaimed = true; 638 473 out: 474 + if (open->op_filp) { 475 + fput(open->op_filp); 476 + open->op_filp = NULL; 477 + } 639 478 if (resfh && resfh != &cstate->current_fh) { 640 479 fh_dup2(&cstate->current_fh, resfh); 641 480 fh_put(resfh); ··· 970 801 * the client wants us to do more in this compound: 971 802 */ 972 803 if (!nfsd4_last_compound_op(rqstp)) 973 - clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 804 + __clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 974 805 975 806 /* check stateid */ 976 807 status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, ··· 2650 2481 cstate->minorversion = args->minorversion; 2651 2482 fh_init(current_fh, NFS4_FHSIZE); 2652 2483 fh_init(save_fh, NFS4_FHSIZE); 2484 + 2653 2485 /* 2654 2486 * Don't use the deferral mechanism for NFSv4; compounds make it 2655 2487 * too hard to avoid non-idempotency problems. 2656 2488 */ 2657 - clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); 2489 + __clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); 2658 2490 2659 2491 /* 2660 2492 * According to RFC3010, this takes precedence over all other errors. ··· 2770 2600 out: 2771 2601 cstate->status = status; 2772 2602 /* Reset deferral mechanism for RPC deferrals */ 2773 - set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); 2603 + __set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); 2774 2604 return rpc_success; 2775 2605 } 2776 2606
+285 -70
fs/nfsd/nfs4state.c
··· 125 125 static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; 126 126 static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; 127 127 128 + static struct workqueue_struct *laundry_wq; 129 + 130 + int nfsd4_create_laundry_wq(void) 131 + { 132 + int rc = 0; 133 + 134 + laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); 135 + if (laundry_wq == NULL) 136 + rc = -ENOMEM; 137 + return rc; 138 + } 139 + 140 + void nfsd4_destroy_laundry_wq(void) 141 + { 142 + destroy_workqueue(laundry_wq); 143 + } 144 + 128 145 static bool is_session_dead(struct nfsd4_session *ses) 129 146 { 130 147 return ses->se_flags & NFS4_SESSION_DEAD; ··· 169 152 if (is_client_expired(clp)) 170 153 return nfserr_expired; 171 154 atomic_inc(&clp->cl_rpc_users); 155 + clp->cl_state = NFSD4_ACTIVE; 172 156 return nfs_ok; 173 157 } 174 158 ··· 190 172 191 173 list_move_tail(&clp->cl_lru, &nn->client_lru); 192 174 clp->cl_time = ktime_get_boottime_seconds(); 175 + clp->cl_state = NFSD4_ACTIVE; 193 176 } 194 177 195 178 static void put_client_renew_locked(struct nfs4_client *clp) ··· 709 690 710 691 static struct hlist_head file_hashtbl[FILE_HASH_SIZE]; 711 692 693 + /* 694 + * Check if courtesy clients have conflicting access and resolve it if possible 695 + * 696 + * access: is op_share_access if share_access is true. 697 + * Check if access mode, op_share_access, would conflict with 698 + * the current deny mode of the file 'fp'. 699 + * access: is op_share_deny if share_access is false. 700 + * Check if the deny mode, op_share_deny, would conflict with 701 + * current access of the file 'fp'. 702 + * stp: skip checking this entry. 703 + * new_stp: normal open, not open upgrade. 704 + * 705 + * Function returns: 706 + * false - access/deny mode conflict with normal client. 707 + * true - no conflict or conflict with courtesy client(s) is resolved. 708 + */ 709 + static bool 710 + nfs4_resolve_deny_conflicts_locked(struct nfs4_file *fp, bool new_stp, 711 + struct nfs4_ol_stateid *stp, u32 access, bool share_access) 712 + { 713 + struct nfs4_ol_stateid *st; 714 + bool resolvable = true; 715 + unsigned char bmap; 716 + struct nfsd_net *nn; 717 + struct nfs4_client *clp; 718 + 719 + lockdep_assert_held(&fp->fi_lock); 720 + list_for_each_entry(st, &fp->fi_stateids, st_perfile) { 721 + /* ignore lock stateid */ 722 + if (st->st_openstp) 723 + continue; 724 + if (st == stp && new_stp) 725 + continue; 726 + /* check file access against deny mode or vice versa */ 727 + bmap = share_access ? st->st_deny_bmap : st->st_access_bmap; 728 + if (!(access & bmap_to_share_mode(bmap))) 729 + continue; 730 + clp = st->st_stid.sc_client; 731 + if (try_to_expire_client(clp)) 732 + continue; 733 + resolvable = false; 734 + break; 735 + } 736 + if (resolvable) { 737 + clp = stp->st_stid.sc_client; 738 + nn = net_generic(clp->net, nfsd_net_id); 739 + mod_delayed_work(laundry_wq, &nn->laundromat_work, 0); 740 + } 741 + return resolvable; 742 + } 743 + 712 744 static void 713 745 __nfs4_file_get_access(struct nfs4_file *fp, u32 access) 714 746 { ··· 1160 1090 get_clnt_odstate(odstate); 1161 1091 dp->dl_type = NFS4_OPEN_DELEGATE_READ; 1162 1092 dp->dl_retries = 1; 1093 + dp->dl_recalled = false; 1163 1094 nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, 1164 1095 &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL); 1165 1096 get_nfs4_file(fp); ··· 2075 2004 idr_init(&clp->cl_stateids); 2076 2005 atomic_set(&clp->cl_rpc_users, 0); 2077 2006 clp->cl_cb_state = NFSD4_CB_UNKNOWN; 2007 + clp->cl_state = NFSD4_ACTIVE; 2008 + atomic_set(&clp->cl_delegs_in_recall, 0); 2078 2009 INIT_LIST_HEAD(&clp->cl_idhash); 2079 2010 INIT_LIST_HEAD(&clp->cl_openowners); 2080 2011 INIT_LIST_HEAD(&clp->cl_delegations); ··· 2481 2408 memcpy(&clid, &clp->cl_clientid, sizeof(clid)); 2482 2409 seq_printf(m, "clientid: 0x%llx\n", clid); 2483 2410 seq_printf(m, "address: \"%pISpc\"\n", (struct sockaddr *)&clp->cl_addr); 2484 - if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags)) 2411 + 2412 + if (clp->cl_state == NFSD4_COURTESY) 2413 + seq_puts(m, "status: courtesy\n"); 2414 + else if (clp->cl_state == NFSD4_EXPIRABLE) 2415 + seq_puts(m, "status: expirable\n"); 2416 + else if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags)) 2485 2417 seq_puts(m, "status: confirmed\n"); 2486 2418 else 2487 2419 seq_puts(m, "status: unconfirmed\n"); 2420 + seq_printf(m, "seconds from last renew: %lld\n", 2421 + ktime_get_boottime_seconds() - clp->cl_time); 2488 2422 seq_printf(m, "name: "); 2489 2423 seq_quote_mem(m, clp->cl_name.data, clp->cl_name.len); 2490 2424 seq_printf(m, "\nminor version: %d\n", clp->cl_minorversion); ··· 4774 4694 bool ret = false; 4775 4695 struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner; 4776 4696 struct nfs4_file *fp = dp->dl_stid.sc_file; 4697 + struct nfs4_client *clp = dp->dl_stid.sc_client; 4698 + struct nfsd_net *nn; 4777 4699 4778 4700 trace_nfsd_cb_recall(&dp->dl_stid); 4701 + 4702 + dp->dl_recalled = true; 4703 + atomic_inc(&clp->cl_delegs_in_recall); 4704 + if (try_to_expire_client(clp)) { 4705 + nn = net_generic(clp->net, nfsd_net_id); 4706 + mod_delayed_work(laundry_wq, &nn->laundromat_work, 0); 4707 + } 4779 4708 4780 4709 /* 4781 4710 * We don't want the locks code to timeout the lease for us; ··· 4828 4739 nfsd_change_deleg_cb(struct file_lock *onlist, int arg, 4829 4740 struct list_head *dispose) 4830 4741 { 4831 - if (arg & F_UNLCK) 4742 + struct nfs4_delegation *dp = (struct nfs4_delegation *)onlist->fl_owner; 4743 + struct nfs4_client *clp = dp->dl_stid.sc_client; 4744 + 4745 + if (arg & F_UNLCK) { 4746 + if (dp->dl_recalled) 4747 + atomic_dec(&clp->cl_delegs_in_recall); 4832 4748 return lease_modify(onlist, arg, dispose); 4833 - else 4749 + } else 4834 4750 return -EAGAIN; 4835 4751 } 4836 4752 ··· 5041 4947 5042 4948 static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, 5043 4949 struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp, 5044 - struct nfsd4_open *open) 4950 + struct nfsd4_open *open, bool new_stp) 5045 4951 { 5046 4952 struct nfsd_file *nf = NULL; 5047 4953 __be32 status; ··· 5057 4963 */ 5058 4964 status = nfs4_file_check_deny(fp, open->op_share_deny); 5059 4965 if (status != nfs_ok) { 4966 + if (status != nfserr_share_denied) { 4967 + spin_unlock(&fp->fi_lock); 4968 + goto out; 4969 + } 4970 + if (nfs4_resolve_deny_conflicts_locked(fp, new_stp, 4971 + stp, open->op_share_deny, false)) 4972 + status = nfserr_jukebox; 5060 4973 spin_unlock(&fp->fi_lock); 5061 4974 goto out; 5062 4975 } ··· 5071 4970 /* set access to the file */ 5072 4971 status = nfs4_file_get_access(fp, open->op_share_access); 5073 4972 if (status != nfs_ok) { 4973 + if (status != nfserr_share_denied) { 4974 + spin_unlock(&fp->fi_lock); 4975 + goto out; 4976 + } 4977 + if (nfs4_resolve_deny_conflicts_locked(fp, new_stp, 4978 + stp, open->op_share_access, true)) 4979 + status = nfserr_jukebox; 5074 4980 spin_unlock(&fp->fi_lock); 5075 4981 goto out; 5076 4982 } ··· 5093 4985 5094 4986 if (!fp->fi_fds[oflag]) { 5095 4987 spin_unlock(&fp->fi_lock); 5096 - status = nfsd_file_acquire(rqstp, cur_fh, access, &nf); 5097 - if (status) 5098 - goto out_put_access; 4988 + 4989 + if (!open->op_filp) { 4990 + status = nfsd_file_acquire(rqstp, cur_fh, access, &nf); 4991 + if (status != nfs_ok) 4992 + goto out_put_access; 4993 + } else { 4994 + status = nfsd_file_create(rqstp, cur_fh, access, &nf); 4995 + if (status != nfs_ok) 4996 + goto out_put_access; 4997 + nf->nf_file = open->op_filp; 4998 + open->op_filp = NULL; 4999 + } 5000 + 5099 5001 spin_lock(&fp->fi_lock); 5100 5002 if (!fp->fi_fds[oflag]) { 5101 5003 fp->fi_fds[oflag] = nf; ··· 5134 5016 } 5135 5017 5136 5018 static __be32 5137 - nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp, struct nfsd4_open *open) 5019 + nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, 5020 + struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp, 5021 + struct nfsd4_open *open) 5138 5022 { 5139 5023 __be32 status; 5140 5024 unsigned char old_deny_bmap = stp->st_deny_bmap; 5141 5025 5142 5026 if (!test_access(open->op_share_access, stp)) 5143 - return nfs4_get_vfs_file(rqstp, fp, cur_fh, stp, open); 5027 + return nfs4_get_vfs_file(rqstp, fp, cur_fh, stp, open, false); 5144 5028 5145 5029 /* test and set deny mode */ 5146 5030 spin_lock(&fp->fi_lock); 5147 5031 status = nfs4_file_check_deny(fp, open->op_share_deny); 5148 5032 if (status == nfs_ok) { 5149 - set_deny(open->op_share_deny, stp); 5150 - fp->fi_share_deny |= 5033 + if (status != nfserr_share_denied) { 5034 + set_deny(open->op_share_deny, stp); 5035 + fp->fi_share_deny |= 5151 5036 (open->op_share_deny & NFS4_SHARE_DENY_BOTH); 5037 + } else { 5038 + if (nfs4_resolve_deny_conflicts_locked(fp, false, 5039 + stp, open->op_share_deny, false)) 5040 + status = nfserr_jukebox; 5041 + } 5152 5042 } 5153 5043 spin_unlock(&fp->fi_lock); 5154 5044 ··· 5448 5322 */ 5449 5323 } 5450 5324 5325 + /** 5326 + * nfsd4_process_open2 - finish open processing 5327 + * @rqstp: the RPC transaction being executed 5328 + * @current_fh: NFSv4 COMPOUND's current filehandle 5329 + * @open: OPEN arguments 5330 + * 5331 + * If successful, (1) truncate the file if open->op_truncate was 5332 + * set, (2) set open->op_stateid, (3) set open->op_delegation. 5333 + * 5334 + * Returns %nfs_ok on success; otherwise an nfs4stat value in 5335 + * network byte order is returned. 5336 + */ 5451 5337 __be32 5452 5338 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 5453 5339 { ··· 5509 5371 goto out; 5510 5372 } 5511 5373 } else { 5512 - status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open); 5374 + status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open, true); 5513 5375 if (status) { 5514 5376 stp->st_stid.sc_type = NFS4_CLOSED_STID; 5515 5377 release_open_stateid(stp); ··· 5743 5605 } 5744 5606 #endif 5745 5607 5608 + /* Check if any lock belonging to this lockowner has any blockers */ 5609 + static bool 5610 + nfs4_lockowner_has_blockers(struct nfs4_lockowner *lo) 5611 + { 5612 + struct file_lock_context *ctx; 5613 + struct nfs4_ol_stateid *stp; 5614 + struct nfs4_file *nf; 5615 + 5616 + list_for_each_entry(stp, &lo->lo_owner.so_stateids, st_perstateowner) { 5617 + nf = stp->st_stid.sc_file; 5618 + ctx = nf->fi_inode->i_flctx; 5619 + if (!ctx) 5620 + continue; 5621 + if (locks_owner_has_blockers(ctx, lo)) 5622 + return true; 5623 + } 5624 + return false; 5625 + } 5626 + 5627 + static bool 5628 + nfs4_anylock_blockers(struct nfs4_client *clp) 5629 + { 5630 + int i; 5631 + struct nfs4_stateowner *so; 5632 + struct nfs4_lockowner *lo; 5633 + 5634 + if (atomic_read(&clp->cl_delegs_in_recall)) 5635 + return true; 5636 + spin_lock(&clp->cl_lock); 5637 + for (i = 0; i < OWNER_HASH_SIZE; i++) { 5638 + list_for_each_entry(so, &clp->cl_ownerstr_hashtbl[i], 5639 + so_strhash) { 5640 + if (so->so_is_open_owner) 5641 + continue; 5642 + lo = lockowner(so); 5643 + if (nfs4_lockowner_has_blockers(lo)) { 5644 + spin_unlock(&clp->cl_lock); 5645 + return true; 5646 + } 5647 + } 5648 + } 5649 + spin_unlock(&clp->cl_lock); 5650 + return false; 5651 + } 5652 + 5653 + static void 5654 + nfs4_get_client_reaplist(struct nfsd_net *nn, struct list_head *reaplist, 5655 + struct laundry_time *lt) 5656 + { 5657 + struct list_head *pos, *next; 5658 + struct nfs4_client *clp; 5659 + 5660 + INIT_LIST_HEAD(reaplist); 5661 + spin_lock(&nn->client_lock); 5662 + list_for_each_safe(pos, next, &nn->client_lru) { 5663 + clp = list_entry(pos, struct nfs4_client, cl_lru); 5664 + if (clp->cl_state == NFSD4_EXPIRABLE) 5665 + goto exp_client; 5666 + if (!state_expired(lt, clp->cl_time)) 5667 + break; 5668 + if (!atomic_read(&clp->cl_rpc_users)) 5669 + clp->cl_state = NFSD4_COURTESY; 5670 + if (!client_has_state(clp) || 5671 + ktime_get_boottime_seconds() >= 5672 + (clp->cl_time + NFSD_COURTESY_CLIENT_TIMEOUT)) 5673 + goto exp_client; 5674 + if (nfs4_anylock_blockers(clp)) { 5675 + exp_client: 5676 + if (!mark_client_expired_locked(clp)) 5677 + list_add(&clp->cl_lru, reaplist); 5678 + } 5679 + } 5680 + spin_unlock(&nn->client_lock); 5681 + } 5682 + 5746 5683 static time64_t 5747 5684 nfs4_laundromat(struct nfsd_net *nn) 5748 5685 { ··· 5840 5627 goto out; 5841 5628 } 5842 5629 nfsd4_end_grace(nn); 5843 - INIT_LIST_HEAD(&reaplist); 5844 5630 5845 5631 spin_lock(&nn->s2s_cp_lock); 5846 5632 idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) { ··· 5849 5637 _free_cpntf_state_locked(nn, cps); 5850 5638 } 5851 5639 spin_unlock(&nn->s2s_cp_lock); 5852 - 5853 - spin_lock(&nn->client_lock); 5854 - list_for_each_safe(pos, next, &nn->client_lru) { 5855 - clp = list_entry(pos, struct nfs4_client, cl_lru); 5856 - if (!state_expired(&lt, clp->cl_time)) 5857 - break; 5858 - if (mark_client_expired_locked(clp)) 5859 - continue; 5860 - list_add(&clp->cl_lru, &reaplist); 5861 - } 5862 - spin_unlock(&nn->client_lock); 5640 + nfs4_get_client_reaplist(nn, &reaplist, &lt); 5863 5641 list_for_each_safe(pos, next, &reaplist) { 5864 5642 clp = list_entry(pos, struct nfs4_client, cl_lru); 5865 5643 trace_nfsd_clid_purged(&clp->cl_clientid); ··· 5924 5722 return max_t(time64_t, lt.new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT); 5925 5723 } 5926 5724 5927 - static struct workqueue_struct *laundry_wq; 5928 5725 static void laundromat_main(struct work_struct *); 5929 5726 5930 5727 static void ··· 6752 6551 nfs4_put_stateowner(&lo->lo_owner); 6753 6552 } 6754 6553 6554 + /* return pointer to struct nfs4_client if client is expirable */ 6555 + static bool 6556 + nfsd4_lm_lock_expirable(struct file_lock *cfl) 6557 + { 6558 + struct nfs4_lockowner *lo = (struct nfs4_lockowner *)cfl->fl_owner; 6559 + struct nfs4_client *clp = lo->lo_owner.so_client; 6560 + struct nfsd_net *nn; 6561 + 6562 + if (try_to_expire_client(clp)) { 6563 + nn = net_generic(clp->net, nfsd_net_id); 6564 + mod_delayed_work(laundry_wq, &nn->laundromat_work, 0); 6565 + return true; 6566 + } 6567 + return false; 6568 + } 6569 + 6570 + /* schedule laundromat to run immediately and wait for it to complete */ 6571 + static void 6572 + nfsd4_lm_expire_lock(void) 6573 + { 6574 + flush_workqueue(laundry_wq); 6575 + } 6576 + 6755 6577 static void 6756 6578 nfsd4_lm_notify(struct file_lock *fl) 6757 6579 { ··· 6801 6577 } 6802 6578 6803 6579 static const struct lock_manager_operations nfsd_posix_mng_ops = { 6580 + .lm_mod_owner = THIS_MODULE, 6804 6581 .lm_notify = nfsd4_lm_notify, 6805 6582 .lm_get_owner = nfsd4_lm_get_owner, 6806 6583 .lm_put_owner = nfsd4_lm_put_owner, 6584 + .lm_lock_expirable = nfsd4_lm_lock_expirable, 6585 + .lm_expire_lock = nfsd4_lm_expire_lock, 6807 6586 }; 6808 6587 6809 6588 static inline void ··· 7524 7297 return status; 7525 7298 } 7526 7299 7300 + /** 7301 + * nfsd4_release_lockowner - process NFSv4.0 RELEASE_LOCKOWNER operations 7302 + * @rqstp: RPC transaction 7303 + * @cstate: NFSv4 COMPOUND state 7304 + * @u: RELEASE_LOCKOWNER arguments 7305 + * 7306 + * The lockowner's so_count is bumped when a lock record is added 7307 + * or when copying a conflicting lock. The latter case is brief, 7308 + * but can lead to fleeting false positives when looking for 7309 + * locks-in-use. 7310 + * 7311 + * Return values: 7312 + * %nfs_ok: lockowner released or not found 7313 + * %nfserr_locks_held: lockowner still in use 7314 + * %nfserr_stale_clientid: clientid no longer active 7315 + * %nfserr_expired: clientid not recognized 7316 + */ 7527 7317 __be32 7528 7318 nfsd4_release_lockowner(struct svc_rqst *rqstp, 7529 7319 struct nfsd4_compound_state *cstate, 7530 7320 union nfsd4_op_u *u) 7531 7321 { 7532 7322 struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner; 7533 - clientid_t *clid = &rlockowner->rl_clientid; 7534 - struct nfs4_stateowner *sop; 7535 - struct nfs4_lockowner *lo = NULL; 7536 - struct nfs4_ol_stateid *stp; 7537 - struct xdr_netobj *owner = &rlockowner->rl_owner; 7538 - unsigned int hashval = ownerstr_hashval(owner); 7539 - __be32 status; 7540 7323 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 7324 + clientid_t *clid = &rlockowner->rl_clientid; 7325 + struct nfs4_ol_stateid *stp; 7326 + struct nfs4_lockowner *lo; 7541 7327 struct nfs4_client *clp; 7542 - LIST_HEAD (reaplist); 7328 + LIST_HEAD(reaplist); 7329 + __be32 status; 7543 7330 7544 7331 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", 7545 7332 clid->cl_boot, clid->cl_id); ··· 7561 7320 status = set_client(clid, cstate, nn); 7562 7321 if (status) 7563 7322 return status; 7564 - 7565 7323 clp = cstate->clp; 7566 - /* Find the matching lock stateowner */ 7324 + 7567 7325 spin_lock(&clp->cl_lock); 7568 - list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval], 7569 - so_strhash) { 7570 - 7571 - if (sop->so_is_open_owner || !same_owner_str(sop, owner)) 7572 - continue; 7573 - 7574 - /* see if there are still any locks associated with it */ 7575 - lo = lockowner(sop); 7576 - list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) { 7577 - if (check_for_locks(stp->st_stid.sc_file, lo)) { 7578 - status = nfserr_locks_held; 7579 - spin_unlock(&clp->cl_lock); 7580 - return status; 7581 - } 7582 - } 7583 - 7584 - nfs4_get_stateowner(sop); 7585 - break; 7586 - } 7326 + lo = find_lockowner_str_locked(clp, &rlockowner->rl_owner); 7587 7327 if (!lo) { 7588 7328 spin_unlock(&clp->cl_lock); 7589 - return status; 7329 + return nfs_ok; 7590 7330 } 7591 - 7331 + if (atomic_read(&lo->lo_owner.so_count) != 2) { 7332 + spin_unlock(&clp->cl_lock); 7333 + nfs4_put_stateowner(&lo->lo_owner); 7334 + return nfserr_locks_held; 7335 + } 7592 7336 unhash_lockowner_locked(lo); 7593 7337 while (!list_empty(&lo->lo_owner.so_stateids)) { 7594 7338 stp = list_first_entry(&lo->lo_owner.so_stateids, ··· 7583 7357 put_ol_stateid_locked(stp, &reaplist); 7584 7358 } 7585 7359 spin_unlock(&clp->cl_lock); 7360 + 7586 7361 free_ol_stateid_reaplist(&reaplist); 7587 7362 remove_blocked_locks(lo); 7588 7363 nfs4_put_stateowner(&lo->lo_owner); 7589 - 7590 - return status; 7364 + return nfs_ok; 7591 7365 } 7592 7366 7593 7367 static inline struct nfs4_client_reclaim * ··· 7828 7602 { 7829 7603 int ret; 7830 7604 7831 - laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); 7832 - if (laundry_wq == NULL) { 7833 - ret = -ENOMEM; 7834 - goto out; 7835 - } 7836 7605 ret = nfsd4_create_callback_queue(); 7837 7606 if (ret) 7838 - goto out_free_laundry; 7607 + return ret; 7839 7608 7840 7609 set_max_delegations(); 7841 7610 return 0; 7842 - 7843 - out_free_laundry: 7844 - destroy_workqueue(laundry_wq); 7845 - out: 7846 - return ret; 7847 7611 } 7848 7612 7849 7613 void ··· 7870 7654 void 7871 7655 nfs4_state_shutdown(void) 7872 7656 { 7873 - destroy_workqueue(laundry_wq); 7874 7657 nfsd4_destroy_callback_queue(); 7875 7658 } 7876 7659
+1 -1
fs/nfsd/nfs4xdr.c
··· 2411 2411 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; 2412 2412 2413 2413 if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack) 2414 - clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags); 2414 + __clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags); 2415 2415 2416 2416 return true; 2417 2417 }
+1 -1
fs/nfsd/nfscache.c
··· 206 206 struct svc_cacherep *rp; 207 207 unsigned int i; 208 208 209 - nfsd_reply_cache_stats_destroy(nn); 210 209 unregister_shrinker(&nn->nfsd_reply_cache_shrinker); 211 210 212 211 for (i = 0; i < nn->drc_hashsize; i++) { ··· 216 217 rp, nn); 217 218 } 218 219 } 220 + nfsd_reply_cache_stats_destroy(nn); 219 221 220 222 kvfree(nn->drc_hashtbl); 221 223 nn->drc_hashtbl = NULL;
+13 -7
fs/nfsd/nfsctl.c
··· 1535 1535 retval = create_proc_exports_entry(); 1536 1536 if (retval) 1537 1537 goto out_free_lockd; 1538 - retval = register_filesystem(&nfsd_fs_type); 1539 - if (retval) 1540 - goto out_free_exports; 1541 1538 retval = register_pernet_subsys(&nfsd_net_ops); 1542 1539 if (retval < 0) 1543 - goto out_free_filesystem; 1540 + goto out_free_exports; 1544 1541 retval = register_cld_notifier(); 1542 + if (retval) 1543 + goto out_free_subsys; 1544 + retval = nfsd4_create_laundry_wq(); 1545 + if (retval) 1546 + goto out_free_cld; 1547 + retval = register_filesystem(&nfsd_fs_type); 1545 1548 if (retval) 1546 1549 goto out_free_all; 1547 1550 return 0; 1548 1551 out_free_all: 1552 + nfsd4_destroy_laundry_wq(); 1553 + out_free_cld: 1554 + unregister_cld_notifier(); 1555 + out_free_subsys: 1549 1556 unregister_pernet_subsys(&nfsd_net_ops); 1550 - out_free_filesystem: 1551 - unregister_filesystem(&nfsd_fs_type); 1552 1557 out_free_exports: 1553 1558 remove_proc_entry("fs/nfs/exports", NULL); 1554 1559 remove_proc_entry("fs/nfs", NULL); ··· 1571 1566 1572 1567 static void __exit exit_nfsd(void) 1573 1568 { 1569 + unregister_filesystem(&nfsd_fs_type); 1570 + nfsd4_destroy_laundry_wq(); 1574 1571 unregister_cld_notifier(); 1575 1572 unregister_pernet_subsys(&nfsd_net_ops); 1576 1573 nfsd_drc_slab_free(); ··· 1582 1575 nfsd_lockd_shutdown(); 1583 1576 nfsd4_free_slabs(); 1584 1577 nfsd4_exit_pnfs(); 1585 - unregister_filesystem(&nfsd_fs_type); 1586 1578 } 1587 1579 1588 1580 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
+5
fs/nfsd/nfsd.h
··· 162 162 int nfs4_reset_recoverydir(char *recdir); 163 163 char * nfs4_recoverydir(void); 164 164 bool nfsd4_spo_must_allow(struct svc_rqst *rqstp); 165 + int nfsd4_create_laundry_wq(void); 166 + void nfsd4_destroy_laundry_wq(void); 165 167 #else 166 168 static inline int nfsd4_init_slabs(void) { return 0; } 167 169 static inline void nfsd4_free_slabs(void) { } ··· 177 175 { 178 176 return false; 179 177 } 178 + static inline int nfsd4_create_laundry_wq(void) { return 0; }; 179 + static inline void nfsd4_destroy_laundry_wq(void) {}; 180 180 #endif 181 181 182 182 /* ··· 340 336 #define COMPOUND_ERR_SLACK_SPACE 16 /* OP_SETATTR */ 341 337 342 338 #define NFSD_LAUNDROMAT_MINTIMEOUT 1 /* seconds */ 339 + #define NFSD_COURTESY_CLIENT_TIMEOUT (24 * 60 * 60) /* seconds */ 343 340 344 341 /* 345 342 * The following attributes are currently not supported by the NFSv4 server:
+31
fs/nfsd/state.h
··· 149 149 /* For recall: */ 150 150 int dl_retries; 151 151 struct nfsd4_callback dl_recall; 152 + bool dl_recalled; 152 153 }; 153 154 154 155 #define cb_to_delegation(cb) \ ··· 284 283 #define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */ 285 284 286 285 /* 286 + * State Meaning Where set 287 + * -------------------------------------------------------------------------- 288 + * | NFSD4_ACTIVE | Confirmed, active | Default | 289 + * |------------------- ----------------------------------------------------| 290 + * | NFSD4_COURTESY | Courtesy state. | nfs4_get_client_reaplist | 291 + * | | Lease/lock/share | | 292 + * | | reservation conflict | | 293 + * | | can cause Courtesy | | 294 + * | | client to be expired | | 295 + * |------------------------------------------------------------------------| 296 + * | NFSD4_EXPIRABLE | Courtesy client to be| nfs4_laundromat | 297 + * | | expired by Laundromat| try_to_expire_client | 298 + * | | due to conflict | | 299 + * |------------------------------------------------------------------------| 300 + */ 301 + enum { 302 + NFSD4_ACTIVE = 0, 303 + NFSD4_COURTESY, 304 + NFSD4_EXPIRABLE, 305 + }; 306 + 307 + /* 287 308 * struct nfs4_client - one per client. Clientids live here. 288 309 * 289 310 * The initial object created by an NFS client using SETCLIENTID (for NFSv4.0) ··· 408 385 struct list_head async_copies; /* list of async copies */ 409 386 spinlock_t async_lock; /* lock for async copies */ 410 387 atomic_t cl_cb_inflight; /* Outstanding callbacks */ 388 + 389 + unsigned int cl_state; 390 + atomic_t cl_delegs_in_recall; 411 391 }; 412 392 413 393 /* struct nfs4_client_reset ··· 728 702 extern int nfsd4_client_record_check(struct nfs4_client *clp); 729 703 extern void nfsd4_record_grace_done(struct nfsd_net *nn); 730 704 705 + static inline bool try_to_expire_client(struct nfs4_client *clp) 706 + { 707 + cmpxchg(&clp->cl_state, NFSD4_COURTESY, NFSD4_EXPIRABLE); 708 + return clp->cl_state == NFSD4_EXPIRABLE; 709 + } 731 710 #endif /* NFSD4_STATE_H */
+28 -6
fs/nfsd/trace.h
··· 692 692 /* 693 693 * from fs/nfsd/filecache.h 694 694 */ 695 - TRACE_DEFINE_ENUM(NFSD_FILE_HASHED); 696 - TRACE_DEFINE_ENUM(NFSD_FILE_PENDING); 697 - TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_READ); 698 - TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_WRITE); 699 - TRACE_DEFINE_ENUM(NFSD_FILE_REFERENCED); 700 - 701 695 #define show_nf_flags(val) \ 702 696 __print_flags(val, "|", \ 703 697 { 1 << NFSD_FILE_HASHED, "HASHED" }, \ ··· 777 783 show_nfsd_may_flags(__entry->nf_may), 778 784 __entry->nf_file, __entry->status) 779 785 ); 786 + 787 + TRACE_EVENT(nfsd_file_open, 788 + TP_PROTO(struct nfsd_file *nf, __be32 status), 789 + TP_ARGS(nf, status), 790 + TP_STRUCT__entry( 791 + __field(unsigned int, nf_hashval) 792 + __field(void *, nf_inode) /* cannot be dereferenced */ 793 + __field(int, nf_ref) 794 + __field(unsigned long, nf_flags) 795 + __field(unsigned long, nf_may) 796 + __field(void *, nf_file) /* cannot be dereferenced */ 797 + ), 798 + TP_fast_assign( 799 + __entry->nf_hashval = nf->nf_hashval; 800 + __entry->nf_inode = nf->nf_inode; 801 + __entry->nf_ref = refcount_read(&nf->nf_ref); 802 + __entry->nf_flags = nf->nf_flags; 803 + __entry->nf_may = nf->nf_may; 804 + __entry->nf_file = nf->nf_file; 805 + ), 806 + TP_printk("hash=0x%x inode=%p ref=%d flags=%s may=%s file=%p", 807 + __entry->nf_hashval, 808 + __entry->nf_inode, 809 + __entry->nf_ref, 810 + show_nf_flags(__entry->nf_flags), 811 + show_nfsd_may_flags(__entry->nf_may), 812 + __entry->nf_file) 813 + ) 780 814 781 815 DECLARE_EVENT_CLASS(nfsd_file_search_class, 782 816 TP_PROTO(struct inode *inode, unsigned int hash, int found),
+55 -200
fs/nfsd/vfs.c
··· 827 827 return err; 828 828 } 829 829 830 + /** 831 + * nfsd_open_verified - Open a regular file for the filecache 832 + * @rqstp: RPC request 833 + * @fhp: NFS filehandle of the file to open 834 + * @may_flags: internal permission flags 835 + * @filp: OUT: open "struct file *" 836 + * 837 + * Returns an nfsstat value in network byte order. 838 + */ 830 839 __be32 831 - nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, 832 - int may_flags, struct file **filp) 840 + nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, int may_flags, 841 + struct file **filp) 833 842 { 834 843 __be32 err; 835 844 836 845 validate_process_creds(); 837 - err = __nfsd_open(rqstp, fhp, type, may_flags, filp); 846 + err = __nfsd_open(rqstp, fhp, S_IFREG, may_flags, filp); 838 847 validate_process_creds(); 839 848 return err; 840 849 } ··· 858 849 struct splice_desc *sd) 859 850 { 860 851 struct svc_rqst *rqstp = sd->u.data; 861 - struct page **pp = rqstp->rq_next_page; 862 - struct page *page = buf->page; 863 852 864 - if (rqstp->rq_res.page_len == 0) { 865 - svc_rqst_replace_page(rqstp, page); 853 + svc_rqst_replace_page(rqstp, buf->page); 854 + if (rqstp->rq_res.page_len == 0) 866 855 rqstp->rq_res.page_base = buf->offset; 867 - } else if (page != pp[-1]) { 868 - svc_rqst_replace_page(rqstp, page); 869 - } 870 856 rqstp->rq_res.page_len += sd->len; 871 - 872 857 return sd->len; 873 858 } 874 859 ··· 1190 1187 return err; 1191 1188 } 1192 1189 1193 - static __be32 1194 - nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, 1195 - struct iattr *iap) 1190 + /** 1191 + * nfsd_create_setattr - Set a created file's attributes 1192 + * @rqstp: RPC transaction being executed 1193 + * @fhp: NFS filehandle of parent directory 1194 + * @resfhp: NFS filehandle of new object 1195 + * @iap: requested attributes of new object 1196 + * 1197 + * Returns nfs_ok on success, or an nfsstat in network byte order. 1198 + */ 1199 + __be32 1200 + nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 1201 + struct svc_fh *resfhp, struct iattr *iap) 1196 1202 { 1203 + __be32 status; 1204 + 1197 1205 /* 1198 - * Mode has already been set earlier in create: 1206 + * Mode has already been set by file creation. 1199 1207 */ 1200 1208 iap->ia_valid &= ~ATTR_MODE; 1209 + 1201 1210 /* 1202 1211 * Setting uid/gid works only for root. Irix appears to 1203 1212 * send along the gid on create when it tries to implement ··· 1217 1202 */ 1218 1203 if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) 1219 1204 iap->ia_valid &= ~(ATTR_UID|ATTR_GID); 1205 + 1206 + /* 1207 + * Callers expect new file metadata to be committed even 1208 + * if the attributes have not changed. 1209 + */ 1220 1210 if (iap->ia_valid) 1221 - return nfsd_setattr(rqstp, resfhp, iap, 0, (time64_t)0); 1222 - /* Callers expect file metadata to be committed here */ 1223 - return nfserrno(commit_metadata(resfhp)); 1211 + status = nfsd_setattr(rqstp, resfhp, iap, 0, (time64_t)0); 1212 + else 1213 + status = nfserrno(commit_metadata(resfhp)); 1214 + 1215 + /* 1216 + * Transactional filesystems had a chance to commit changes 1217 + * for both parent and child simultaneously making the 1218 + * following commit_metadata a noop in many cases. 1219 + */ 1220 + if (!status) 1221 + status = nfserrno(commit_metadata(fhp)); 1222 + 1223 + /* 1224 + * Update the new filehandle to pick up the new attributes. 1225 + */ 1226 + if (!status) 1227 + status = fh_update(resfhp); 1228 + 1229 + return status; 1224 1230 } 1225 1231 1226 1232 /* HPUX client sometimes creates a file in mode 000, and sets size to 0. ··· 1268 1232 struct dentry *dentry, *dchild; 1269 1233 struct inode *dirp; 1270 1234 __be32 err; 1271 - __be32 err2; 1272 1235 int host_err; 1273 1236 1274 1237 dentry = fhp->fh_dentry; ··· 1340 1305 if (host_err < 0) 1341 1306 goto out_nfserr; 1342 1307 1343 - err = nfsd_create_setattr(rqstp, resfhp, iap); 1308 + err = nfsd_create_setattr(rqstp, fhp, resfhp, iap); 1344 1309 1345 - /* 1346 - * nfsd_create_setattr already committed the child. Transactional 1347 - * filesystems had a chance to commit changes for both parent and 1348 - * child simultaneously making the following commit_metadata a 1349 - * noop. 1350 - */ 1351 - err2 = nfserrno(commit_metadata(fhp)); 1352 - if (err2) 1353 - err = err2; 1354 - /* 1355 - * Update the file handle to get the new inode info. 1356 - */ 1357 - if (!err) 1358 - err = fh_update(resfhp); 1359 1310 out: 1360 1311 dput(dchild); 1361 1312 return err; ··· 1394 1373 return err; 1395 1374 return nfsd_create_locked(rqstp, fhp, fname, flen, iap, type, 1396 1375 rdev, resfhp); 1397 - } 1398 - 1399 - /* 1400 - * NFSv3 and NFSv4 version of nfsd_create 1401 - */ 1402 - __be32 1403 - do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, 1404 - char *fname, int flen, struct iattr *iap, 1405 - struct svc_fh *resfhp, int createmode, u32 *verifier, 1406 - bool *truncp, bool *created) 1407 - { 1408 - struct dentry *dentry, *dchild = NULL; 1409 - struct inode *dirp; 1410 - __be32 err; 1411 - int host_err; 1412 - __u32 v_mtime=0, v_atime=0; 1413 - 1414 - err = nfserr_perm; 1415 - if (!flen) 1416 - goto out; 1417 - err = nfserr_exist; 1418 - if (isdotent(fname, flen)) 1419 - goto out; 1420 - if (!(iap->ia_valid & ATTR_MODE)) 1421 - iap->ia_mode = 0; 1422 - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); 1423 - if (err) 1424 - goto out; 1425 - 1426 - dentry = fhp->fh_dentry; 1427 - dirp = d_inode(dentry); 1428 - 1429 - host_err = fh_want_write(fhp); 1430 - if (host_err) 1431 - goto out_nfserr; 1432 - 1433 - fh_lock_nested(fhp, I_MUTEX_PARENT); 1434 - 1435 - /* 1436 - * Compose the response file handle. 1437 - */ 1438 - dchild = lookup_one_len(fname, dentry, flen); 1439 - host_err = PTR_ERR(dchild); 1440 - if (IS_ERR(dchild)) 1441 - goto out_nfserr; 1442 - 1443 - /* If file doesn't exist, check for permissions to create one */ 1444 - if (d_really_is_negative(dchild)) { 1445 - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); 1446 - if (err) 1447 - goto out; 1448 - } 1449 - 1450 - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); 1451 - if (err) 1452 - goto out; 1453 - 1454 - if (nfsd_create_is_exclusive(createmode)) { 1455 - /* solaris7 gets confused (bugid 4218508) if these have 1456 - * the high bit set, as do xfs filesystems without the 1457 - * "bigtime" feature. So just clear the high bits. If this is 1458 - * ever changed to use different attrs for storing the 1459 - * verifier, then do_open_lookup() will also need to be fixed 1460 - * accordingly. 1461 - */ 1462 - v_mtime = verifier[0]&0x7fffffff; 1463 - v_atime = verifier[1]&0x7fffffff; 1464 - } 1465 - 1466 - if (d_really_is_positive(dchild)) { 1467 - err = 0; 1468 - 1469 - switch (createmode) { 1470 - case NFS3_CREATE_UNCHECKED: 1471 - if (! d_is_reg(dchild)) 1472 - goto out; 1473 - else if (truncp) { 1474 - /* in nfsv4, we need to treat this case a little 1475 - * differently. we don't want to truncate the 1476 - * file now; this would be wrong if the OPEN 1477 - * fails for some other reason. furthermore, 1478 - * if the size is nonzero, we should ignore it 1479 - * according to spec! 1480 - */ 1481 - *truncp = (iap->ia_valid & ATTR_SIZE) && !iap->ia_size; 1482 - } 1483 - else { 1484 - iap->ia_valid &= ATTR_SIZE; 1485 - goto set_attr; 1486 - } 1487 - break; 1488 - case NFS3_CREATE_EXCLUSIVE: 1489 - if ( d_inode(dchild)->i_mtime.tv_sec == v_mtime 1490 - && d_inode(dchild)->i_atime.tv_sec == v_atime 1491 - && d_inode(dchild)->i_size == 0 ) { 1492 - if (created) 1493 - *created = true; 1494 - break; 1495 - } 1496 - fallthrough; 1497 - case NFS4_CREATE_EXCLUSIVE4_1: 1498 - if ( d_inode(dchild)->i_mtime.tv_sec == v_mtime 1499 - && d_inode(dchild)->i_atime.tv_sec == v_atime 1500 - && d_inode(dchild)->i_size == 0 ) { 1501 - if (created) 1502 - *created = true; 1503 - goto set_attr; 1504 - } 1505 - fallthrough; 1506 - case NFS3_CREATE_GUARDED: 1507 - err = nfserr_exist; 1508 - } 1509 - fh_drop_write(fhp); 1510 - goto out; 1511 - } 1512 - 1513 - if (!IS_POSIXACL(dirp)) 1514 - iap->ia_mode &= ~current_umask(); 1515 - 1516 - host_err = vfs_create(&init_user_ns, dirp, dchild, iap->ia_mode, true); 1517 - if (host_err < 0) { 1518 - fh_drop_write(fhp); 1519 - goto out_nfserr; 1520 - } 1521 - if (created) 1522 - *created = true; 1523 - 1524 - nfsd_check_ignore_resizing(iap); 1525 - 1526 - if (nfsd_create_is_exclusive(createmode)) { 1527 - /* Cram the verifier into atime/mtime */ 1528 - iap->ia_valid = ATTR_MTIME|ATTR_ATIME 1529 - | ATTR_MTIME_SET|ATTR_ATIME_SET; 1530 - /* XXX someone who knows this better please fix it for nsec */ 1531 - iap->ia_mtime.tv_sec = v_mtime; 1532 - iap->ia_atime.tv_sec = v_atime; 1533 - iap->ia_mtime.tv_nsec = 0; 1534 - iap->ia_atime.tv_nsec = 0; 1535 - } 1536 - 1537 - set_attr: 1538 - err = nfsd_create_setattr(rqstp, resfhp, iap); 1539 - 1540 - /* 1541 - * nfsd_create_setattr already committed the child 1542 - * (and possibly also the parent). 1543 - */ 1544 - if (!err) 1545 - err = nfserrno(commit_metadata(fhp)); 1546 - 1547 - /* 1548 - * Update the filehandle to get the new inode info. 1549 - */ 1550 - if (!err) 1551 - err = fh_update(resfhp); 1552 - 1553 - out: 1554 - fh_unlock(fhp); 1555 - if (dchild && !IS_ERR(dchild)) 1556 - dput(dchild); 1557 - fh_drop_write(fhp); 1558 - return err; 1559 - 1560 - out_nfserr: 1561 - err = nfserrno(host_err); 1562 - goto out; 1563 1376 } 1564 1377 1565 1378 /*
+3 -11
fs/nfsd/vfs.h
··· 69 69 char *name, int len, struct iattr *attrs, 70 70 int type, dev_t rdev, struct svc_fh *res); 71 71 __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); 72 - __be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, 73 - char *name, int len, struct iattr *attrs, 74 - struct svc_fh *res, int createmode, 75 - u32 *verifier, bool *truncp, bool *created); 72 + __be32 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 73 + struct svc_fh *resfhp, struct iattr *iap); 76 74 __be32 nfsd_commit(struct svc_rqst *rqst, struct svc_fh *fhp, 77 75 u64 offset, u32 count, __be32 *verf); 78 76 #ifdef CONFIG_NFSD_V4 ··· 86 88 int nfsd_open_break_lease(struct inode *, int); 87 89 __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, 88 90 int, struct file **); 89 - __be32 nfsd_open_verified(struct svc_rqst *, struct svc_fh *, umode_t, 91 + __be32 nfsd_open_verified(struct svc_rqst *, struct svc_fh *, 90 92 int, struct file **); 91 93 __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, 92 94 struct file *file, loff_t offset, ··· 155 157 .dentry = fh->fh_dentry}; 156 158 return nfserrno(vfs_getattr(&p, stat, STATX_BASIC_STATS, 157 159 AT_STATX_SYNC_AS_STAT)); 158 - } 159 - 160 - static inline int nfsd_create_is_exclusive(int createmode) 161 - { 162 - return createmode == NFS3_CREATE_EXCLUSIVE 163 - || createmode == NFS4_CREATE_EXCLUSIVE4_1; 164 160 } 165 161 166 162 #endif /* LINUX_NFSD_VFS_H */
+1
fs/nfsd/xdr4.h
··· 273 273 bool op_truncate; /* used during processing */ 274 274 bool op_created; /* used during processing */ 275 275 struct nfs4_openowner *op_openowner; /* used during processing */ 276 + struct file *op_filp; /* used during processing */ 276 277 struct nfs4_file *op_file; /* used during processing */ 277 278 struct nfs4_ol_stateid *op_stp; /* used during processing */ 278 279 struct nfs4_clnt_odstate *op_odstate; /* used during processing */
+42
fs/open.c
··· 980 980 } 981 981 EXPORT_SYMBOL(dentry_open); 982 982 983 + /** 984 + * dentry_create - Create and open a file 985 + * @path: path to create 986 + * @flags: O_ flags 987 + * @mode: mode bits for new file 988 + * @cred: credentials to use 989 + * 990 + * Caller must hold the parent directory's lock, and have prepared 991 + * a negative dentry, placed in @path->dentry, for the new file. 992 + * 993 + * Caller sets @path->mnt to the vfsmount of the filesystem where 994 + * the new file is to be created. The parent directory and the 995 + * negative dentry must reside on the same filesystem instance. 996 + * 997 + * On success, returns a "struct file *". Otherwise a ERR_PTR 998 + * is returned. 999 + */ 1000 + struct file *dentry_create(const struct path *path, int flags, umode_t mode, 1001 + const struct cred *cred) 1002 + { 1003 + struct file *f; 1004 + int error; 1005 + 1006 + validate_creds(cred); 1007 + f = alloc_empty_file(flags, cred); 1008 + if (IS_ERR(f)) 1009 + return f; 1010 + 1011 + error = vfs_create(mnt_user_ns(path->mnt), 1012 + d_inode(path->dentry->d_parent), 1013 + path->dentry, mode, true); 1014 + if (!error) 1015 + error = vfs_open(path, f); 1016 + 1017 + if (unlikely(error)) { 1018 + fput(f); 1019 + return ERR_PTR(error); 1020 + } 1021 + return f; 1022 + } 1023 + EXPORT_SYMBOL(dentry_create); 1024 + 983 1025 struct file *open_with_fake_path(const struct path *path, int flags, 984 1026 struct inode *inode, const struct cred *cred) 985 1027 {
+12
include/linux/fs.h
··· 1022 1022 }; 1023 1023 1024 1024 struct lock_manager_operations { 1025 + void *lm_mod_owner; 1025 1026 fl_owner_t (*lm_get_owner)(fl_owner_t); 1026 1027 void (*lm_put_owner)(fl_owner_t); 1027 1028 void (*lm_notify)(struct file_lock *); /* unblock callback */ ··· 1031 1030 int (*lm_change)(struct file_lock *, int, struct list_head *); 1032 1031 void (*lm_setup)(struct file_lock *, void **); 1033 1032 bool (*lm_breaker_owns_lease)(struct file_lock *); 1033 + bool (*lm_lock_expirable)(struct file_lock *cfl); 1034 + void (*lm_expire_lock)(void); 1034 1035 }; 1035 1036 1036 1037 struct lock_manager { ··· 1170 1167 struct files_struct; 1171 1168 extern void show_fd_locks(struct seq_file *f, 1172 1169 struct file *filp, struct files_struct *files); 1170 + extern bool locks_owner_has_blockers(struct file_lock_context *flctx, 1171 + fl_owner_t owner); 1173 1172 #else /* !CONFIG_FILE_LOCKING */ 1174 1173 static inline int fcntl_getlk(struct file *file, unsigned int cmd, 1175 1174 struct flock __user *user) ··· 1307 1302 struct files_struct; 1308 1303 static inline void show_fd_locks(struct seq_file *f, 1309 1304 struct file *filp, struct files_struct *files) {} 1305 + static inline bool locks_owner_has_blockers(struct file_lock_context *flctx, 1306 + fl_owner_t owner) 1307 + { 1308 + return false; 1309 + } 1310 1310 #endif /* !CONFIG_FILE_LOCKING */ 1311 1311 1312 1312 static inline struct inode *file_inode(const struct file *f) ··· 2640 2630 name, flags, mode); 2641 2631 } 2642 2632 extern struct file * dentry_open(const struct path *, int, const struct cred *); 2633 + extern struct file *dentry_create(const struct path *path, int flags, 2634 + umode_t mode, const struct cred *cred); 2643 2635 extern struct file * open_with_fake_path(const struct path *, int, 2644 2636 struct inode*, const struct cred *); 2645 2637 static inline struct file *file_clone_open(struct file *file)
+4 -4
include/linux/sunrpc/cache.h
··· 121 121 struct net *net; 122 122 }; 123 123 124 - 125 124 /* this must be embedded in any request structure that 126 125 * identifies an object that will want a callback on 127 126 * a cache fill 128 127 */ 129 128 struct cache_req { 130 129 struct cache_deferred_req *(*defer)(struct cache_req *req); 131 - int thread_wait; /* How long (jiffies) we can block the 132 - * current thread to wait for updates. 133 - */ 130 + unsigned long thread_wait; /* How long (jiffies) we can block the 131 + * current thread to wait for updates. 132 + */ 134 133 }; 134 + 135 135 /* this must be embedded in a deferred_request that is being 136 136 * delayed awaiting cache-fill 137 137 */
+1 -3
include/linux/sunrpc/svc.h
··· 257 257 void * rq_xprt_ctxt; /* transport specific context ptr */ 258 258 struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ 259 259 260 - size_t rq_xprt_hlen; /* xprt header len */ 261 260 struct xdr_buf rq_arg; 262 261 struct xdr_stream rq_arg_stream; 263 262 struct xdr_stream rq_res_stream; ··· 396 397 size_t daddrlen; 397 398 void *xprt_ctxt; 398 399 struct cache_deferred_req handle; 399 - size_t xprt_hlen; 400 400 int argslen; 401 401 __be32 args[]; 402 402 }; ··· 504 506 505 507 void svc_wake_up(struct svc_serv *); 506 508 void svc_reserve(struct svc_rqst *rqstp, int space); 507 - struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu); 509 + struct svc_pool *svc_pool_for_cpu(struct svc_serv *serv); 508 510 char * svc_print_addr(struct svc_rqst *, char *, size_t); 509 511 const char * svc_proc_name(const struct svc_rqst *rqstp); 510 512 int svc_encode_result_payload(struct svc_rqst *rqstp,
+5 -7
include/trace/events/sunrpc.h
··· 2015 2015 TP_STRUCT__entry( 2016 2016 __field(const void *, dr) 2017 2017 __field(u32, xid) 2018 - __array(__u8, addr, INET6_ADDRSTRLEN + 10) 2018 + __sockaddr(addr, dr->addrlen) 2019 2019 ), 2020 2020 2021 2021 TP_fast_assign( 2022 2022 __entry->dr = dr; 2023 - __entry->xid = be32_to_cpu(*(__be32 *)(dr->args + 2024 - (dr->xprt_hlen>>2))); 2025 - snprintf(__entry->addr, sizeof(__entry->addr) - 1, 2026 - "%pISpc", (struct sockaddr *)&dr->addr); 2023 + __entry->xid = be32_to_cpu(*(__be32 *)dr->args); 2024 + __assign_sockaddr(addr, &dr->addr, dr->addrlen); 2027 2025 ), 2028 2026 2029 - TP_printk("addr=%s dr=%p xid=0x%08x", __entry->addr, __entry->dr, 2030 - __entry->xid) 2027 + TP_printk("addr=%pISpc dr=%p xid=0x%08x", __get_sockaddr(addr), 2028 + __entry->dr, __entry->xid) 2031 2029 ); 2032 2030 2033 2031 #define DEFINE_SVC_DEFERRED_EVENT(name) \
+2 -2
net/sunrpc/auth_gss/svcauth_gss.c
··· 900 900 * rejecting the server-computed MIC in this somewhat rare case, 901 901 * do not use splice with the GSS integrity service. 902 902 */ 903 - clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 903 + __clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 904 904 905 905 /* Did we already verify the signature on the original pass through? */ 906 906 if (rqstp->rq_deferred) ··· 972 972 int pad, remaining_len, offset; 973 973 u32 rseqno; 974 974 975 - clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 975 + __clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 976 976 977 977 priv_len = svc_getnl(&buf->head[0]); 978 978 if (rqstp->rq_deferred) {
+17 -1
net/sunrpc/cache.c
··· 33 33 #include <linux/sunrpc/stats.h> 34 34 #include <linux/sunrpc/rpc_pipe_fs.h> 35 35 #include <trace/events/sunrpc.h> 36 + 36 37 #include "netns.h" 38 + #include "fail.h" 37 39 38 40 #define RPCDBG_FACILITY RPCDBG_CACHE 39 41 ··· 690 688 discard->revisit(discard, 1); 691 689 } 692 690 691 + #if IS_ENABLED(CONFIG_FAIL_SUNRPC) 692 + static inline bool cache_defer_immediately(void) 693 + { 694 + return !fail_sunrpc.ignore_cache_wait && 695 + should_fail(&fail_sunrpc.attr, 1); 696 + } 697 + #else 698 + static inline bool cache_defer_immediately(void) 699 + { 700 + return false; 701 + } 702 + #endif 703 + 693 704 /* Return true if and only if a deferred request is queued. */ 694 705 static bool cache_defer_req(struct cache_req *req, struct cache_head *item) 695 706 { 696 707 struct cache_deferred_req *dreq; 697 708 698 - if (req->thread_wait) { 709 + if (!cache_defer_immediately()) { 699 710 cache_wait_req(req, item); 700 711 if (!test_bit(CACHE_PENDING, &item->flags)) 701 712 return false; 702 713 } 714 + 703 715 dreq = req->defer(req); 704 716 if (dreq == NULL) 705 717 return false;
+3
net/sunrpc/debugfs.c
··· 262 262 263 263 debugfs_create_bool("ignore-server-disconnect", S_IFREG | 0600, dir, 264 264 &fail_sunrpc.ignore_server_disconnect); 265 + 266 + debugfs_create_bool("ignore-cache-wait", S_IFREG | 0600, dir, 267 + &fail_sunrpc.ignore_cache_wait); 265 268 } 266 269 #else 267 270 static void fail_sunrpc_init(void)
+1 -1
net/sunrpc/fail.h
··· 14 14 struct fault_attr attr; 15 15 16 16 bool ignore_client_disconnect; 17 - 18 17 bool ignore_server_disconnect; 18 + bool ignore_cache_wait; 19 19 }; 20 20 21 21 extern struct fail_sunrpc_attr fail_sunrpc;
+15 -9
net/sunrpc/svc.c
··· 356 356 } 357 357 } 358 358 359 - /* 360 - * Use the mapping mode to choose a pool for a given CPU. 361 - * Used when enqueueing an incoming RPC. Always returns 362 - * a non-NULL pool pointer. 359 + /** 360 + * svc_pool_for_cpu - Select pool to run a thread on this cpu 361 + * @serv: An RPC service 362 + * 363 + * Use the active CPU and the svc_pool_map's mode setting to 364 + * select the svc thread pool to use. Once initialized, the 365 + * svc_pool_map does not change. 366 + * 367 + * Return value: 368 + * A pointer to an svc_pool 363 369 */ 364 - struct svc_pool * 365 - svc_pool_for_cpu(struct svc_serv *serv, int cpu) 370 + struct svc_pool *svc_pool_for_cpu(struct svc_serv *serv) 366 371 { 367 372 struct svc_pool_map *m = &svc_pool_map; 373 + int cpu = raw_smp_processor_id(); 368 374 unsigned int pidx = 0; 369 375 370 376 if (serv->sv_nrpools <= 1) ··· 1244 1238 goto err_short_len; 1245 1239 1246 1240 /* Will be turned off by GSS integrity and privacy services */ 1247 - set_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 1241 + __set_bit(RQ_SPLICE_OK, &rqstp->rq_flags); 1248 1242 /* Will be turned off only when NFSv4 Sessions are used */ 1249 - set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); 1250 - clear_bit(RQ_DROPME, &rqstp->rq_flags); 1243 + __set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); 1244 + __clear_bit(RQ_DROPME, &rqstp->rq_flags); 1251 1245 1252 1246 svc_putu32(resv, rqstp->rq_xid); 1253 1247
+6 -11
net/sunrpc/svc_xprt.c
··· 448 448 { 449 449 struct svc_pool *pool; 450 450 struct svc_rqst *rqstp = NULL; 451 - int cpu; 452 451 453 452 if (!svc_xprt_ready(xprt)) 454 453 return; ··· 460 461 if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) 461 462 return; 462 463 463 - cpu = get_cpu(); 464 - pool = svc_pool_for_cpu(xprt->xpt_server, cpu); 464 + pool = svc_pool_for_cpu(xprt->xpt_server); 465 465 466 466 atomic_long_inc(&pool->sp_stats.packets); 467 467 ··· 483 485 rqstp = NULL; 484 486 out_unlock: 485 487 rcu_read_unlock(); 486 - put_cpu(); 487 488 trace_svc_xprt_enqueue(xprt, rqstp); 488 489 } 489 490 EXPORT_SYMBOL_GPL(svc_xprt_enqueue); ··· 1227 1230 dr->addrlen = rqstp->rq_addrlen; 1228 1231 dr->daddr = rqstp->rq_daddr; 1229 1232 dr->argslen = rqstp->rq_arg.len >> 2; 1230 - dr->xprt_hlen = rqstp->rq_xprt_hlen; 1231 1233 dr->xprt_ctxt = rqstp->rq_xprt_ctxt; 1232 1234 rqstp->rq_xprt_ctxt = NULL; 1233 1235 ··· 1238 1242 trace_svc_defer(rqstp); 1239 1243 svc_xprt_get(rqstp->rq_xprt); 1240 1244 dr->xprt = rqstp->rq_xprt; 1241 - set_bit(RQ_DROPME, &rqstp->rq_flags); 1245 + __set_bit(RQ_DROPME, &rqstp->rq_flags); 1242 1246 1243 1247 dr->handle.revisit = svc_revisit; 1244 1248 return &dr->handle; ··· 1254 1258 trace_svc_defer_recv(dr); 1255 1259 1256 1260 /* setup iov_base past transport header */ 1257 - rqstp->rq_arg.head[0].iov_base = dr->args + (dr->xprt_hlen>>2); 1261 + rqstp->rq_arg.head[0].iov_base = dr->args; 1258 1262 /* The iov_len does not include the transport header bytes */ 1259 - rqstp->rq_arg.head[0].iov_len = (dr->argslen<<2) - dr->xprt_hlen; 1263 + rqstp->rq_arg.head[0].iov_len = dr->argslen << 2; 1260 1264 rqstp->rq_arg.page_len = 0; 1261 1265 /* The rq_arg.len includes the transport header bytes */ 1262 - rqstp->rq_arg.len = dr->argslen<<2; 1266 + rqstp->rq_arg.len = dr->argslen << 2; 1263 1267 rqstp->rq_prot = dr->prot; 1264 1268 memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen); 1265 1269 rqstp->rq_addrlen = dr->addrlen; 1266 1270 /* Save off transport header len in case we get deferred again */ 1267 - rqstp->rq_xprt_hlen = dr->xprt_hlen; 1268 1271 rqstp->rq_daddr = dr->daddr; 1269 1272 rqstp->rq_respages = rqstp->rq_pages; 1270 1273 rqstp->rq_xprt_ctxt = dr->xprt_ctxt; 1271 1274 svc_xprt_received(rqstp->rq_xprt); 1272 - return (dr->argslen<<2) - dr->xprt_hlen; 1275 + return dr->argslen << 2; 1273 1276 } 1274 1277 1275 1278
+4 -15
net/sunrpc/svcsock.c
··· 117 117 */ 118 118 static void svc_tcp_release_rqst(struct svc_rqst *rqstp) 119 119 { 120 - struct sk_buff *skb = rqstp->rq_xprt_ctxt; 121 - 122 - if (skb) { 123 - struct svc_sock *svsk = 124 - container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); 125 - 126 - rqstp->rq_xprt_ctxt = NULL; 127 - skb_free_datagram_locked(svsk->sk_sk, skb); 128 - } 129 120 } 130 121 131 122 /** ··· 250 259 ssize_t len; 251 260 size_t t; 252 261 253 - rqstp->rq_xprt_hlen = 0; 254 - 255 262 clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 256 263 257 264 for (i = 0, t = 0; t < buflen; i++, t += PAGE_SIZE) { ··· 298 309 static void svc_sock_secure_port(struct svc_rqst *rqstp) 299 310 { 300 311 if (svc_port_is_privileged(svc_addr(rqstp))) 301 - set_bit(RQ_SECURE, &rqstp->rq_flags); 312 + __set_bit(RQ_SECURE, &rqstp->rq_flags); 302 313 else 303 - clear_bit(RQ_SECURE, &rqstp->rq_flags); 314 + __clear_bit(RQ_SECURE, &rqstp->rq_flags); 304 315 } 305 316 306 317 /* ··· 1008 1019 rqstp->rq_xprt_ctxt = NULL; 1009 1020 rqstp->rq_prot = IPPROTO_TCP; 1010 1021 if (test_bit(XPT_LOCAL, &svsk->sk_xprt.xpt_flags)) 1011 - set_bit(RQ_LOCAL, &rqstp->rq_flags); 1022 + __set_bit(RQ_LOCAL, &rqstp->rq_flags); 1012 1023 else 1013 - clear_bit(RQ_LOCAL, &rqstp->rq_flags); 1024 + __clear_bit(RQ_LOCAL, &rqstp->rq_flags); 1014 1025 1015 1026 p = (__be32 *)rqstp->rq_arg.head[0].iov_base; 1016 1027 calldir = p[1];
-1
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
··· 831 831 goto out_err; 832 832 if (ret == 0) 833 833 goto out_drop; 834 - rqstp->rq_xprt_hlen = 0; 835 834 836 835 if (svc_rdma_is_reverse_direction_reply(xprt, ctxt)) 837 836 goto out_backchannel;
+1 -1
net/sunrpc/xprtrdma/svc_rdma_transport.c
··· 602 602 603 603 static void svc_rdma_secure_port(struct svc_rqst *rqstp) 604 604 { 605 - set_bit(RQ_SECURE, &rqstp->rq_flags); 605 + __set_bit(RQ_SECURE, &rqstp->rq_flags); 606 606 } 607 607 608 608 static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt)