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

Merge tag 'nfsd-4.19-1' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields:
"Chuck Lever fixed a problem with NFSv4.0 callbacks over GSS from
multi-homed servers.

The only new feature is a minor bit of protocol (change_attr_type)
which the client doesn't even use yet.

Other than that, various bugfixes and cleanup"

* tag 'nfsd-4.19-1' of git://linux-nfs.org/~bfields/linux: (27 commits)
sunrpc: Add comment defining gssd upcall API keywords
nfsd: Remove callback_cred
nfsd: Use correct credential for NFSv4.0 callback with GSS
sunrpc: Extract target name into svc_cred
sunrpc: Enable the kernel to specify the hostname part of service principals
sunrpc: Don't use stack buffer with scatterlist
rpc: remove unneeded variable 'ret' in rdma_listen_handler
nfsd: use true and false for boolean values
nfsd: constify write_op[]
fs/nfsd: Delete invalid assignment statements in nfsd4_decode_exchange_id
NFSD: Handle full-length symlinks
NFSD: Refactor the generic write vector fill helper
svcrdma: Clean up Read chunk path
svcrdma: Avoid releasing a page in svc_xprt_release()
nfsd: Mark expected switch fall-through
sunrpc: remove redundant variables 'checksumlen','blocksize' and 'data'
nfsd: fix leaked file lock with nfs exported overlayfs
nfsd: don't advertise a SCSI layout for an unsupported request_queue
nfsd: fix corrupted reply to badly ordered compound
nfsd: clarify check_op_ordering
...

+300 -218
+1 -1
fs/lockd/clntlock.c
··· 187 187 continue; 188 188 if (!rpc_cmp_addr(nlm_addr(block->b_host), addr)) 189 189 continue; 190 - if (nfs_compare_fh(NFS_FH(file_inode(fl_blocked->fl_file)) ,fh) != 0) 190 + if (nfs_compare_fh(NFS_FH(locks_inode(fl_blocked->fl_file)), fh) != 0) 191 191 continue; 192 192 /* Alright, we found a lock. Set the return status 193 193 * and wake up the caller
+1 -1
fs/lockd/clntproc.c
··· 128 128 char *nodename = req->a_host->h_rpcclnt->cl_nodename; 129 129 130 130 nlmclnt_next_cookie(&argp->cookie); 131 - memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh)); 131 + memcpy(&lock->fh, NFS_FH(locks_inode(fl->fl_file)), sizeof(struct nfs_fh)); 132 132 lock->caller = nodename; 133 133 lock->oh.data = req->a_owner; 134 134 lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
+8 -8
fs/lockd/svclock.c
··· 405 405 __be32 ret; 406 406 407 407 dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n", 408 - file_inode(file->f_file)->i_sb->s_id, 409 - file_inode(file->f_file)->i_ino, 408 + locks_inode(file->f_file)->i_sb->s_id, 409 + locks_inode(file->f_file)->i_ino, 410 410 lock->fl.fl_type, lock->fl.fl_pid, 411 411 (long long)lock->fl.fl_start, 412 412 (long long)lock->fl.fl_end, ··· 511 511 __be32 ret; 512 512 513 513 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", 514 - file_inode(file->f_file)->i_sb->s_id, 515 - file_inode(file->f_file)->i_ino, 514 + locks_inode(file->f_file)->i_sb->s_id, 515 + locks_inode(file->f_file)->i_ino, 516 516 lock->fl.fl_type, 517 517 (long long)lock->fl.fl_start, 518 518 (long long)lock->fl.fl_end); ··· 566 566 int error; 567 567 568 568 dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n", 569 - file_inode(file->f_file)->i_sb->s_id, 570 - file_inode(file->f_file)->i_ino, 569 + locks_inode(file->f_file)->i_sb->s_id, 570 + locks_inode(file->f_file)->i_ino, 571 571 lock->fl.fl_pid, 572 572 (long long)lock->fl.fl_start, 573 573 (long long)lock->fl.fl_end); ··· 595 595 int status = 0; 596 596 597 597 dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", 598 - file_inode(file->f_file)->i_sb->s_id, 599 - file_inode(file->f_file)->i_ino, 598 + locks_inode(file->f_file)->i_sb->s_id, 599 + locks_inode(file->f_file)->i_ino, 600 600 lock->fl.fl_pid, 601 601 (long long)lock->fl.fl_start, 602 602 (long long)lock->fl.fl_end);
+2 -2
fs/lockd/svcsubs.c
··· 44 44 45 45 static inline void nlm_debug_print_file(char *msg, struct nlm_file *file) 46 46 { 47 - struct inode *inode = file_inode(file->f_file); 47 + struct inode *inode = locks_inode(file->f_file); 48 48 49 49 dprintk("lockd: %s %s/%ld\n", 50 50 msg, inode->i_sb->s_id, inode->i_ino); ··· 414 414 { 415 415 struct super_block *sb = datap; 416 416 417 - return sb == file_inode(file->f_file)->i_sb; 417 + return sb == locks_inode(file->f_file)->i_sb; 418 418 } 419 419 420 420 /**
+1
fs/nfsd/netns.h
··· 102 102 103 103 time_t nfsd4_lease; 104 104 time_t nfsd4_grace; 105 + bool somebody_reclaimed; 105 106 106 107 bool nfsd_net_up; 107 108 bool lockd_up;
+4 -1
fs/nfsd/nfs3proc.c
··· 202 202 203 203 fh_copy(&resp->fh, &argp->fh); 204 204 resp->committed = argp->stable; 205 - nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt); 205 + nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages, 206 + &argp->first, cnt); 206 207 if (!nvecs) 207 208 RETURN_STATUS(nfserr_io); 208 209 nfserr = nfsd_write(rqstp, &resp->fh, argp->offset, ··· 290 289 RETURN_STATUS(nfserr_nametoolong); 291 290 292 291 argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first, 292 + page_address(rqstp->rq_arg.pages[0]), 293 293 argp->tlen); 294 294 if (IS_ERR(argp->tname)) 295 295 RETURN_STATUS(nfserrno(PTR_ERR(argp->tname))); ··· 304 302 fh_init(&resp->fh, NFS3_FHSIZE); 305 303 nfserr = nfsd_symlink(rqstp, &resp->dirfh, argp->fname, argp->flen, 306 304 argp->tname, &resp->fh); 305 + kfree(argp->tname); 307 306 RETURN_STATUS(nfserr); 308 307 } 309 308
+9 -21
fs/nfsd/nfs4callback.c
··· 746 746 return max(nn->nfsd4_lease/10, (time_t)1) * HZ; 747 747 } 748 748 749 - static struct rpc_cred *callback_cred; 750 - 751 - int set_callback_cred(void) 752 - { 753 - if (callback_cred) 754 - return 0; 755 - callback_cred = rpc_lookup_machine_cred("nfs"); 756 - if (!callback_cred) 757 - return -ENOMEM; 758 - return 0; 759 - } 760 - 761 - void cleanup_callback_cred(void) 762 - { 763 - if (callback_cred) { 764 - put_rpccred(callback_cred); 765 - callback_cred = NULL; 766 - } 767 - } 768 - 769 749 static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses) 770 750 { 771 751 if (clp->cl_minorversion == 0) { 772 - return get_rpccred(callback_cred); 752 + char *principal = clp->cl_cred.cr_targ_princ ? 753 + clp->cl_cred.cr_targ_princ : "nfs"; 754 + struct rpc_cred *cred; 755 + 756 + cred = rpc_lookup_machine_cred(principal); 757 + if (!IS_ERR(cred)) 758 + get_rpccred(cred); 759 + return cred; 773 760 } else { 774 761 struct rpc_auth *auth = client->cl_auth; 775 762 struct auth_cred acred = {}; ··· 967 980 break; 968 981 case -ESERVERFAULT: 969 982 ++session->se_cb_seq_nr; 983 + /* Fall through */ 970 984 case 1: 971 985 case -NFS4ERR_BADSESSION: 972 986 nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status);
+2 -9
fs/nfsd/nfs4layouts.c
··· 133 133 if (!(exp->ex_flags & NFSEXP_PNFS)) 134 134 return; 135 135 136 - /* 137 - * If flex file is configured, use it by default. Otherwise 138 - * check if the file system supports exporting a block-like layout. 139 - * If the block device supports reservations prefer the SCSI layout, 140 - * otherwise advertise the block layout. 141 - */ 142 136 #ifdef CONFIG_NFSD_FLEXFILELAYOUT 143 137 exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES; 144 138 #endif 145 139 #ifdef CONFIG_NFSD_BLOCKLAYOUT 146 - /* overwrite flex file layout selection if needed */ 147 140 if (sb->s_export_op->get_uuid && 148 141 sb->s_export_op->map_blocks && 149 142 sb->s_export_op->commit_blocks) 150 143 exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME; 151 144 #endif 152 145 #ifdef CONFIG_NFSD_SCSILAYOUT 153 - /* overwrite block layout selection if needed */ 154 146 if (sb->s_export_op->map_blocks && 155 147 sb->s_export_op->commit_blocks && 156 - sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops) 148 + sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops && 149 + blk_queue_scsi_passthrough(sb->s_bdev->bd_disk->queue)) 157 150 exp->ex_layout_types |= 1 << LAYOUT_SCSI; 158 151 #endif 159 152 }
+18 -23
fs/nfsd/nfs4proc.c
··· 354 354 struct svc_fh *resfh = NULL; 355 355 struct net *net = SVC_NET(rqstp); 356 356 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 357 + bool reclaim = false; 357 358 358 359 dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n", 359 360 (int)open->op_fname.len, open->op_fname.data, ··· 425 424 if (status) 426 425 goto out; 427 426 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 427 + reclaim = true; 428 428 case NFS4_OPEN_CLAIM_FH: 429 429 case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 430 430 status = do_open_fhandle(rqstp, cstate, open); ··· 454 452 WARN(status && open->op_created, 455 453 "nfsd4_process_open2 failed to open newly-created file! status=%u\n", 456 454 be32_to_cpu(status)); 455 + if (reclaim && !status) 456 + nn->somebody_reclaimed = true; 457 457 out: 458 458 if (resfh && resfh != &cstate->current_fh) { 459 459 fh_dup2(&cstate->current_fh, resfh); ··· 986 982 return status; 987 983 } 988 984 989 - static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write) 990 - { 991 - int i = 1; 992 - int buflen = write->wr_buflen; 993 - 994 - vec[0].iov_base = write->wr_head.iov_base; 995 - vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len); 996 - buflen -= vec[0].iov_len; 997 - 998 - while (buflen) { 999 - vec[i].iov_base = page_address(write->wr_pagelist[i - 1]); 1000 - vec[i].iov_len = min_t(int, PAGE_SIZE, buflen); 1001 - buflen -= vec[i].iov_len; 1002 - i++; 1003 - } 1004 - return i; 1005 - } 1006 - 1007 985 static __be32 1008 986 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1009 987 union nfsd4_op_u *u) ··· 1013 1027 write->wr_how_written = write->wr_stable_how; 1014 1028 gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp)); 1015 1029 1016 - nvecs = fill_in_write_vector(rqstp->rq_vec, write); 1030 + nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist, 1031 + &write->wr_head, write->wr_buflen); 1032 + if (!nvecs) 1033 + return nfserr_io; 1017 1034 WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec)); 1018 1035 1019 1036 status = nfsd_vfs_write(rqstp, &cstate->current_fh, filp, ··· 1588 1599 */ 1589 1600 static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args) 1590 1601 { 1591 - struct nfsd4_op *op = &args->ops[0]; 1602 + struct nfsd4_op *first_op = &args->ops[0]; 1592 1603 1593 1604 /* These ordering requirements don't apply to NFSv4.0: */ 1594 1605 if (args->minorversion == 0) ··· 1596 1607 /* This is weird, but OK, not our problem: */ 1597 1608 if (args->opcnt == 0) 1598 1609 return nfs_ok; 1599 - if (op->status == nfserr_op_illegal) 1610 + if (first_op->status == nfserr_op_illegal) 1600 1611 return nfs_ok; 1601 - if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP)) 1612 + if (!(nfsd4_ops[first_op->opnum].op_flags & ALLOWED_AS_FIRST_OP)) 1602 1613 return nfserr_op_not_in_session; 1603 - if (op->opnum == OP_SEQUENCE) 1614 + if (first_op->opnum == OP_SEQUENCE) 1604 1615 return nfs_ok; 1616 + /* 1617 + * So first_op is something allowed outside a session, like 1618 + * EXCHANGE_ID; but then it has to be the only op in the 1619 + * compound: 1620 + */ 1605 1621 if (args->opcnt != 1) 1606 1622 return nfserr_not_only_op; 1607 1623 return nfs_ok; ··· 1720 1726 if (status) { 1721 1727 op = &args->ops[0]; 1722 1728 op->status = status; 1729 + resp->opcnt = 1; 1723 1730 goto encode_op; 1724 1731 } 1725 1732
+48 -22
fs/nfsd/nfs4state.c
··· 1979 1979 target->cr_principal = kstrdup(source->cr_principal, GFP_KERNEL); 1980 1980 target->cr_raw_principal = kstrdup(source->cr_raw_principal, 1981 1981 GFP_KERNEL); 1982 - if ((source->cr_principal && ! target->cr_principal) || 1983 - (source->cr_raw_principal && ! target->cr_raw_principal)) 1982 + target->cr_targ_princ = kstrdup(source->cr_targ_princ, GFP_KERNEL); 1983 + if ((source->cr_principal && !target->cr_principal) || 1984 + (source->cr_raw_principal && !target->cr_raw_principal) || 1985 + (source->cr_targ_princ && !target->cr_targ_princ)) 1984 1986 return -ENOMEM; 1985 1987 1986 1988 target->cr_flavor = source->cr_flavor; ··· 2059 2057 || (!gid_eq(cr1->cr_gid, cr2->cr_gid)) 2060 2058 || !groups_equal(cr1->cr_group_info, cr2->cr_group_info)) 2061 2059 return false; 2060 + /* XXX: check that cr_targ_princ fields match ? */ 2062 2061 if (cr1->cr_principal == cr2->cr_principal) 2063 2062 return true; 2064 2063 if (!cr1->cr_principal || !cr2->cr_principal) ··· 2959 2956 return status; 2960 2957 } 2961 2958 2962 - static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) 2959 + static bool nfsd4_compound_in_session(struct nfsd4_compound_state *cstate, struct nfs4_sessionid *sid) 2963 2960 { 2964 - if (!session) 2961 + if (!cstate->session) 2965 2962 return false; 2966 - return !memcmp(sid, &session->se_sessionid, sizeof(*sid)); 2963 + return !memcmp(sid, &cstate->session->se_sessionid, sizeof(*sid)); 2967 2964 } 2968 2965 2969 2966 __be32 2970 2967 nfsd4_destroy_session(struct svc_rqst *r, struct nfsd4_compound_state *cstate, 2971 2968 union nfsd4_op_u *u) 2972 2969 { 2973 - struct nfsd4_destroy_session *sessionid = &u->destroy_session; 2970 + struct nfs4_sessionid *sessionid = &u->destroy_session.sessionid; 2974 2971 struct nfsd4_session *ses; 2975 2972 __be32 status; 2976 2973 int ref_held_by_me = 0; ··· 2978 2975 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 2979 2976 2980 2977 status = nfserr_not_only_op; 2981 - if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) { 2978 + if (nfsd4_compound_in_session(cstate, sessionid)) { 2982 2979 if (!nfsd4_last_compound_op(r)) 2983 2980 goto out; 2984 2981 ref_held_by_me++; 2985 2982 } 2986 - dump_sessionid(__func__, &sessionid->sessionid); 2983 + dump_sessionid(__func__, sessionid); 2987 2984 spin_lock(&nn->client_lock); 2988 - ses = find_in_sessionid_hashtbl(&sessionid->sessionid, net, &status); 2985 + ses = find_in_sessionid_hashtbl(sessionid, net, &status); 2989 2986 if (!ses) 2990 2987 goto out_client_lock; 2991 2988 status = nfserr_wrong_cred; ··· 3948 3945 /* 3949 3946 * We're assuming the state code never drops its reference 3950 3947 * without first removing the lease. Since we're in this lease 3951 - * callback (and since the lease code is serialized by the kernel 3952 - * lock) we know the server hasn't removed the lease yet, we know 3953 - * it's safe to take a reference. 3948 + * callback (and since the lease code is serialized by the 3949 + * i_lock) we know the server hasn't removed the lease yet, and 3950 + * we know it's safe to take a reference. 3954 3951 */ 3955 3952 refcount_inc(&dp->dl_stid.sc_count); 3956 3953 nfsd4_run_cb(&dp->dl_recall); ··· 4696 4693 */ 4697 4694 } 4698 4695 4696 + /* 4697 + * If we've waited a lease period but there are still clients trying to 4698 + * reclaim, wait a little longer to give them a chance to finish. 4699 + */ 4700 + static bool clients_still_reclaiming(struct nfsd_net *nn) 4701 + { 4702 + unsigned long now = get_seconds(); 4703 + unsigned long double_grace_period_end = nn->boot_time + 4704 + 2 * nn->nfsd4_lease; 4705 + 4706 + if (!nn->somebody_reclaimed) 4707 + return false; 4708 + nn->somebody_reclaimed = false; 4709 + /* 4710 + * If we've given them *two* lease times to reclaim, and they're 4711 + * still not done, give up: 4712 + */ 4713 + if (time_after(now, double_grace_period_end)) 4714 + return false; 4715 + return true; 4716 + } 4717 + 4699 4718 static time_t 4700 4719 nfs4_laundromat(struct nfsd_net *nn) 4701 4720 { ··· 4731 4706 time_t t, new_timeo = nn->nfsd4_lease; 4732 4707 4733 4708 dprintk("NFSD: laundromat service - starting\n"); 4709 + 4710 + if (clients_still_reclaiming(nn)) { 4711 + new_timeo = 0; 4712 + goto out; 4713 + } 4734 4714 nfsd4_end_grace(nn); 4735 4715 INIT_LIST_HEAD(&reaplist); 4736 4716 spin_lock(&nn->client_lock); ··· 4833 4803 posix_unblock_lock(&nbl->nbl_lock); 4834 4804 free_blocked_lock(nbl); 4835 4805 } 4836 - 4806 + out: 4837 4807 new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT); 4838 4808 return new_timeo; 4839 4809 } ··· 6083 6053 case 0: /* success! */ 6084 6054 nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid); 6085 6055 status = 0; 6056 + if (lock->lk_reclaim) 6057 + nn->somebody_reclaimed = true; 6086 6058 break; 6087 6059 case FILE_LOCK_DEFERRED: 6088 6060 nbl = NULL; ··· 6325 6293 return status; 6326 6294 } 6327 6295 6328 - inode = file_inode(filp); 6296 + inode = locks_inode(filp); 6329 6297 flctx = inode->i_flctx; 6330 6298 6331 6299 if (flctx && !list_empty_careful(&flctx->flc_posix)) { ··· 7231 7199 { 7232 7200 int ret; 7233 7201 7234 - ret = set_callback_cred(); 7235 - if (ret) 7236 - return ret; 7237 - 7238 7202 laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); 7239 7203 if (laundry_wq == NULL) { 7240 7204 ret = -ENOMEM; 7241 - goto out_cleanup_cred; 7205 + goto out; 7242 7206 } 7243 7207 ret = nfsd4_create_callback_queue(); 7244 7208 if (ret) ··· 7245 7217 7246 7218 out_free_laundry: 7247 7219 destroy_workqueue(laundry_wq); 7248 - out_cleanup_cred: 7249 - cleanup_callback_cred(); 7220 + out: 7250 7221 return ret; 7251 7222 } 7252 7223 ··· 7282 7255 { 7283 7256 destroy_workqueue(laundry_wq); 7284 7257 nfsd4_destroy_callback_queue(); 7285 - cleanup_callback_cred(); 7286 7258 } 7287 7259 7288 7260 static void
+37 -6
fs/nfsd/nfs4xdr.c
··· 1390 1390 p += XDR_QUADLEN(dummy); 1391 1391 } 1392 1392 1393 - /* ssp_window and ssp_num_gss_handles */ 1393 + /* ignore ssp_window and ssp_num_gss_handles: */ 1394 1394 READ_BUF(8); 1395 - dummy = be32_to_cpup(p++); 1396 - dummy = be32_to_cpup(p++); 1397 1395 break; 1398 1396 default: 1399 1397 goto xdr_error; ··· 2001 2003 *p++ = cpu_to_be32(stat->ctime.tv_sec); 2002 2004 *p++ = cpu_to_be32(stat->ctime.tv_nsec); 2003 2005 } 2006 + return p; 2007 + } 2008 + 2009 + /* 2010 + * ctime (in NFSv4, time_metadata) is not writeable, and the client 2011 + * doesn't really care what resolution could theoretically be stored by 2012 + * the filesystem. 2013 + * 2014 + * The client cares how close together changes can be while still 2015 + * guaranteeing ctime changes. For most filesystems (which have 2016 + * timestamps with nanosecond fields) that is limited by the resolution 2017 + * of the time returned from current_time() (which I'm assuming to be 2018 + * 1/HZ). 2019 + */ 2020 + static __be32 *encode_time_delta(__be32 *p, struct inode *inode) 2021 + { 2022 + struct timespec ts; 2023 + u32 ns; 2024 + 2025 + ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran); 2026 + ts = ns_to_timespec(ns); 2027 + 2028 + p = xdr_encode_hyper(p, ts.tv_sec); 2029 + *p++ = cpu_to_be32(ts.tv_nsec); 2030 + 2004 2031 return p; 2005 2032 } 2006 2033 ··· 2820 2797 p = xdr_reserve_space(xdr, 12); 2821 2798 if (!p) 2822 2799 goto out_resource; 2823 - *p++ = cpu_to_be32(0); 2824 - *p++ = cpu_to_be32(1); 2825 - *p++ = cpu_to_be32(0); 2800 + p = encode_time_delta(p, d_inode(dentry)); 2826 2801 } 2827 2802 if (bmval1 & FATTR4_WORD1_TIME_METADATA) { 2828 2803 p = xdr_reserve_space(xdr, 12); ··· 2887 2866 status = nfsd4_encode_bitmap(xdr, supp[0], supp[1], supp[2]); 2888 2867 if (status) 2889 2868 goto out; 2869 + } 2870 + 2871 + if (bmval2 & FATTR4_WORD2_CHANGE_ATTR_TYPE) { 2872 + p = xdr_reserve_space(xdr, 4); 2873 + if (!p) 2874 + goto out_resource; 2875 + if (IS_I_VERSION(d_inode(dentry))) 2876 + *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR); 2877 + else 2878 + *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_TIME_METADATA); 2890 2879 } 2891 2880 2892 2881 if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
+4 -3
fs/nfsd/nfsctl.c
··· 73 73 static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size); 74 74 #endif 75 75 76 - static ssize_t (*write_op[])(struct file *, char *, size_t) = { 76 + static ssize_t (*const write_op[])(struct file *, char *, size_t) = { 77 77 [NFSD_Fh] = write_filehandle, 78 78 [NFSD_FO_UnlockIP] = write_unlock_ip, 79 79 [NFSD_FO_UnlockFS] = write_unlock_fs, ··· 1237 1237 retval = nfsd_idmap_init(net); 1238 1238 if (retval) 1239 1239 goto out_idmap_error; 1240 - nn->nfsd4_lease = 90; /* default lease time */ 1241 - nn->nfsd4_grace = 90; 1240 + nn->nfsd4_lease = 45; /* default lease time */ 1241 + nn->nfsd4_grace = 45; 1242 + nn->somebody_reclaimed = false; 1242 1243 nn->clverifier_counter = prandom_u32(); 1243 1244 nn->clientid_counter = prandom_u32(); 1244 1245
+1
fs/nfsd/nfsd.h
··· 360 360 361 361 #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \ 362 362 (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ 363 + FATTR4_WORD2_CHANGE_ATTR_TYPE | \ 363 364 FATTR4_WORD2_MODE_UMASK | \ 364 365 NFSD4_2_SECURITY_ATTRS) 365 366
+3 -3
fs/nfsd/nfsfh.c
··· 451 451 switch (fsid_type) { 452 452 case FSID_DEV: 453 453 if (!old_valid_dev(exp_sb(exp)->s_dev)) 454 - return 0; 454 + return false; 455 455 /* FALL THROUGH */ 456 456 case FSID_MAJOR_MINOR: 457 457 case FSID_ENCODE_DEV: ··· 461 461 case FSID_UUID8: 462 462 case FSID_UUID16: 463 463 if (!is_root_export(exp)) 464 - return 0; 464 + return false; 465 465 /* fall through */ 466 466 case FSID_UUID4_INUM: 467 467 case FSID_UUID16_INUM: 468 468 return exp->ex_uuid != NULL; 469 469 } 470 - return 1; 470 + return true; 471 471 } 472 472 473 473
+4 -1
fs/nfsd/nfsproc.c
··· 218 218 SVCFH_fmt(&argp->fh), 219 219 argp->len, argp->offset); 220 220 221 - nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt); 221 + nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages, 222 + &argp->first, cnt); 222 223 if (!nvecs) 223 224 return nfserr_io; 224 225 nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), ··· 454 453 return nfserr_nametoolong; 455 454 456 455 argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first, 456 + page_address(rqstp->rq_arg.pages[0]), 457 457 argp->tlen); 458 458 if (IS_ERR(argp->tname)) 459 459 return nfserrno(PTR_ERR(argp->tname)); ··· 467 465 nfserr = nfsd_symlink(rqstp, &argp->ffh, argp->fname, argp->flen, 468 466 argp->tname, &newfh); 469 467 468 + kfree(argp->tname); 470 469 fh_put(&argp->ffh); 471 470 fh_put(&newfh); 472 471 return nfserr;
-2
fs/nfsd/state.h
··· 617 617 struct nfsd_net *nn); 618 618 extern __be32 nfs4_check_open_reclaim(clientid_t *clid, 619 619 struct nfsd4_compound_state *cstate, struct nfsd_net *nn); 620 - extern int set_callback_cred(void); 621 - extern void cleanup_callback_cred(void); 622 620 extern void nfsd4_probe_callback(struct nfs4_client *clp); 623 621 extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); 624 622 extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
+2 -2
include/linux/lockd/lockd.h
··· 299 299 300 300 static inline struct inode *nlmsvc_file_inode(struct nlm_file *file) 301 301 { 302 - return file_inode(file->f_file); 302 + return locks_inode(file->f_file); 303 303 } 304 304 305 305 static inline int __nlm_privileged_request4(const struct sockaddr *sap) ··· 359 359 static inline int nlm_compare_locks(const struct file_lock *fl1, 360 360 const struct file_lock *fl2) 361 361 { 362 - return file_inode(fl1->fl_file) == file_inode(fl2->fl_file) 362 + return locks_inode(fl1->fl_file) == locks_inode(fl2->fl_file) 363 363 && fl1->fl_pid == fl2->fl_pid 364 364 && fl1->fl_owner == fl2->fl_owner 365 365 && fl1->fl_start == fl2->fl_start
+8
include/linux/nfs4.h
··· 374 374 NFS4_WRITEW_LT = 4 375 375 }; 376 376 377 + enum change_attr_type4 { 378 + NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR = 0, 379 + NFS4_CHANGE_TYPE_IS_VERSION_COUNTER = 1, 380 + NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS = 2, 381 + NFS4_CHANGE_TYPE_IS_TIME_METADATA = 3, 382 + NFS4_CHANGE_TYPE_IS_UNDEFINED = 4 383 + }; 377 384 378 385 /* Mandatory Attributes */ 379 386 #define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0) ··· 448 441 #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) 449 442 #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) 450 443 #define FATTR4_WORD2_CLONE_BLKSIZE (1UL << 13) 444 + #define FATTR4_WORD2_CHANGE_ATTR_TYPE (1UL << 15) 451 445 #define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) 452 446 #define FATTR4_WORD2_MODE_UMASK (1UL << 17) 453 447
+3 -1
include/linux/sunrpc/svc.h
··· 496 496 struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu); 497 497 char * svc_print_addr(struct svc_rqst *, char *, size_t); 498 498 unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, 499 + struct page **pages, 499 500 struct kvec *first, size_t total); 500 501 char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, 501 - struct kvec *first, size_t total); 502 + struct kvec *first, void *p, 503 + size_t total); 502 504 503 505 #define RPC_MAX_ADDRBUFLEN (63U) 504 506
+3
include/linux/sunrpc/svcauth.h
··· 31 31 /* name of form servicetype@hostname, passed down by 32 32 * rpc.svcgssd, or computed from the above: */ 33 33 char *cr_principal; 34 + char *cr_targ_princ; 34 35 struct gss_api_mech *cr_gss_mech; 35 36 }; 36 37 ··· 40 39 cred->cr_group_info = NULL; 41 40 cred->cr_raw_principal = NULL; 42 41 cred->cr_principal = NULL; 42 + cred->cr_targ_princ = NULL; 43 43 cred->cr_gss_mech = NULL; 44 44 } 45 45 ··· 50 48 put_group_info(cred->cr_group_info); 51 49 kfree(cred->cr_raw_principal); 52 50 kfree(cred->cr_principal); 51 + kfree(cred->cr_targ_princ); 53 52 gss_mech_put(cred->cr_gss_mech); 54 53 init_svc_cred(cred); 55 54 }
+34 -3
net/sunrpc/auth_gss/auth_gss.c
··· 284 284 return p; 285 285 } 286 286 287 - #define UPCALL_BUF_LEN 128 287 + /* XXX: Need some documentation about why UPCALL_BUF_LEN is so small. 288 + * Is user space expecting no more than UPCALL_BUF_LEN bytes? 289 + * Note that there are now _two_ NI_MAXHOST sized data items 290 + * being passed in this string. 291 + */ 292 + #define UPCALL_BUF_LEN 256 288 293 289 294 struct gss_upcall_msg { 290 295 refcount_t count; ··· 461 456 buflen -= len; 462 457 p += len; 463 458 gss_msg->msg.len = len; 459 + 460 + /* 461 + * target= is a full service principal that names the remote 462 + * identity that we are authenticating to. 463 + */ 464 464 if (target_name) { 465 465 len = scnprintf(p, buflen, "target=%s ", target_name); 466 466 buflen -= len; 467 467 p += len; 468 468 gss_msg->msg.len += len; 469 469 } 470 - if (service_name != NULL) { 471 - len = scnprintf(p, buflen, "service=%s ", service_name); 470 + 471 + /* 472 + * gssd uses service= and srchost= to select a matching key from 473 + * the system's keytab to use as the source principal. 474 + * 475 + * service= is the service name part of the source principal, 476 + * or "*" (meaning choose any). 477 + * 478 + * srchost= is the hostname part of the source principal. When 479 + * not provided, gssd uses the local hostname. 480 + */ 481 + if (service_name) { 482 + char *c = strchr(service_name, '@'); 483 + 484 + if (!c) 485 + len = scnprintf(p, buflen, "service=%s ", 486 + service_name); 487 + else 488 + len = scnprintf(p, buflen, 489 + "service=%.*s srchost=%s ", 490 + (int)(c - service_name), 491 + service_name, c + 1); 472 492 buflen -= len; 473 493 p += len; 474 494 gss_msg->msg.len += len; 475 495 } 496 + 476 497 if (mech->gm_upcall_enctypes) { 477 498 len = scnprintf(p, buflen, "enctypes=%s ", 478 499 mech->gm_upcall_enctypes);
+9 -5
net/sunrpc/auth_gss/gss_krb5_crypto.c
··· 169 169 struct scatterlist sg[1]; 170 170 int err = -1; 171 171 u8 *checksumdata; 172 - u8 rc4salt[4]; 172 + u8 *rc4salt; 173 173 struct crypto_ahash *md5; 174 174 struct crypto_ahash *hmac_md5; 175 175 struct ahash_request *req; ··· 183 183 return GSS_S_FAILURE; 184 184 } 185 185 186 + rc4salt = kmalloc_array(4, sizeof(*rc4salt), GFP_NOFS); 187 + if (!rc4salt) 188 + return GSS_S_FAILURE; 189 + 186 190 if (arcfour_hmac_md5_usage_to_salt(usage, rc4salt)) { 187 191 dprintk("%s: invalid usage value %u\n", __func__, usage); 188 - return GSS_S_FAILURE; 192 + goto out_free_rc4salt; 189 193 } 190 194 191 195 checksumdata = kmalloc(GSS_KRB5_MAX_CKSUM_LEN, GFP_NOFS); 192 196 if (!checksumdata) 193 - return GSS_S_FAILURE; 197 + goto out_free_rc4salt; 194 198 195 199 md5 = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC); 196 200 if (IS_ERR(md5)) ··· 262 258 crypto_free_ahash(md5); 263 259 out_free_cksum: 264 260 kfree(checksumdata); 261 + out_free_rc4salt: 262 + kfree(rc4salt); 265 263 return err ? GSS_S_FAILURE : 0; 266 264 } 267 265 ··· 379 373 struct scatterlist sg[1]; 380 374 int err = -1; 381 375 u8 *checksumdata; 382 - unsigned int checksumlen; 383 376 384 377 if (kctx->gk5e->keyed_cksum == 0) { 385 378 dprintk("%s: expected keyed hash for %s\n", ··· 398 393 tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); 399 394 if (IS_ERR(tfm)) 400 395 goto out_free_cksum; 401 - checksumlen = crypto_ahash_digestsize(tfm); 402 396 403 397 req = ahash_request_alloc(tfm, GFP_NOFS); 404 398 if (!req)
-2
net/sunrpc/auth_gss/gss_krb5_wrap.c
··· 440 440 gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset, 441 441 struct xdr_buf *buf, struct page **pages) 442 442 { 443 - int blocksize; 444 443 u8 *ptr, *plainhdr; 445 444 s32 now; 446 445 u8 flags = 0x00; ··· 472 473 *ptr++ = 0xff; 473 474 be16ptr = (__be16 *)ptr; 474 475 475 - blocksize = crypto_skcipher_blocksize(kctx->acceptor_enc); 476 476 *be16ptr++ = 0; 477 477 /* "inner" token header always uses 0 for RRC */ 478 478 *be16ptr++ = 0;
+45 -25
net/sunrpc/auth_gss/gss_rpc_upcall.c
··· 234 234 return 0; 235 235 } 236 236 237 + static char *gssp_stringify(struct xdr_netobj *netobj) 238 + { 239 + return kstrndup(netobj->data, netobj->len, GFP_KERNEL); 240 + } 241 + 242 + static void gssp_hostbased_service(char **principal) 243 + { 244 + char *c; 245 + 246 + if (!*principal) 247 + return; 248 + 249 + /* terminate and remove realm part */ 250 + c = strchr(*principal, '@'); 251 + if (c) { 252 + *c = '\0'; 253 + 254 + /* change service-hostname delimiter */ 255 + c = strchr(*principal, '/'); 256 + if (c) 257 + *c = '@'; 258 + } 259 + if (!c) { 260 + /* not a service principal */ 261 + kfree(*principal); 262 + *principal = NULL; 263 + } 264 + } 265 + 237 266 /* 238 267 * Public functions 239 268 */ ··· 291 262 */ 292 263 .exported_context_token.len = GSSX_max_output_handle_sz, 293 264 .mech.len = GSS_OID_MAX_LEN, 265 + .targ_name.display_name.len = GSSX_max_princ_sz, 294 266 .src_name.display_name.len = GSSX_max_princ_sz 295 267 }; 296 268 struct gssx_res_accept_sec_context res = { ··· 305 275 .rpc_cred = NULL, /* FIXME ? */ 306 276 }; 307 277 struct xdr_netobj client_name = { 0 , NULL }; 278 + struct xdr_netobj target_name = { 0, NULL }; 308 279 int ret; 309 280 310 281 if (data->in_handle.len != 0) ··· 315 284 ret = gssp_alloc_receive_pages(&arg); 316 285 if (ret) 317 286 return ret; 318 - 319 - /* use nfs/ for targ_name ? */ 320 287 321 288 ret = gssp_call(net, &msg); 322 289 ··· 333 304 kfree(rctxh.mech.data); 334 305 } 335 306 client_name = rctxh.src_name.display_name; 307 + target_name = rctxh.targ_name.display_name; 336 308 } 337 309 338 310 if (res.options.count == 1) { ··· 355 325 } 356 326 357 327 /* convert to GSS_NT_HOSTBASED_SERVICE form and set into creds */ 358 - if (data->found_creds && client_name.data != NULL) { 359 - char *c; 360 - 361 - data->creds.cr_raw_principal = kstrndup(client_name.data, 362 - client_name.len, GFP_KERNEL); 363 - 364 - data->creds.cr_principal = kstrndup(client_name.data, 365 - client_name.len, GFP_KERNEL); 366 - if (data->creds.cr_principal) { 367 - /* terminate and remove realm part */ 368 - c = strchr(data->creds.cr_principal, '@'); 369 - if (c) { 370 - *c = '\0'; 371 - 372 - /* change service-hostname delimiter */ 373 - c = strchr(data->creds.cr_principal, '/'); 374 - if (c) *c = '@'; 375 - } 376 - if (!c) { 377 - /* not a service principal */ 378 - kfree(data->creds.cr_principal); 379 - data->creds.cr_principal = NULL; 380 - } 328 + if (data->found_creds) { 329 + if (client_name.data) { 330 + data->creds.cr_raw_principal = 331 + gssp_stringify(&client_name); 332 + data->creds.cr_principal = 333 + gssp_stringify(&client_name); 334 + gssp_hostbased_service(&data->creds.cr_principal); 335 + } 336 + if (target_name.data) { 337 + data->creds.cr_targ_princ = 338 + gssp_stringify(&target_name); 339 + gssp_hostbased_service(&data->creds.cr_targ_princ); 381 340 } 382 341 } 383 342 kfree(client_name.data); 343 + kfree(target_name.data); 384 344 385 345 return ret; 386 346 }
+30 -50
net/sunrpc/svc.c
··· 1537 1537 /** 1538 1538 * svc_fill_write_vector - Construct data argument for VFS write call 1539 1539 * @rqstp: svc_rqst to operate on 1540 + * @pages: list of pages containing data payload 1540 1541 * @first: buffer containing first section of write payload 1541 1542 * @total: total number of bytes of write payload 1542 1543 * 1543 - * Returns the number of elements populated in the data argument array. 1544 + * Fills in rqstp::rq_vec, and returns the number of elements. 1544 1545 */ 1545 - unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first, 1546 - size_t total) 1546 + unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct page **pages, 1547 + struct kvec *first, size_t total) 1547 1548 { 1548 1549 struct kvec *vec = rqstp->rq_vec; 1549 - struct page **pages; 1550 1550 unsigned int i; 1551 1551 1552 1552 /* Some types of transport can present the write payload ··· 1560 1560 ++i; 1561 1561 } 1562 1562 1563 - WARN_ON_ONCE(rqstp->rq_arg.page_base != 0); 1564 - pages = rqstp->rq_arg.pages; 1565 1563 while (total) { 1566 1564 vec[i].iov_base = page_address(*pages); 1567 1565 vec[i].iov_len = min_t(size_t, total, PAGE_SIZE); 1568 1566 total -= vec[i].iov_len; 1569 1567 ++i; 1570 - 1571 1568 ++pages; 1572 1569 } 1573 1570 ··· 1577 1580 * svc_fill_symlink_pathname - Construct pathname argument for VFS symlink call 1578 1581 * @rqstp: svc_rqst to operate on 1579 1582 * @first: buffer containing first section of pathname 1583 + * @p: buffer containing remaining section of pathname 1580 1584 * @total: total length of the pathname argument 1581 1585 * 1582 - * Returns pointer to a NUL-terminated string, or an ERR_PTR. The buffer is 1583 - * released automatically when @rqstp is recycled. 1586 + * The VFS symlink API demands a NUL-terminated pathname in mapped memory. 1587 + * Returns pointer to a NUL-terminated string, or an ERR_PTR. Caller must free 1588 + * the returned string. 1584 1589 */ 1585 1590 char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, struct kvec *first, 1586 - size_t total) 1591 + void *p, size_t total) 1587 1592 { 1588 - struct xdr_buf *arg = &rqstp->rq_arg; 1589 - struct page **pages; 1590 - char *result; 1593 + size_t len, remaining; 1594 + char *result, *dst; 1591 1595 1592 - /* VFS API demands a NUL-terminated pathname. This function 1593 - * uses a page from @rqstp as the pathname buffer, to enable 1594 - * direct placement. Thus the total buffer size is PAGE_SIZE. 1595 - * Space in this buffer for NUL-termination requires that we 1596 - * cap the size of the returned symlink pathname just a 1597 - * little early. 1598 - */ 1599 - if (total > PAGE_SIZE - 1) 1600 - return ERR_PTR(-ENAMETOOLONG); 1596 + result = kmalloc(total + 1, GFP_KERNEL); 1597 + if (!result) 1598 + return ERR_PTR(-ESERVERFAULT); 1601 1599 1602 - /* Some types of transport can present the pathname entirely 1603 - * in rq_arg.pages. If not, then copy the pathname into one 1604 - * page. 1605 - */ 1606 - pages = arg->pages; 1607 - WARN_ON_ONCE(arg->page_base != 0); 1608 - if (first->iov_base == 0) { 1609 - result = page_address(*pages); 1610 - result[total] = '\0'; 1611 - } else { 1612 - size_t len, remaining; 1613 - char *dst; 1600 + dst = result; 1601 + remaining = total; 1614 1602 1615 - result = page_address(*(rqstp->rq_next_page++)); 1616 - dst = result; 1617 - remaining = total; 1618 - 1619 - len = min_t(size_t, total, first->iov_len); 1603 + len = min_t(size_t, total, first->iov_len); 1604 + if (len) { 1620 1605 memcpy(dst, first->iov_base, len); 1621 1606 dst += len; 1622 1607 remaining -= len; 1623 - 1624 - /* No more than one page left */ 1625 - if (remaining) { 1626 - len = min_t(size_t, remaining, PAGE_SIZE); 1627 - memcpy(dst, page_address(*pages), len); 1628 - dst += len; 1629 - } 1630 - 1631 - *dst = '\0'; 1632 1608 } 1633 1609 1634 - /* Sanity check: we don't allow the pathname argument to 1610 + if (remaining) { 1611 + len = min_t(size_t, remaining, PAGE_SIZE); 1612 + memcpy(dst, p, len); 1613 + dst += len; 1614 + } 1615 + 1616 + *dst = '\0'; 1617 + 1618 + /* Sanity check: Linux doesn't allow the pathname argument to 1635 1619 * contain a NUL byte. 1636 1620 */ 1637 - if (strlen(result) != total) 1621 + if (strlen(result) != total) { 1622 + kfree(result); 1638 1623 return ERR_PTR(-EINVAL); 1624 + } 1639 1625 return result; 1640 1626 } 1641 1627 EXPORT_SYMBOL_GPL(svc_fill_symlink_pathname);
-2
net/sunrpc/xprtrdma/svc_rdma.c
··· 94 94 atomic_set(stat, 0); 95 95 else { 96 96 char str_buf[32]; 97 - char *data; 98 97 int len = snprintf(str_buf, 32, "%d\n", atomic_read(stat)); 99 98 if (len >= 32) 100 99 return -EFAULT; ··· 102 103 *lenp = 0; 103 104 return 0; 104 105 } 105 - data = &str_buf[*ppos]; 106 106 len -= *ppos; 107 107 if (len > *lenp) 108 108 len = *lenp;
+6 -3
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
··· 365 365 arg->page_base = 0; 366 366 arg->buflen = ctxt->rc_byte_len; 367 367 arg->len = ctxt->rc_byte_len; 368 - 369 - rqstp->rq_respages = &rqstp->rq_pages[0]; 370 - rqstp->rq_next_page = rqstp->rq_respages + 1; 371 368 } 372 369 373 370 /* This accommodates the largest possible Write chunk, ··· 725 728 atomic_inc(&rdma_stat_recv); 726 729 727 730 svc_rdma_build_arg_xdr(rqstp, ctxt); 731 + 732 + /* Prevent svc_xprt_release from releasing pages in rq_pages 733 + * if we return 0 or an error. 734 + */ 735 + rqstp->rq_respages = rqstp->rq_pages; 736 + rqstp->rq_next_page = rqstp->rq_respages; 728 737 729 738 p = (__be32 *)rqstp->rq_arg.head[0].iov_base; 730 739 ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg);
+13 -19
net/sunrpc/xprtrdma/svc_rdma_rw.c
··· 680 680 struct svc_rdma_read_info *info, 681 681 __be32 *p) 682 682 { 683 + unsigned int i; 683 684 int ret; 684 685 685 686 ret = -EINVAL; ··· 702 701 trace_svcrdma_encode_rseg(rs_handle, rs_length, rs_offset); 703 702 info->ri_chunklen += rs_length; 704 703 } 704 + 705 + /* Pages under I/O have been copied to head->rc_pages. 706 + * Prevent their premature release by svc_xprt_release() . 707 + */ 708 + for (i = 0; i < info->ri_readctxt->rc_page_count; i++) 709 + rqstp->rq_pages[i] = NULL; 705 710 706 711 return ret; 707 712 } ··· 824 817 struct svc_rdma_recv_ctxt *head, __be32 *p) 825 818 { 826 819 struct svc_rdma_read_info *info; 827 - struct page **page; 828 820 int ret; 829 821 830 822 /* The request (with page list) is constructed in ··· 850 844 ret = svc_rdma_build_normal_read_chunk(rqstp, info, p); 851 845 else 852 846 ret = svc_rdma_build_pz_read_chunk(rqstp, info, p); 853 - 854 - /* Mark the start of the pages that can be used for the reply */ 855 - if (info->ri_pageoff > 0) 856 - info->ri_pageno++; 857 - rqstp->rq_respages = &rqstp->rq_pages[info->ri_pageno]; 858 - rqstp->rq_next_page = rqstp->rq_respages + 1; 859 - 860 847 if (ret < 0) 861 - goto out; 848 + goto out_err; 862 849 863 850 ret = svc_rdma_post_chunk_ctxt(&info->ri_cc); 864 - 865 - out: 866 - /* Read sink pages have been moved from rqstp->rq_pages to 867 - * head->rc_arg.pages. Force svc_recv to refill those slots 868 - * in rq_pages. 869 - */ 870 - for (page = rqstp->rq_pages; page < rqstp->rq_respages; page++) 871 - *page = NULL; 872 - 873 851 if (ret < 0) 874 - svc_rdma_read_info_free(info); 852 + goto out_err; 853 + return 0; 854 + 855 + out_err: 856 + svc_rdma_read_info_free(info); 875 857 return ret; 876 858 }
+3 -1
net/sunrpc/xprtrdma/svc_rdma_sendto.c
··· 656 656 ctxt->sc_pages[i] = rqstp->rq_respages[i]; 657 657 rqstp->rq_respages[i] = NULL; 658 658 } 659 - rqstp->rq_next_page = rqstp->rq_respages + 1; 659 + 660 + /* Prevent svc_xprt_release from releasing pages in rq_pages */ 661 + rqstp->rq_next_page = rqstp->rq_respages; 660 662 } 661 663 662 664 /* Prepare the portion of the RPC Reply that will be transmitted
+1 -2
net/sunrpc/xprtrdma/svc_rdma_transport.c
··· 296 296 struct rdma_cm_event *event) 297 297 { 298 298 struct sockaddr *sap = (struct sockaddr *)&cma_id->route.addr.src_addr; 299 - int ret = 0; 300 299 301 300 trace_svcrdma_cm_event(event, sap); 302 301 ··· 314 315 break; 315 316 } 316 317 317 - return ret; 318 + return 0; 318 319 } 319 320 320 321 static int rdma_cma_handler(struct rdma_cm_id *cma_id,