Loading fs/nfs/nfs42.h +14 −1 Original line number Diff line number Diff line Loading @@ -13,8 +13,10 @@ #define PNFS_LAYOUTSTATS_MAXDEV (4) /* nfs4.2proc.c */ #ifdef CONFIG_NFS_V4_2 int nfs42_proc_allocate(struct file *, loff_t, loff_t); ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t); ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t, struct nl4_server *, nfs4_stateid *, bool); int nfs42_proc_deallocate(struct file *, loff_t, loff_t); loff_t nfs42_proc_llseek(struct file *, loff_t, int); int nfs42_proc_layoutstats_generic(struct nfs_server *, Loading @@ -23,5 +25,16 @@ int nfs42_proc_clone(struct file *, struct file *, loff_t, loff_t, loff_t); int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg, const struct nfs42_layout_error *errors, size_t n); int nfs42_proc_copy_notify(struct file *, struct file *, struct nfs42_copy_notify_res *); static inline bool nfs42_files_from_same_server(struct file *in, struct file *out) { struct nfs_client *c_in = (NFS_SERVER(file_inode(in)))->nfs_client; struct nfs_client *c_out = (NFS_SERVER(file_inode(out)))->nfs_client; return nfs4_check_serverowner_major_id(c_in->cl_serverowner, c_out->cl_serverowner); } #endif /* CONFIG_NFS_V4_2 */ #endif /* __LINUX_FS_NFS_NFS4_2_H */ fs/nfs/nfs42proc.c +167 −32 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com> */ #include <linux/fs.h> #include <linux/sunrpc/addr.h> #include <linux/sunrpc/sched.h> #include <linux/nfs.h> #include <linux/nfs3.h> Loading @@ -15,10 +16,30 @@ #include "pnfs.h" #include "nfs4session.h" #include "internal.h" #include "delegation.h" #define NFSDBG_FACILITY NFSDBG_PROC static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std); static void nfs42_set_netaddr(struct file *filep, struct nfs42_netaddr *naddr) { struct nfs_client *clp = (NFS_SERVER(file_inode(filep)))->nfs_client; unsigned short port = 2049; rcu_read_lock(); naddr->netid_len = scnprintf(naddr->netid, sizeof(naddr->netid), "%s", rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_NETID)); naddr->addr_len = scnprintf(naddr->addr, sizeof(naddr->addr), "%s.%u.%u", rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR), port >> 8, port & 255); rcu_read_unlock(); } static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, struct nfs_lock_context *lock, loff_t offset, loff_t len) { Loading Loading @@ -132,22 +153,26 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) } static int handle_async_copy(struct nfs42_copy_res *res, struct nfs_server *server, struct nfs_server *dst_server, struct nfs_server *src_server, struct file *src, struct file *dst, nfs4_stateid *src_stateid) nfs4_stateid *src_stateid, bool *restart) { struct nfs4_copy_state *copy, *tmp_copy; int status = NFS4_OK; bool found_pending = false; struct nfs_open_context *ctx = nfs_file_open_context(dst); struct nfs_open_context *dst_ctx = nfs_file_open_context(dst); struct nfs_open_context *src_ctx = nfs_file_open_context(src); copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS); if (!copy) return -ENOMEM; spin_lock(&server->nfs_client->cl_lock); list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids, spin_lock(&dst_server->nfs_client->cl_lock); list_for_each_entry(tmp_copy, &dst_server->nfs_client->pending_cb_stateids, copies) { if (memcmp(&res->write_res.stateid, &tmp_copy->stateid, NFS4_STATEID_SIZE)) Loading @@ -157,7 +182,7 @@ static int handle_async_copy(struct nfs42_copy_res *res, break; } if (found_pending) { spin_unlock(&server->nfs_client->cl_lock); spin_unlock(&dst_server->nfs_client->cl_lock); kfree(copy); copy = tmp_copy; goto out; Loading @@ -165,19 +190,32 @@ static int handle_async_copy(struct nfs42_copy_res *res, memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE); init_completion(©->completion); copy->parent_state = ctx->state; copy->parent_dst_state = dst_ctx->state; copy->parent_src_state = src_ctx->state; list_add_tail(©->copies, &server->ss_copies); spin_unlock(&server->nfs_client->cl_lock); list_add_tail(©->copies, &dst_server->ss_copies); spin_unlock(&dst_server->nfs_client->cl_lock); if (dst_server != src_server) { spin_lock(&src_server->nfs_client->cl_lock); list_add_tail(©->src_copies, &src_server->ss_copies); spin_unlock(&src_server->nfs_client->cl_lock); } status = wait_for_completion_interruptible(©->completion); spin_lock(&server->nfs_client->cl_lock); spin_lock(&dst_server->nfs_client->cl_lock); list_del_init(©->copies); spin_unlock(&server->nfs_client->cl_lock); spin_unlock(&dst_server->nfs_client->cl_lock); if (dst_server != src_server) { spin_lock(&src_server->nfs_client->cl_lock); list_del_init(©->src_copies); spin_unlock(&src_server->nfs_client->cl_lock); } if (status == -ERESTARTSYS) { goto out_cancel; } else if (copy->flags) { } else if (copy->flags || copy->error == NFS4ERR_PARTNER_NO_AUTH) { status = -EAGAIN; *restart = true; goto out_cancel; } out: Loading @@ -185,12 +223,14 @@ static int handle_async_copy(struct nfs42_copy_res *res, memcpy(&res->write_res.verifier, ©->verf, sizeof(copy->verf)); status = -copy->error; out_free: kfree(copy); return status; out_cancel: nfs42_do_offload_cancel_async(dst, ©->stateid); kfree(copy); return status; if (!nfs42_files_from_same_server(src, dst)) nfs42_do_offload_cancel_async(src, src_stateid); goto out_free; } static int process_copy_commit(struct file *dst, loff_t pos_dst, Loading Loading @@ -222,7 +262,10 @@ static ssize_t _nfs42_proc_copy(struct file *src, struct file *dst, struct nfs_lock_context *dst_lock, struct nfs42_copy_args *args, struct nfs42_copy_res *res) struct nfs42_copy_res *res, struct nl4_server *nss, nfs4_stateid *cnr_stateid, bool *restart) { struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY], Loading @@ -230,17 +273,23 @@ static ssize_t _nfs42_proc_copy(struct file *src, .rpc_resp = res, }; struct inode *dst_inode = file_inode(dst); struct nfs_server *server = NFS_SERVER(dst_inode); struct inode *src_inode = file_inode(src); struct nfs_server *dst_server = NFS_SERVER(dst_inode); struct nfs_server *src_server = NFS_SERVER(src_inode); loff_t pos_src = args->src_pos; loff_t pos_dst = args->dst_pos; size_t count = args->count; ssize_t status; status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context, src_lock, FMODE_READ); if (nss) { args->cp_src = nss; nfs4_stateid_copy(&args->src_stateid, cnr_stateid); } else { status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context, src_lock, FMODE_READ); if (status) return status; } status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping, pos_src, pos_src + (loff_t)count - 1); if (status) Loading @@ -262,13 +311,15 @@ static ssize_t _nfs42_proc_copy(struct file *src, if (!res->commit_res.verf) return -ENOMEM; } set_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &src_lock->open_context->state->flags); set_bit(NFS_CLNT_DST_SSC_COPY_STATE, &dst_lock->open_context->state->flags); status = nfs4_call_sync(server->client, server, &msg, status = nfs4_call_sync(dst_server->client, dst_server, &msg, &args->seq_args, &res->seq_res, 0); if (status == -ENOTSUPP) server->caps &= ~NFS_CAP_COPY; dst_server->caps &= ~NFS_CAP_COPY; if (status) goto out; Loading @@ -280,8 +331,8 @@ static ssize_t _nfs42_proc_copy(struct file *src, } if (!res->synchronous) { status = handle_async_copy(res, server, src, dst, &args->src_stateid); status = handle_async_copy(res, dst_server, src_server, src, dst, &args->src_stateid, restart); if (status) return status; } Loading @@ -304,8 +355,9 @@ static ssize_t _nfs42_proc_copy(struct file *src, } ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, struct file *dst, loff_t pos_dst, size_t count) struct file *dst, loff_t pos_dst, size_t count, struct nl4_server *nss, nfs4_stateid *cnr_stateid, bool sync) { struct nfs_server *server = NFS_SERVER(file_inode(dst)); struct nfs_lock_context *src_lock; Loading @@ -316,7 +368,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, .dst_fh = NFS_FH(file_inode(dst)), .dst_pos = pos_dst, .count = count, .sync = false, .sync = sync, }; struct nfs42_copy_res res; struct nfs4_exception src_exception = { Loading @@ -328,6 +380,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, .stateid = &args.dst_stateid, }; ssize_t err, err2; bool restart = false; src_lock = nfs_get_lock_context(nfs_file_open_context(src)); if (IS_ERR(src_lock)) Loading @@ -347,21 +400,33 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, inode_lock(file_inode(dst)); err = _nfs42_proc_copy(src, src_lock, dst, dst_lock, &args, &res); &args, &res, nss, cnr_stateid, &restart); inode_unlock(file_inode(dst)); if (err >= 0) break; if (err == -ENOTSUPP) { if (err == -ENOTSUPP && nfs42_files_from_same_server(src, dst)) { err = -EOPNOTSUPP; break; } else if (err == -EAGAIN) { if (!restart) { dst_exception.retry = 1; continue; } break; } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) { args.sync = true; dst_exception.retry = 1; continue; } else if ((err == -ESTALE || err == -NFS4ERR_OFFLOAD_DENIED || err == -ENOTSUPP) && !nfs42_files_from_same_server(src, dst)) { nfs42_do_offload_cancel_async(src, &args.src_stateid); err = -EOPNOTSUPP; break; } err2 = nfs4_handle_exception(server, err, &src_exception); Loading Loading @@ -459,6 +524,76 @@ static int nfs42_do_offload_cancel_async(struct file *dst, return status; } int _nfs42_proc_copy_notify(struct file *src, struct file *dst, struct nfs42_copy_notify_args *args, struct nfs42_copy_notify_res *res) { struct nfs_server *src_server = NFS_SERVER(file_inode(src)); struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY_NOTIFY], .rpc_argp = args, .rpc_resp = res, }; int status; struct nfs_open_context *ctx; struct nfs_lock_context *l_ctx; ctx = get_nfs_open_context(nfs_file_open_context(src)); l_ctx = nfs_get_lock_context(ctx); if (IS_ERR(l_ctx)) return PTR_ERR(l_ctx); status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx, FMODE_READ); nfs_put_lock_context(l_ctx); if (status) return status; status = nfs4_call_sync(src_server->client, src_server, &msg, &args->cna_seq_args, &res->cnr_seq_res, 0); if (status == -ENOTSUPP) src_server->caps &= ~NFS_CAP_COPY_NOTIFY; put_nfs_open_context(nfs_file_open_context(src)); return status; } int nfs42_proc_copy_notify(struct file *src, struct file *dst, struct nfs42_copy_notify_res *res) { struct nfs_server *src_server = NFS_SERVER(file_inode(src)); struct nfs42_copy_notify_args *args; struct nfs4_exception exception = { .inode = file_inode(src), }; int status; if (!(src_server->caps & NFS_CAP_COPY_NOTIFY)) return -EOPNOTSUPP; args = kzalloc(sizeof(struct nfs42_copy_notify_args), GFP_NOFS); if (args == NULL) return -ENOMEM; args->cna_src_fh = NFS_FH(file_inode(src)), args->cna_dst.nl4_type = NL4_NETADDR; nfs42_set_netaddr(dst, &args->cna_dst.u.nl4_addr); exception.stateid = &args->cna_src_stateid; do { status = _nfs42_proc_copy_notify(src, dst, args, res); if (status == -ENOTSUPP) { status = -EOPNOTSUPP; goto out; } status = nfs4_handle_exception(src_server, status, &exception); } while (exception.retry); out: kfree(args); return status; } static loff_t _nfs42_proc_llseek(struct file *filep, struct nfs_lock_context *lock, loff_t offset, int whence) { Loading fs/nfs/nfs42xdr.c +188 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,10 @@ #define encode_copy_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 2 + 2 + 2 + 1 + 1 + 1) 2 + 2 + 2 + 1 + 1 + 1 +\ 1 + /* One cnr_source_server */\ 1 + /* nl4_type */ \ 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define decode_copy_maxsz (op_decode_hdr_maxsz + \ NFS42_WRITE_RES_SIZE + \ 1 /* cr_consecutive */ + \ Loading @@ -29,6 +32,16 @@ #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE)) #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz) #define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 1 + /* nl4_type */ \ 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \ 3 + /* cnr_lease_time */\ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 1 + /* Support 1 cnr_source_server */\ 1 + /* nl4_type */ \ 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ encode_fallocate_maxsz) #define decode_deallocate_maxsz (op_decode_hdr_maxsz) Loading Loading @@ -99,6 +112,12 @@ decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_offload_cancel_maxsz) #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_copy_notify_maxsz) #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_copy_notify_maxsz) #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ encode_sequence_maxsz + \ encode_putfh_maxsz + \ Loading Loading @@ -166,6 +185,26 @@ static void encode_allocate(struct xdr_stream *xdr, encode_fallocate(xdr, args); } static void encode_nl4_server(struct xdr_stream *xdr, const struct nl4_server *ns) { encode_uint32(xdr, ns->nl4_type); switch (ns->nl4_type) { case NL4_NAME: case NL4_URL: encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str); break; case NL4_NETADDR: encode_string(xdr, ns->u.nl4_addr.netid_len, ns->u.nl4_addr.netid); encode_string(xdr, ns->u.nl4_addr.addr_len, ns->u.nl4_addr.addr); break; default: WARN_ON_ONCE(1); } } static void encode_copy(struct xdr_stream *xdr, const struct nfs42_copy_args *args, struct compound_hdr *hdr) Loading @@ -180,7 +219,12 @@ static void encode_copy(struct xdr_stream *xdr, encode_uint32(xdr, 1); /* consecutive = true */ encode_uint32(xdr, args->sync); encode_uint32(xdr, 0); /* src server list */ if (args->cp_src == NULL) { /* intra-ssc */ encode_uint32(xdr, 0); /* no src server list */ return; } encode_uint32(xdr, 1); /* supporting 1 server */ encode_nl4_server(xdr, args->cp_src); } static void encode_offload_cancel(struct xdr_stream *xdr, Loading @@ -191,6 +235,15 @@ static void encode_offload_cancel(struct xdr_stream *xdr, encode_nfs4_stateid(xdr, &args->osa_stateid); } static void encode_copy_notify(struct xdr_stream *xdr, const struct nfs42_copy_notify_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr); encode_nfs4_stateid(xdr, &args->cna_src_stateid); encode_nl4_server(xdr, &args->cna_dst); } static void encode_deallocate(struct xdr_stream *xdr, const struct nfs42_falloc_args *args, struct compound_hdr *hdr) Loading Loading @@ -354,6 +407,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, encode_nops(&hdr); } /* * Encode COPY_NOTIFY request */ static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req, struct xdr_stream *xdr, const void *data) { const struct nfs42_copy_notify_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->cna_seq_args, &hdr); encode_putfh(xdr, args->cna_src_fh, &hdr); encode_copy_notify(xdr, args, &hdr); encode_nops(&hdr); } /* * Encode DEALLOCATE request */ Loading Loading @@ -490,6 +562,58 @@ static int decode_write_response(struct xdr_stream *xdr, return decode_verifier(xdr, &res->verifier.verifier); } static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) { struct nfs42_netaddr *naddr; uint32_t dummy; char *dummy_str; __be32 *p; int status; /* nl_type */ p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) return -EIO; ns->nl4_type = be32_to_cpup(p); switch (ns->nl4_type) { case NL4_NAME: case NL4_URL: status = decode_opaque_inline(xdr, &dummy, &dummy_str); if (unlikely(status)) return status; if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) return -EIO; memcpy(&ns->u.nl4_str, dummy_str, dummy); ns->u.nl4_str_sz = dummy; break; case NL4_NETADDR: naddr = &ns->u.nl4_addr; /* netid string */ status = decode_opaque_inline(xdr, &dummy, &dummy_str); if (unlikely(status)) return status; if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) return -EIO; naddr->netid_len = dummy; memcpy(naddr->netid, dummy_str, naddr->netid_len); /* uaddr string */ status = decode_opaque_inline(xdr, &dummy, &dummy_str); if (unlikely(status)) return status; if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) return -EIO; naddr->addr_len = dummy; memcpy(naddr->addr, dummy_str, naddr->addr_len); break; default: WARN_ON_ONCE(1); return -EIO; } return 0; } static int decode_copy_requirements(struct xdr_stream *xdr, struct nfs42_copy_res *res) { __be32 *p; Loading Loading @@ -529,6 +653,42 @@ static int decode_offload_cancel(struct xdr_stream *xdr, return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); } static int decode_copy_notify(struct xdr_stream *xdr, struct nfs42_copy_notify_res *res) { __be32 *p; int status, count; status = decode_op_hdr(xdr, OP_COPY_NOTIFY); if (status) return status; /* cnr_lease_time */ p = xdr_inline_decode(xdr, 12); if (unlikely(!p)) return -EIO; p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds); res->cnr_lease_time.nseconds = be32_to_cpup(p); status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE); if (unlikely(status)) return -EIO; /* number of source addresses */ p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) return -EIO; count = be32_to_cpup(p); if (count > 1) pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n", __func__, count); status = decode_nl4_server(xdr, &res->cnr_src); if (unlikely(status)) return -EIO; return 0; } static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) { return decode_op_hdr(xdr, OP_DEALLOCATE); Loading Loading @@ -656,6 +816,32 @@ static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, return status; } /* * Decode COPY_NOTIFY response */ static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp, struct xdr_stream *xdr, void *data) { struct nfs42_copy_notify_res *res = data; struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->cnr_seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_copy_notify(xdr, res); out: return status; } /* * Decode DEALLOCATE request */ Loading fs/nfs/nfs4_fs.h +11 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,8 @@ enum { NFS_STATE_CHANGE_WAIT, /* A state changing operation is outstanding */ #ifdef CONFIG_NFS_V4_2 NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/ NFS_CLNT_SRC_SSC_COPY_STATE, /* src server open state on client*/ NFS_SRV_SSC_COPY_STATE, /* ssc state on the dst server */ #endif /* CONFIG_NFS_V4_2 */ }; Loading Loading @@ -311,6 +313,13 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx, fmode_t fmode); extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode); extern int update_open_stateid(struct nfs4_state *state, const nfs4_stateid *open_stateid, const nfs4_stateid *deleg_stateid, fmode_t fmode); extern int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo); Loading Loading @@ -457,6 +466,8 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, struct nfs_client **, const struct cred *); extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); extern void nfs41_notify_server(struct nfs_client *); bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1, struct nfs41_server_owner *o2); #else static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err) { Loading fs/nfs/nfs4client.c +1 −1 Original line number Diff line number Diff line Loading @@ -629,7 +629,7 @@ int nfs40_walk_client_list(struct nfs_client *new, /* * Returns true if the server major ids match */ static bool bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1, struct nfs41_server_owner *o2) { Loading Loading
fs/nfs/nfs42.h +14 −1 Original line number Diff line number Diff line Loading @@ -13,8 +13,10 @@ #define PNFS_LAYOUTSTATS_MAXDEV (4) /* nfs4.2proc.c */ #ifdef CONFIG_NFS_V4_2 int nfs42_proc_allocate(struct file *, loff_t, loff_t); ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t); ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t, struct nl4_server *, nfs4_stateid *, bool); int nfs42_proc_deallocate(struct file *, loff_t, loff_t); loff_t nfs42_proc_llseek(struct file *, loff_t, int); int nfs42_proc_layoutstats_generic(struct nfs_server *, Loading @@ -23,5 +25,16 @@ int nfs42_proc_clone(struct file *, struct file *, loff_t, loff_t, loff_t); int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg, const struct nfs42_layout_error *errors, size_t n); int nfs42_proc_copy_notify(struct file *, struct file *, struct nfs42_copy_notify_res *); static inline bool nfs42_files_from_same_server(struct file *in, struct file *out) { struct nfs_client *c_in = (NFS_SERVER(file_inode(in)))->nfs_client; struct nfs_client *c_out = (NFS_SERVER(file_inode(out)))->nfs_client; return nfs4_check_serverowner_major_id(c_in->cl_serverowner, c_out->cl_serverowner); } #endif /* CONFIG_NFS_V4_2 */ #endif /* __LINUX_FS_NFS_NFS4_2_H */
fs/nfs/nfs42proc.c +167 −32 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com> */ #include <linux/fs.h> #include <linux/sunrpc/addr.h> #include <linux/sunrpc/sched.h> #include <linux/nfs.h> #include <linux/nfs3.h> Loading @@ -15,10 +16,30 @@ #include "pnfs.h" #include "nfs4session.h" #include "internal.h" #include "delegation.h" #define NFSDBG_FACILITY NFSDBG_PROC static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std); static void nfs42_set_netaddr(struct file *filep, struct nfs42_netaddr *naddr) { struct nfs_client *clp = (NFS_SERVER(file_inode(filep)))->nfs_client; unsigned short port = 2049; rcu_read_lock(); naddr->netid_len = scnprintf(naddr->netid, sizeof(naddr->netid), "%s", rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_NETID)); naddr->addr_len = scnprintf(naddr->addr, sizeof(naddr->addr), "%s.%u.%u", rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR), port >> 8, port & 255); rcu_read_unlock(); } static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, struct nfs_lock_context *lock, loff_t offset, loff_t len) { Loading Loading @@ -132,22 +153,26 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) } static int handle_async_copy(struct nfs42_copy_res *res, struct nfs_server *server, struct nfs_server *dst_server, struct nfs_server *src_server, struct file *src, struct file *dst, nfs4_stateid *src_stateid) nfs4_stateid *src_stateid, bool *restart) { struct nfs4_copy_state *copy, *tmp_copy; int status = NFS4_OK; bool found_pending = false; struct nfs_open_context *ctx = nfs_file_open_context(dst); struct nfs_open_context *dst_ctx = nfs_file_open_context(dst); struct nfs_open_context *src_ctx = nfs_file_open_context(src); copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS); if (!copy) return -ENOMEM; spin_lock(&server->nfs_client->cl_lock); list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids, spin_lock(&dst_server->nfs_client->cl_lock); list_for_each_entry(tmp_copy, &dst_server->nfs_client->pending_cb_stateids, copies) { if (memcmp(&res->write_res.stateid, &tmp_copy->stateid, NFS4_STATEID_SIZE)) Loading @@ -157,7 +182,7 @@ static int handle_async_copy(struct nfs42_copy_res *res, break; } if (found_pending) { spin_unlock(&server->nfs_client->cl_lock); spin_unlock(&dst_server->nfs_client->cl_lock); kfree(copy); copy = tmp_copy; goto out; Loading @@ -165,19 +190,32 @@ static int handle_async_copy(struct nfs42_copy_res *res, memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE); init_completion(©->completion); copy->parent_state = ctx->state; copy->parent_dst_state = dst_ctx->state; copy->parent_src_state = src_ctx->state; list_add_tail(©->copies, &server->ss_copies); spin_unlock(&server->nfs_client->cl_lock); list_add_tail(©->copies, &dst_server->ss_copies); spin_unlock(&dst_server->nfs_client->cl_lock); if (dst_server != src_server) { spin_lock(&src_server->nfs_client->cl_lock); list_add_tail(©->src_copies, &src_server->ss_copies); spin_unlock(&src_server->nfs_client->cl_lock); } status = wait_for_completion_interruptible(©->completion); spin_lock(&server->nfs_client->cl_lock); spin_lock(&dst_server->nfs_client->cl_lock); list_del_init(©->copies); spin_unlock(&server->nfs_client->cl_lock); spin_unlock(&dst_server->nfs_client->cl_lock); if (dst_server != src_server) { spin_lock(&src_server->nfs_client->cl_lock); list_del_init(©->src_copies); spin_unlock(&src_server->nfs_client->cl_lock); } if (status == -ERESTARTSYS) { goto out_cancel; } else if (copy->flags) { } else if (copy->flags || copy->error == NFS4ERR_PARTNER_NO_AUTH) { status = -EAGAIN; *restart = true; goto out_cancel; } out: Loading @@ -185,12 +223,14 @@ static int handle_async_copy(struct nfs42_copy_res *res, memcpy(&res->write_res.verifier, ©->verf, sizeof(copy->verf)); status = -copy->error; out_free: kfree(copy); return status; out_cancel: nfs42_do_offload_cancel_async(dst, ©->stateid); kfree(copy); return status; if (!nfs42_files_from_same_server(src, dst)) nfs42_do_offload_cancel_async(src, src_stateid); goto out_free; } static int process_copy_commit(struct file *dst, loff_t pos_dst, Loading Loading @@ -222,7 +262,10 @@ static ssize_t _nfs42_proc_copy(struct file *src, struct file *dst, struct nfs_lock_context *dst_lock, struct nfs42_copy_args *args, struct nfs42_copy_res *res) struct nfs42_copy_res *res, struct nl4_server *nss, nfs4_stateid *cnr_stateid, bool *restart) { struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY], Loading @@ -230,17 +273,23 @@ static ssize_t _nfs42_proc_copy(struct file *src, .rpc_resp = res, }; struct inode *dst_inode = file_inode(dst); struct nfs_server *server = NFS_SERVER(dst_inode); struct inode *src_inode = file_inode(src); struct nfs_server *dst_server = NFS_SERVER(dst_inode); struct nfs_server *src_server = NFS_SERVER(src_inode); loff_t pos_src = args->src_pos; loff_t pos_dst = args->dst_pos; size_t count = args->count; ssize_t status; status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context, src_lock, FMODE_READ); if (nss) { args->cp_src = nss; nfs4_stateid_copy(&args->src_stateid, cnr_stateid); } else { status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context, src_lock, FMODE_READ); if (status) return status; } status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping, pos_src, pos_src + (loff_t)count - 1); if (status) Loading @@ -262,13 +311,15 @@ static ssize_t _nfs42_proc_copy(struct file *src, if (!res->commit_res.verf) return -ENOMEM; } set_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &src_lock->open_context->state->flags); set_bit(NFS_CLNT_DST_SSC_COPY_STATE, &dst_lock->open_context->state->flags); status = nfs4_call_sync(server->client, server, &msg, status = nfs4_call_sync(dst_server->client, dst_server, &msg, &args->seq_args, &res->seq_res, 0); if (status == -ENOTSUPP) server->caps &= ~NFS_CAP_COPY; dst_server->caps &= ~NFS_CAP_COPY; if (status) goto out; Loading @@ -280,8 +331,8 @@ static ssize_t _nfs42_proc_copy(struct file *src, } if (!res->synchronous) { status = handle_async_copy(res, server, src, dst, &args->src_stateid); status = handle_async_copy(res, dst_server, src_server, src, dst, &args->src_stateid, restart); if (status) return status; } Loading @@ -304,8 +355,9 @@ static ssize_t _nfs42_proc_copy(struct file *src, } ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, struct file *dst, loff_t pos_dst, size_t count) struct file *dst, loff_t pos_dst, size_t count, struct nl4_server *nss, nfs4_stateid *cnr_stateid, bool sync) { struct nfs_server *server = NFS_SERVER(file_inode(dst)); struct nfs_lock_context *src_lock; Loading @@ -316,7 +368,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, .dst_fh = NFS_FH(file_inode(dst)), .dst_pos = pos_dst, .count = count, .sync = false, .sync = sync, }; struct nfs42_copy_res res; struct nfs4_exception src_exception = { Loading @@ -328,6 +380,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, .stateid = &args.dst_stateid, }; ssize_t err, err2; bool restart = false; src_lock = nfs_get_lock_context(nfs_file_open_context(src)); if (IS_ERR(src_lock)) Loading @@ -347,21 +400,33 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, inode_lock(file_inode(dst)); err = _nfs42_proc_copy(src, src_lock, dst, dst_lock, &args, &res); &args, &res, nss, cnr_stateid, &restart); inode_unlock(file_inode(dst)); if (err >= 0) break; if (err == -ENOTSUPP) { if (err == -ENOTSUPP && nfs42_files_from_same_server(src, dst)) { err = -EOPNOTSUPP; break; } else if (err == -EAGAIN) { if (!restart) { dst_exception.retry = 1; continue; } break; } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) { args.sync = true; dst_exception.retry = 1; continue; } else if ((err == -ESTALE || err == -NFS4ERR_OFFLOAD_DENIED || err == -ENOTSUPP) && !nfs42_files_from_same_server(src, dst)) { nfs42_do_offload_cancel_async(src, &args.src_stateid); err = -EOPNOTSUPP; break; } err2 = nfs4_handle_exception(server, err, &src_exception); Loading Loading @@ -459,6 +524,76 @@ static int nfs42_do_offload_cancel_async(struct file *dst, return status; } int _nfs42_proc_copy_notify(struct file *src, struct file *dst, struct nfs42_copy_notify_args *args, struct nfs42_copy_notify_res *res) { struct nfs_server *src_server = NFS_SERVER(file_inode(src)); struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY_NOTIFY], .rpc_argp = args, .rpc_resp = res, }; int status; struct nfs_open_context *ctx; struct nfs_lock_context *l_ctx; ctx = get_nfs_open_context(nfs_file_open_context(src)); l_ctx = nfs_get_lock_context(ctx); if (IS_ERR(l_ctx)) return PTR_ERR(l_ctx); status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx, FMODE_READ); nfs_put_lock_context(l_ctx); if (status) return status; status = nfs4_call_sync(src_server->client, src_server, &msg, &args->cna_seq_args, &res->cnr_seq_res, 0); if (status == -ENOTSUPP) src_server->caps &= ~NFS_CAP_COPY_NOTIFY; put_nfs_open_context(nfs_file_open_context(src)); return status; } int nfs42_proc_copy_notify(struct file *src, struct file *dst, struct nfs42_copy_notify_res *res) { struct nfs_server *src_server = NFS_SERVER(file_inode(src)); struct nfs42_copy_notify_args *args; struct nfs4_exception exception = { .inode = file_inode(src), }; int status; if (!(src_server->caps & NFS_CAP_COPY_NOTIFY)) return -EOPNOTSUPP; args = kzalloc(sizeof(struct nfs42_copy_notify_args), GFP_NOFS); if (args == NULL) return -ENOMEM; args->cna_src_fh = NFS_FH(file_inode(src)), args->cna_dst.nl4_type = NL4_NETADDR; nfs42_set_netaddr(dst, &args->cna_dst.u.nl4_addr); exception.stateid = &args->cna_src_stateid; do { status = _nfs42_proc_copy_notify(src, dst, args, res); if (status == -ENOTSUPP) { status = -EOPNOTSUPP; goto out; } status = nfs4_handle_exception(src_server, status, &exception); } while (exception.retry); out: kfree(args); return status; } static loff_t _nfs42_proc_llseek(struct file *filep, struct nfs_lock_context *lock, loff_t offset, int whence) { Loading
fs/nfs/nfs42xdr.c +188 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,10 @@ #define encode_copy_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 2 + 2 + 2 + 1 + 1 + 1) 2 + 2 + 2 + 1 + 1 + 1 +\ 1 + /* One cnr_source_server */\ 1 + /* nl4_type */ \ 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define decode_copy_maxsz (op_decode_hdr_maxsz + \ NFS42_WRITE_RES_SIZE + \ 1 /* cr_consecutive */ + \ Loading @@ -29,6 +32,16 @@ #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE)) #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz) #define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 1 + /* nl4_type */ \ 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \ 3 + /* cnr_lease_time */\ XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 1 + /* Support 1 cnr_source_server */\ 1 + /* nl4_type */ \ 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ encode_fallocate_maxsz) #define decode_deallocate_maxsz (op_decode_hdr_maxsz) Loading Loading @@ -99,6 +112,12 @@ decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_offload_cancel_maxsz) #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_copy_notify_maxsz) #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_copy_notify_maxsz) #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ encode_sequence_maxsz + \ encode_putfh_maxsz + \ Loading Loading @@ -166,6 +185,26 @@ static void encode_allocate(struct xdr_stream *xdr, encode_fallocate(xdr, args); } static void encode_nl4_server(struct xdr_stream *xdr, const struct nl4_server *ns) { encode_uint32(xdr, ns->nl4_type); switch (ns->nl4_type) { case NL4_NAME: case NL4_URL: encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str); break; case NL4_NETADDR: encode_string(xdr, ns->u.nl4_addr.netid_len, ns->u.nl4_addr.netid); encode_string(xdr, ns->u.nl4_addr.addr_len, ns->u.nl4_addr.addr); break; default: WARN_ON_ONCE(1); } } static void encode_copy(struct xdr_stream *xdr, const struct nfs42_copy_args *args, struct compound_hdr *hdr) Loading @@ -180,7 +219,12 @@ static void encode_copy(struct xdr_stream *xdr, encode_uint32(xdr, 1); /* consecutive = true */ encode_uint32(xdr, args->sync); encode_uint32(xdr, 0); /* src server list */ if (args->cp_src == NULL) { /* intra-ssc */ encode_uint32(xdr, 0); /* no src server list */ return; } encode_uint32(xdr, 1); /* supporting 1 server */ encode_nl4_server(xdr, args->cp_src); } static void encode_offload_cancel(struct xdr_stream *xdr, Loading @@ -191,6 +235,15 @@ static void encode_offload_cancel(struct xdr_stream *xdr, encode_nfs4_stateid(xdr, &args->osa_stateid); } static void encode_copy_notify(struct xdr_stream *xdr, const struct nfs42_copy_notify_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr); encode_nfs4_stateid(xdr, &args->cna_src_stateid); encode_nl4_server(xdr, &args->cna_dst); } static void encode_deallocate(struct xdr_stream *xdr, const struct nfs42_falloc_args *args, struct compound_hdr *hdr) Loading Loading @@ -354,6 +407,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, encode_nops(&hdr); } /* * Encode COPY_NOTIFY request */ static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req, struct xdr_stream *xdr, const void *data) { const struct nfs42_copy_notify_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->cna_seq_args, &hdr); encode_putfh(xdr, args->cna_src_fh, &hdr); encode_copy_notify(xdr, args, &hdr); encode_nops(&hdr); } /* * Encode DEALLOCATE request */ Loading Loading @@ -490,6 +562,58 @@ static int decode_write_response(struct xdr_stream *xdr, return decode_verifier(xdr, &res->verifier.verifier); } static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) { struct nfs42_netaddr *naddr; uint32_t dummy; char *dummy_str; __be32 *p; int status; /* nl_type */ p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) return -EIO; ns->nl4_type = be32_to_cpup(p); switch (ns->nl4_type) { case NL4_NAME: case NL4_URL: status = decode_opaque_inline(xdr, &dummy, &dummy_str); if (unlikely(status)) return status; if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) return -EIO; memcpy(&ns->u.nl4_str, dummy_str, dummy); ns->u.nl4_str_sz = dummy; break; case NL4_NETADDR: naddr = &ns->u.nl4_addr; /* netid string */ status = decode_opaque_inline(xdr, &dummy, &dummy_str); if (unlikely(status)) return status; if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) return -EIO; naddr->netid_len = dummy; memcpy(naddr->netid, dummy_str, naddr->netid_len); /* uaddr string */ status = decode_opaque_inline(xdr, &dummy, &dummy_str); if (unlikely(status)) return status; if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) return -EIO; naddr->addr_len = dummy; memcpy(naddr->addr, dummy_str, naddr->addr_len); break; default: WARN_ON_ONCE(1); return -EIO; } return 0; } static int decode_copy_requirements(struct xdr_stream *xdr, struct nfs42_copy_res *res) { __be32 *p; Loading Loading @@ -529,6 +653,42 @@ static int decode_offload_cancel(struct xdr_stream *xdr, return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); } static int decode_copy_notify(struct xdr_stream *xdr, struct nfs42_copy_notify_res *res) { __be32 *p; int status, count; status = decode_op_hdr(xdr, OP_COPY_NOTIFY); if (status) return status; /* cnr_lease_time */ p = xdr_inline_decode(xdr, 12); if (unlikely(!p)) return -EIO; p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds); res->cnr_lease_time.nseconds = be32_to_cpup(p); status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE); if (unlikely(status)) return -EIO; /* number of source addresses */ p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) return -EIO; count = be32_to_cpup(p); if (count > 1) pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n", __func__, count); status = decode_nl4_server(xdr, &res->cnr_src); if (unlikely(status)) return -EIO; return 0; } static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) { return decode_op_hdr(xdr, OP_DEALLOCATE); Loading Loading @@ -656,6 +816,32 @@ static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, return status; } /* * Decode COPY_NOTIFY response */ static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp, struct xdr_stream *xdr, void *data) { struct nfs42_copy_notify_res *res = data; struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->cnr_seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_copy_notify(xdr, res); out: return status; } /* * Decode DEALLOCATE request */ Loading
fs/nfs/nfs4_fs.h +11 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,8 @@ enum { NFS_STATE_CHANGE_WAIT, /* A state changing operation is outstanding */ #ifdef CONFIG_NFS_V4_2 NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/ NFS_CLNT_SRC_SSC_COPY_STATE, /* src server open state on client*/ NFS_SRV_SSC_COPY_STATE, /* ssc state on the dst server */ #endif /* CONFIG_NFS_V4_2 */ }; Loading Loading @@ -311,6 +313,13 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx, fmode_t fmode); extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode); extern int update_open_stateid(struct nfs4_state *state, const nfs4_stateid *open_stateid, const nfs4_stateid *deleg_stateid, fmode_t fmode); extern int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo); Loading Loading @@ -457,6 +466,8 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, struct nfs_client **, const struct cred *); extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); extern void nfs41_notify_server(struct nfs_client *); bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1, struct nfs41_server_owner *o2); #else static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err) { Loading
fs/nfs/nfs4client.c +1 −1 Original line number Diff line number Diff line Loading @@ -629,7 +629,7 @@ int nfs40_walk_client_list(struct nfs_client *new, /* * Returns true if the server major ids match */ static bool bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1, struct nfs41_server_owner *o2) { Loading