Skip to content

Commit

Permalink
Merge tag 'nfsd-4.19-1' of git://linux-nfs.org/~bfields/linux
Browse files Browse the repository at this point in the history
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
  ...
  • Loading branch information
torvalds committed Aug 23, 2018
2 parents 6f7948f + 108b833 commit 9157141
Show file tree
Hide file tree
Showing 30 changed files with 299 additions and 217 deletions.
2 changes: 1 addition & 1 deletion fs/lockd/clntlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock)
continue;
if (!rpc_cmp_addr(nlm_addr(block->b_host), addr))
continue;
if (nfs_compare_fh(NFS_FH(file_inode(fl_blocked->fl_file)) ,fh) != 0)
if (nfs_compare_fh(NFS_FH(locks_inode(fl_blocked->fl_file)), fh) != 0)
continue;
/* Alright, we found a lock. Set the return status
* and wake up the caller
Expand Down
2 changes: 1 addition & 1 deletion fs/lockd/clntproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
char *nodename = req->a_host->h_rpcclnt->cl_nodename;

nlmclnt_next_cookie(&argp->cookie);
memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh));
memcpy(&lock->fh, NFS_FH(locks_inode(fl->fl_file)), sizeof(struct nfs_fh));
lock->caller = nodename;
lock->oh.data = req->a_owner;
lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
Expand Down
16 changes: 8 additions & 8 deletions fs/lockd/svclock.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
__be32 ret;

dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
file_inode(file->f_file)->i_sb->s_id,
file_inode(file->f_file)->i_ino,
locks_inode(file->f_file)->i_sb->s_id,
locks_inode(file->f_file)->i_ino,
lock->fl.fl_type, lock->fl.fl_pid,
(long long)lock->fl.fl_start,
(long long)lock->fl.fl_end,
Expand Down Expand Up @@ -511,8 +511,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
__be32 ret;

dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
file_inode(file->f_file)->i_sb->s_id,
file_inode(file->f_file)->i_ino,
locks_inode(file->f_file)->i_sb->s_id,
locks_inode(file->f_file)->i_ino,
lock->fl.fl_type,
(long long)lock->fl.fl_start,
(long long)lock->fl.fl_end);
Expand Down Expand Up @@ -566,8 +566,8 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
int error;

dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
file_inode(file->f_file)->i_sb->s_id,
file_inode(file->f_file)->i_ino,
locks_inode(file->f_file)->i_sb->s_id,
locks_inode(file->f_file)->i_ino,
lock->fl.fl_pid,
(long long)lock->fl.fl_start,
(long long)lock->fl.fl_end);
Expand Down Expand Up @@ -595,8 +595,8 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
int status = 0;

dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
file_inode(file->f_file)->i_sb->s_id,
file_inode(file->f_file)->i_ino,
locks_inode(file->f_file)->i_sb->s_id,
locks_inode(file->f_file)->i_ino,
lock->fl.fl_pid,
(long long)lock->fl.fl_start,
(long long)lock->fl.fl_end);
Expand Down
4 changes: 2 additions & 2 deletions fs/lockd/svcsubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)

static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
{
struct inode *inode = file_inode(file->f_file);
struct inode *inode = locks_inode(file->f_file);

dprintk("lockd: %s %s/%ld\n",
msg, inode->i_sb->s_id, inode->i_ino);
Expand Down Expand Up @@ -414,7 +414,7 @@ nlmsvc_match_sb(void *datap, struct nlm_file *file)
{
struct super_block *sb = datap;

return sb == file_inode(file->f_file)->i_sb;
return sb == locks_inode(file->f_file)->i_sb;
}

/**
Expand Down
1 change: 1 addition & 0 deletions fs/nfsd/netns.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ struct nfsd_net {

time_t nfsd4_lease;
time_t nfsd4_grace;
bool somebody_reclaimed;

bool nfsd_net_up;
bool lockd_up;
Expand Down
5 changes: 4 additions & 1 deletion fs/nfsd/nfs3proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ nfsd3_proc_write(struct svc_rqst *rqstp)

fh_copy(&resp->fh, &argp->fh);
resp->committed = argp->stable;
nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
&argp->first, cnt);
if (!nvecs)
RETURN_STATUS(nfserr_io);
nfserr = nfsd_write(rqstp, &resp->fh, argp->offset,
Expand Down Expand Up @@ -289,6 +290,7 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
RETURN_STATUS(nfserr_nametoolong);

argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
page_address(rqstp->rq_arg.pages[0]),
argp->tlen);
if (IS_ERR(argp->tname))
RETURN_STATUS(nfserrno(PTR_ERR(argp->tname)));
Expand All @@ -302,6 +304,7 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
fh_init(&resp->fh, NFS3_FHSIZE);
nfserr = nfsd_symlink(rqstp, &resp->dirfh, argp->fname, argp->flen,
argp->tname, &resp->fh);
kfree(argp->tname);
RETURN_STATUS(nfserr);
}

Expand Down
30 changes: 9 additions & 21 deletions fs/nfsd/nfs4callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,30 +746,17 @@ static int max_cb_time(struct net *net)
return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
}

static struct rpc_cred *callback_cred;

int set_callback_cred(void)
{
if (callback_cred)
return 0;
callback_cred = rpc_lookup_machine_cred("nfs");
if (!callback_cred)
return -ENOMEM;
return 0;
}

void cleanup_callback_cred(void)
{
if (callback_cred) {
put_rpccred(callback_cred);
callback_cred = NULL;
}
}

static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
{
if (clp->cl_minorversion == 0) {
return get_rpccred(callback_cred);
char *principal = clp->cl_cred.cr_targ_princ ?
clp->cl_cred.cr_targ_princ : "nfs";
struct rpc_cred *cred;

cred = rpc_lookup_machine_cred(principal);
if (!IS_ERR(cred))
get_rpccred(cred);
return cred;
} else {
struct rpc_auth *auth = client->cl_auth;
struct auth_cred acred = {};
Expand Down Expand Up @@ -980,6 +967,7 @@ static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback
break;
case -ESERVERFAULT:
++session->se_cb_seq_nr;
/* Fall through */
case 1:
case -NFS4ERR_BADSESSION:
nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status);
Expand Down
11 changes: 2 additions & 9 deletions fs/nfsd/nfs4layouts.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,27 +133,20 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
if (!(exp->ex_flags & NFSEXP_PNFS))
return;

/*
* If flex file is configured, use it by default. Otherwise
* check if the file system supports exporting a block-like layout.
* If the block device supports reservations prefer the SCSI layout,
* otherwise advertise the block layout.
*/
#ifdef CONFIG_NFSD_FLEXFILELAYOUT
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
#endif
#ifdef CONFIG_NFSD_BLOCKLAYOUT
/* overwrite flex file layout selection if needed */
if (sb->s_export_op->get_uuid &&
sb->s_export_op->map_blocks &&
sb->s_export_op->commit_blocks)
exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
#endif
#ifdef CONFIG_NFSD_SCSILAYOUT
/* overwrite block layout selection if needed */
if (sb->s_export_op->map_blocks &&
sb->s_export_op->commit_blocks &&
sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops)
sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops &&
blk_queue_scsi_passthrough(sb->s_bdev->bd_disk->queue))
exp->ex_layout_types |= 1 << LAYOUT_SCSI;
#endif
}
Expand Down
41 changes: 18 additions & 23 deletions fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct svc_fh *resfh = NULL;
struct net *net = SVC_NET(rqstp);
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
bool reclaim = false;

dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
(int)open->op_fname.len, open->op_fname.data,
Expand Down Expand Up @@ -424,6 +425,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
goto out;
open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
reclaim = true;
case NFS4_OPEN_CLAIM_FH:
case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
status = do_open_fhandle(rqstp, cstate, open);
Expand Down Expand Up @@ -452,6 +454,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
WARN(status && open->op_created,
"nfsd4_process_open2 failed to open newly-created file! status=%u\n",
be32_to_cpu(status));
if (reclaim && !status)
nn->somebody_reclaimed = true;
out:
if (resfh && resfh != &cstate->current_fh) {
fh_dup2(&cstate->current_fh, resfh);
Expand Down Expand Up @@ -982,24 +986,6 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return status;
}

static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
{
int i = 1;
int buflen = write->wr_buflen;

vec[0].iov_base = write->wr_head.iov_base;
vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len);
buflen -= vec[0].iov_len;

while (buflen) {
vec[i].iov_base = page_address(write->wr_pagelist[i - 1]);
vec[i].iov_len = min_t(int, PAGE_SIZE, buflen);
buflen -= vec[i].iov_len;
i++;
}
return i;
}

static __be32
nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
union nfsd4_op_u *u)
Expand Down Expand Up @@ -1027,7 +1013,10 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
write->wr_how_written = write->wr_stable_how;
gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));

nvecs = fill_in_write_vector(rqstp->rq_vec, write);
nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
&write->wr_head, write->wr_buflen);
if (!nvecs)
return nfserr_io;
WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));

status = nfsd_vfs_write(rqstp, &cstate->current_fh, filp,
Expand Down Expand Up @@ -1599,20 +1588,25 @@ static const char *nfsd4_op_name(unsigned opnum);
*/
static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
{
struct nfsd4_op *op = &args->ops[0];
struct nfsd4_op *first_op = &args->ops[0];

/* These ordering requirements don't apply to NFSv4.0: */
if (args->minorversion == 0)
return nfs_ok;
/* This is weird, but OK, not our problem: */
if (args->opcnt == 0)
return nfs_ok;
if (op->status == nfserr_op_illegal)
if (first_op->status == nfserr_op_illegal)
return nfs_ok;
if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
if (!(nfsd4_ops[first_op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
return nfserr_op_not_in_session;
if (op->opnum == OP_SEQUENCE)
if (first_op->opnum == OP_SEQUENCE)
return nfs_ok;
/*
* So first_op is something allowed outside a session, like
* EXCHANGE_ID; but then it has to be the only op in the
* compound:
*/
if (args->opcnt != 1)
return nfserr_not_only_op;
return nfs_ok;
Expand Down Expand Up @@ -1726,6 +1720,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
if (status) {
op = &args->ops[0];
op->status = status;
resp->opcnt = 1;
goto encode_op;
}

Expand Down
Loading

0 comments on commit 9157141

Please sign in to comment.