diff options
Diffstat (limited to 'xlators/nfs/server/src/nfs3.c')
| -rw-r--r-- | xlators/nfs/server/src/nfs3.c | 1643 |
1 files changed, 944 insertions, 699 deletions
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index e43b666d8..f914c3193 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H @@ -32,13 +23,15 @@ #include "nfs3.h" #include "mem-pool.h" #include "logging.h" +#include "nfs-common.h" #include "nfs-fops.h" #include "nfs-inodes.h" #include "nfs-generics.h" #include "nfs3-helpers.h" #include "nfs-mem-types.h" #include "nfs.h" - +#include "xdr-rpc.h" +#include "xdr-generic.h" #include <sys/socket.h> #include <sys/uio.h> @@ -49,6 +42,8 @@ do { \ if ((str)) { \ if (strlen ((str)) > (len)) { \ + gf_log (GF_NFS3, GF_LOG_ERROR, "strlen "\ + "too long"); \ status = NFS3ERR_NAMETOOLONG; \ retval = -ENAMETOOLONG; \ goto label; \ @@ -58,8 +53,8 @@ #define nfs3_validate_nfs3_state(request, state, status, label, retval) \ do { \ - state = nfs_rpcsvc_request_program_private (request); \ - if (!nfs3) { \ + state = rpcsvc_request_program_private (request); \ + if (!state) { \ gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state " \ "missing from RPC request"); \ status = NFS3ERR_SERVERFAULT; \ @@ -85,6 +80,7 @@ __nfs3_get_export_by_index (struct nfs3_state *nfs3, uuid_t exportid) } exp = NULL; + gf_log (GF_NFS, GF_LOG_ERROR, "searchindex=%d not found", searchindex); found: return exp; } @@ -129,8 +125,7 @@ nfs3_export_access (struct nfs3_state *nfs3, uuid_t exportid) int ret = GF_NFS3_VOLACCESS_RO; struct nfs3_export *exp = NULL; - if (!nfs3) - return ret; + GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, err); exp = __nfs3_get_export_by_exportid (nfs3, exportid); @@ -148,7 +143,7 @@ err: #define nfs3_check_rw_volaccess(nfs3state, exid, status, label) \ do { \ if (nfs3_export_access (nfs3state,exid)!=GF_NFS3_VOLACCESS_RW){\ - gf_log (GF_NFS3, GF_LOG_TRACE, "No read-write access");\ + gf_log (GF_NFS3, GF_LOG_ERROR, "No read-write access");\ status = NFS3ERR_ROFS; \ goto label; \ } \ @@ -162,8 +157,8 @@ nfs3_fh_to_xlator (struct nfs3_state *nfs3, struct nfs3_fh *fh) xlator_t *vol = NULL; struct nfs3_export *exp = NULL; - if ((!nfs3) || (!fh)) - return vol; + GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out); exp = __nfs3_get_export_by_exportid (nfs3, fh->exportid); if (!exp) @@ -181,8 +176,8 @@ nfs3_is_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh) struct nfs3_export *exp = NULL; int ret = 0; - if ((!nfs3) || (!rootfh)) - return 0; + GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, rootfh, out); exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid); if (!exp) @@ -200,8 +195,8 @@ nfs3_set_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh) struct nfs3_export *exp = NULL; int ret = 0; - if ((!nfs3) || (!rootfh)) - return 0; + GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, rootfh, out); exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid); if (!exp) @@ -213,35 +208,60 @@ out: } -#define nfs3_map_fh_to_volume(nfs3state, handle, rqst, volume, status, label) \ +#define nfs3_map_fh_to_volume(nfs3state, handle, req, volume, status, label) \ do { \ + char exportid[256], gfid[256]; \ + rpc_transport_t *trans = NULL; \ volume = nfs3_fh_to_xlator ((nfs3state), handle); \ if (!volume) { \ - gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to map " \ - "FH to vol"); \ + uuid_unparse (handle->exportid, exportid); \ + uuid_unparse (handle->gfid, gfid); \ + trans = rpcsvc_request_transport (req); \ + GF_LOG_OCCASIONALLY (nfs3state->occ_logger, \ + GF_NFS3, GF_LOG_ERROR, "Failed to map " \ + "FH to vol: client=%s, exportid=%s, " \ + "gfid=%s", trans->peerinfo.identifier, \ + exportid, gfid); \ + GF_LOG_OCCASIONALLY (nfs3state->occ_logger, \ + GF_NFS3, GF_LOG_ERROR, "Stale nfs " \ + "client %s must be trying to connect to"\ + " a deleted volume, please unmount it.",\ + trans->peerinfo.identifier); \ status = NFS3ERR_STALE; \ goto label; \ } else { \ - gf_log (GF_NFS3, GF_LOG_TRACE, "FH to Volume: %s"\ - ,volume->name); \ - nfs_rpcsvc_request_set_private (req, volume); \ + gf_log (GF_NFS3, GF_LOG_TRACE, "FH to Volume:" \ + "%s", volume->name); \ + rpcsvc_request_set_private (req, volume); \ } \ } while (0); \ #define nfs3_validate_gluster_fh(handle, status, errlabel) \ do { \ - if ((handle)) { \ - if (!nfs3_fh_validate (handle)) { \ - status = NFS3ERR_BADHANDLE; \ - goto errlabel; \ - } \ + if (!nfs3_fh_validate (handle)) { \ + gf_log (GF_NFS3, GF_LOG_ERROR, "Bad Handle"); \ + status = NFS3ERR_BADHANDLE; \ + goto errlabel; \ } \ } while (0) \ #define nfs3_check_fh_resolve_status(cst, nfstat, erlabl) \ do { \ + xlator_t *xlatorp = NULL; \ + char buf[256], gfid[256]; \ + rpc_transport_t *trans = NULL; \ if ((cst)->resolve_ret < 0) { \ + trans = rpcsvc_request_transport (cst->req); \ + xlatorp = nfs3_fh_to_xlator (cst->nfs3state, \ + &cst->resolvefh); \ + uuid_unparse (cst->resolvefh.gfid, gfid); \ + snprintf (buf, sizeof (buf), "(%s) %s : %s", \ + trans->peerinfo.identifier, \ + xlatorp ? xlatorp->name : "ERR", \ + gfid ); \ + gf_log (GF_NFS3, GF_LOG_ERROR, "%s: %s", \ + strerror(cst->resolve_errno), buf); \ nfstat = nfs3_errno_to_nfsstat3 (cst->resolve_errno);\ goto erlabl; \ } \ @@ -249,8 +269,21 @@ out: #define nfs3_check_new_fh_resolve_status(cst, nfstat, erlabl) \ do { \ + xlator_t *xlatorp = NULL; \ + char buf[256], gfid[256]; \ + rpc_transport_t *trans = NULL; \ if (((cst)->resolve_ret < 0) && \ ((cst)->resolve_errno != ENOENT)) { \ + trans = rpcsvc_request_transport (cst->req); \ + xlatorp = nfs3_fh_to_xlator (cst->nfs3state, \ + &cst->resolvefh); \ + uuid_unparse (cst->resolvefh.gfid, gfid); \ + snprintf (buf, sizeof (buf), "(%s) %s : %s", \ + trans->peerinfo.identifier, \ + xlatorp ? xlatorp->name : "ERR", \ + gfid); \ + gf_log (GF_NFS3, GF_LOG_ERROR, "%s: %s", \ + strerror(cst->resolve_errno), buf); \ nfstat = nfs3_errno_to_nfsstat3 (cs->resolve_errno);\ goto erlabl; \ } \ @@ -264,8 +297,8 @@ __nfs3_get_volume_id (struct nfs3_state *nfs3, xlator_t *xl, int ret = -1; struct nfs3_export *exp = NULL; - if ((!nfs3) || (!xl)) - return ret; + GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, xl, out); list_for_each_entry (exp, &nfs3->exports, explist) { if (exp->subvol == xl) { @@ -321,8 +354,7 @@ nfs3_export_sync_trusted (struct nfs3_state *nfs3, uuid_t exportid) struct nfs3_export *exp = NULL; int ret = 0; - if (!nfs3) - return ret; + GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, err); exp = __nfs3_get_export_by_exportid (nfs3, exportid); if (!exp) @@ -340,8 +372,7 @@ nfs3_export_write_trusted (struct nfs3_state *nfs3, uuid_t exportid) struct nfs3_export *exp = NULL; int ret = 0; - if (!nfs3) - return ret; + GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, err); exp = __nfs3_get_export_by_exportid (nfs3, exportid); if (!exp) @@ -379,12 +410,15 @@ nfs3_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req, xlator_t *v) { nfs3_call_state_t *cs = NULL; - if ((!s) || (!req) || (!v)) - return NULL; + GF_VALIDATE_OR_GOTO (GF_NFS3, s, err); + GF_VALIDATE_OR_GOTO (GF_NFS3, req, err); + GF_VALIDATE_OR_GOTO (GF_NFS3, v, err); cs = (nfs3_call_state_t *) mem_get (s->localpool); - if (!cs) + if (!cs) { + gf_log (GF_NFS3, GF_LOG_ERROR, "out of memory"); return NULL; + } memset (cs, 0, sizeof (*cs)); INIT_LIST_HEAD (&cs->entries.list); @@ -394,29 +428,25 @@ nfs3_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req, xlator_t *v) cs->vol = v; cs->nfsx = s->nfsx; cs->nfs3state = s; - +err: return cs; } void nfs3_call_state_wipe (nfs3_call_state_t *cs) { - struct nfs3_state *nfs3 = NULL; if (!cs) return; - nfs3 = cs->nfs3state; if (cs->fd) { gf_log (GF_NFS3, GF_LOG_TRACE, "fd 0x%lx ref: %d", (long)cs->fd, cs->fd->refcount); fd_unref (cs->fd); } - if (cs->resolventry) - GF_FREE (cs->resolventry); + GF_FREE (cs->resolventry); - if (cs->pathname) - GF_FREE (cs->pathname); + GF_FREE (cs->pathname); if (!list_empty (&cs->entries.list)) gf_dirent_free (&cs->entries); @@ -425,8 +455,12 @@ nfs3_call_state_wipe (nfs3_call_state_t *cs) nfs_loc_wipe (&cs->resolvedloc); if (cs->iob) iobuf_unref (cs->iob); + if (cs->iobref) + iobref_unref (cs->iobref); + if (cs->trans) + rpc_transport_unref (cs->trans); memset (cs, 0, sizeof (*cs)); - mem_put (nfs3->localpool, cs); + mem_put (cs); /* Already refd by fd_lookup, so no need to ref again. */ } @@ -452,7 +486,7 @@ nfs3_serialize_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc, struct iobuf *iob = NULL; ssize_t retlen = -1; - nfs3 = (struct nfs3_state *)nfs_rpcsvc_request_program_private (req); + nfs3 = (struct nfs3_state *)rpcsvc_request_program_private (req); if (!nfs3) { gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state not found in RPC" " request"); @@ -462,6 +496,8 @@ nfs3_serialize_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc, /* First, get the io buffer into which the reply in arg will * be serialized. */ + /* TODO: get rid of 'sfunc' and use 'xdrproc_t' so we + can have 'xdr_sizeof' */ iob = iobuf_get (nfs3->iobpool); if (!iob) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to get iobuf"); @@ -500,6 +536,7 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc) struct iovec outmsg = {0, }; struct iobuf *iob = NULL; int ret = -1; + struct iobref *iobref = NULL; if (!req) return -1; @@ -510,14 +547,20 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc) goto ret; } - /* Then, submit the message for transmission. */ - ret = nfs_rpcsvc_submit_message (req, outmsg, iob); + iobref = iobref_new (); + if (!iobref) { + gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new()"); + goto ret; + } - /* Now that we've done our job of handing the message to the RPC layer - * we can safely unref the iob in the hope that RPC layer must have - * ref'ed the iob on receiving into the txlist. - */ - iobuf_unref (iob); + ret = iobref_add (iobref, iob); + if (ret) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to add iob to iobref"); + goto ret; + } + + /* Then, submit the message for transmission. */ + ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref); if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed"); goto ret; @@ -525,6 +568,14 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc) ret = 0; ret: + /* Now that we've done our job of handing the message to the RPC layer + * we can safely unref the iob in the hope that RPC layer must have + * ref'ed the iob on receiving into the txlist. + */ + if (NULL != iob) + iobuf_unref (iob); + if (NULL != iobref) + iobref_unref (iobref); return ret; } @@ -532,11 +583,12 @@ ret: int nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc, struct iovec *payload, - int vcount, struct iobref *piobref) + int vcount, struct iobref *iobref) { struct iovec outmsg = {0, }; struct iobuf *iob = NULL; int ret = -1; + int new_iobref = 0; if (!req) return -1; @@ -544,25 +596,43 @@ nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg, iob = nfs3_serialize_reply (req, arg, sfunc, &outmsg); if (!iob) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to serialize reply"); - goto err; + goto ret; + } + if (iobref == NULL) { + iobref = iobref_new (); + if (!iobref) { + gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new"); + goto ret; + } + new_iobref = 1; } - ret = nfs_rpcsvc_request_attach_vector (req, outmsg, iob, NULL, 0); - iobuf_unref (iob); - - if (piobref) - ret = nfs_rpcsvc_request_attach_vectors (req, payload, vcount, - piobref); + ret = iobref_add (iobref, iob); + if (ret) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to add iob to iobref"); + goto ret; + } - if (ret == -1) - goto err; - ret = nfs_rpcsvc_submit_vectors (req); -err: + /* Then, submit the message for transmission. */ + ret = rpcsvc_submit_message (req, &outmsg, 1, payload, vcount, iobref); + if (ret == -1) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed"); + goto ret; + } + ret = 0; +ret: + /* Now that we've done our job of handing the message to the RPC layer + * we can safely unref the iob in the hope that RPC layer must have + * ref'ed the iob on receiving into the txlist. + */ + if (NULL != iob) + iobuf_unref (iob); + if (new_iobref) + iobref_unref (iobref); return ret; } - uint64_t nfs3_request_xlator_deviceid (rpcsvc_request_t *rq) { @@ -574,8 +644,8 @@ nfs3_request_xlator_deviceid (rpcsvc_request_t *rq) if (!rq) return 0; - xl = nfs_rpcsvc_request_private (rq); - nfs3 = nfs_rpcsvc_request_program_private (rq); + xl = rpcsvc_request_private (rq); + nfs3 = rpcsvc_request_program_private (rq); if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) devid = (uint64_t)nfs_xlator_to_xlid (nfs3->exportslist, xl); else { @@ -593,8 +663,7 @@ nfs3svc_null (rpcsvc_request_t *req) struct iovec dummyvec = {0, }; if (!req) return RPCSVC_ACTOR_ERROR; - - nfs_rpcsvc_submit_generic (req, dummyvec, NULL); + rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL); return RPCSVC_ACTOR_SUCCESS; } @@ -625,10 +694,23 @@ nfs3svc_getattr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; - if (op_ret == -1) - status = nfs3_errno_to_nfsstat3 (op_errno); + /* + * Somewhat counter-intuitively, we don't need to look for sh-failed + * here. Failing this getattr will generate a new lookup from the + * client, and nfs_fop_lookup_cbk will detect any self-heal failures. + */ - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "GETATTR", + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + status = nfs3_cbk_errno_status (op_ret, op_errno); + } + else { + nfs_fix_generation(this,inode); + } + + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_GETATTR, status, op_errno); nfs3_getattr_reply (cs->req, status, buf); @@ -640,17 +722,22 @@ nfs3svc_getattr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t nfs3svc_getattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { nfsstat3 status = NFS3_OK; nfs3_call_state_t *cs = NULL; cs = frame->local; - if (op_ret == -1) - status = nfs3_errno_to_nfsstat3 (op_errno); + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + status = nfs3_cbk_errno_status (op_ret, op_errno); + } - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "GETATTR", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_GETATTR, status, op_errno); nfs3_getattr_reply (cs->req, status, buf); @@ -667,6 +754,9 @@ nfs3_getattr_resume (void *carg) int ret = -EFAULT; nfs_user_t nfu = {0, }; nfs3_call_state_t *cs = NULL; + uint64_t raw_ctx = 0; + struct nfs_inode_ctx *ictx = NULL; + struct nfs_state *priv = NULL; if (!carg) return ret; @@ -679,14 +769,42 @@ nfs3_getattr_resume (void *carg) * for the root to have been looked up when the getattr on the root is * sent. AND, this causes a problem for stat-prefetch in that it * expects even the root inode to have been looked up. - */ - if (cs->resolvedloc.inode->ino == 1) + + if (__is_root_gfid (cs->resolvedloc.inode->gfid)) ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, nfs3svc_getattr_lookup_cbk, cs); else ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3svc_getattr_stat_cbk, cs); + */ + + if (cs->hardresolved) { + ret = -EFAULT; + stat = NFS3_OK; + goto nfs3err; + } + + /* + * If brick state changed, we need to force a proper lookup cycle (as + * would happen in native protocol) to do self-heal checks. We detect + * this by comparing the generation number for the last successful + * creation/lookup on the inode to the current number, so inodes that + * haven't been validated since the state change are affected. + */ + if (inode_ctx_get(cs->resolvedloc.inode,cs->nfsx,&raw_ctx) == 0) { + ictx = (struct nfs_inode_ctx *)raw_ctx; + priv = cs->nfsx->private; + if (ictx->generation != priv->generation) { + ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, + &cs->resolvedloc, + nfs3svc_getattr_lookup_cbk, cs); + goto check_err; + } + } + ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + nfs3svc_getattr_stat_cbk, cs); + +check_err: if (ret < 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Stat fop failed: %s: %s", cs->oploc.path, strerror (-ret)); @@ -695,9 +813,9 @@ nfs3_getattr_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "GETATTR", stat, -ret); - nfs3_getattr_reply (cs->req, stat, NULL); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_GETATTR, stat, -ret); + nfs3_getattr_reply (cs->req, stat, &cs->stbuf); nfs3_call_state_wipe (cs); ret = 0; } @@ -715,10 +833,10 @@ nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh) struct nfs3_state *nfs3 = NULL; nfs3_call_state_t *cstate = NULL; - if ((!req) || (!fh)) - return -1; + GF_VALIDATE_OR_GOTO (GF_NFS3, req, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out); - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "GETATTR", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "GETATTR", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -731,7 +849,7 @@ nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "GETATTR", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_GETATTR, stat, -ret); nfs3_getattr_reply (req, stat, NULL); ret = 0; @@ -753,16 +871,16 @@ nfs3svc_getattr (rpcsvc_request_t *req) return ret; nfs3_prep_getattr3args (&args, &fh); - if (xdr_to_getattr3args (req->msg, &args) <= 0) { + if (xdr_to_getattr3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_getattr (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "GETATTR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -789,7 +907,7 @@ nfs3_setattr_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preop, int32_t nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) + struct iatt *postbuf, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; struct iatt *prestat = NULL; @@ -797,7 +915,10 @@ nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } @@ -812,7 +933,7 @@ nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "SETATTR", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_SETATTR, stat, op_errno); nfs3_setattr_reply (cs->req, stat, prestat, postbuf); nfs3_call_state_wipe (cs); @@ -824,7 +945,7 @@ nfs3err: int32_t nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preop, - struct iatt *postop) + struct iatt *postop, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -1; @@ -834,28 +955,25 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } - /* If the first stat was got from the guarded setattr callback, then - * we'll need to use that stat instead of the preop returned here. + prebuf = preop; + /* Store the current preop in case we need to send a truncate, + * in which case the preop to be returned will be this one. */ - if (cs->preparent.ia_ino != 0) - prebuf = &cs->preparent; - else { - prebuf = preop; - /* Store the current preop in case we need to send a truncate, - * in which case the preop to be returned will be this one. - */ - cs->preparent = *preop; - } + cs->preparent = *preop; /* Only truncate if the size is not already same as the requested * truncation and also only if this is not a directory. */ if ((gf_attr_size_set (cs->setattr_valid)) && - (!IA_ISDIR (postop->ia_type))) { + (!IA_ISDIR (postop->ia_type)) && + (preop->ia_size != cs->stbuf.ia_size)) { nfs_request_user_init (&nfu, cs->req); ret = nfs_truncate (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, cs->stbuf.ia_size, nfs3svc_truncate_cbk,cs); @@ -869,8 +987,8 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "SETATTR", stat, op_errno); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_SETATTR, stat, op_errno); nfs3_setattr_reply (cs->req, stat, prebuf, postop); nfs3_call_state_wipe (cs); } @@ -882,7 +1000,8 @@ nfs3err: int32_t nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { int ret = -EFAULT; @@ -892,12 +1011,15 @@ nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } if (buf->ia_ctime != cs->timestamp.seconds) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Timestamps not in sync"); + gf_log (GF_NFS3, GF_LOG_ERROR, "Timestamps not in sync"); stat = NFS3ERR_NOT_SYNC; goto nfs3err; } @@ -912,8 +1034,8 @@ nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "SETATTR", stat, op_errno); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_SETATTR, stat, op_errno); nfs3_setattr_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); } @@ -936,22 +1058,17 @@ nfs3_setattr_resume (void *carg) cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); nfs_request_user_init (&nfu, cs->req); - /* If no ctime check is required, head straight to setting the attrs. */ - if (cs->sattrguardcheck) - ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3svc_setattr_stat_cbk, cs); - else - ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - &cs->stbuf, cs->setattr_valid, - nfs3svc_setattr_cbk, cs); + ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + &cs->stbuf, cs->setattr_valid, + nfs3svc_setattr_cbk, cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "SETATTR", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_SETATTR, stat, -ret); nfs3_setattr_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); } @@ -970,12 +1087,12 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr, struct nfs3_state *nfs3 = NULL; nfs3_call_state_t *cs = NULL; - if ((!req) || (!fh) || (!sattr) || (!guard)) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments"); - return -1; - } + GF_VALIDATE_OR_GOTO (GF_NFS3, req, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, sattr, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, guard, out); - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "SETATTR", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "SETATTR", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -997,6 +1114,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr, if (!cs->setattr_valid) { ret = -EINVAL; /* Force a reply */ stat = NFS3_OK; + gf_log (GF_NFS3, GF_LOG_ERROR, "cs->setattr_valid is invalid"); goto nfs3err; } @@ -1006,7 +1124,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "SETATTR", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_SETATTR, stat, -ret); nfs3_setattr_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1028,20 +1146,19 @@ nfs3svc_setattr (rpcsvc_request_t *req) setattr3args args; int ret = RPCSVC_ACTOR_ERROR; - if (!req) - return ret; + GF_VALIDATE_OR_GOTO (GF_NFS3, req, rpcerr); nfs3_prep_setattr3args (&args, &fh); - if (xdr_to_setattr3args (req->msg, &args) <= 0) { + if (xdr_to_setattr3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_setattr (req, &fh, &args.new_attributes, &args.guard); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "SETATTR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1074,9 +1191,7 @@ nfs3_fresh_lookup (nfs3_call_state_t *cs) int ret = -EFAULT; char *oldresolventry = NULL; - if (!cs) - return -1; - + GF_VALIDATE_OR_GOTO (GF_NFS3, cs, err); gf_log (GF_NFS3, GF_LOG_DEBUG, "inode needs fresh lookup"); inode_unlink (cs->resolvedloc.inode, cs->resolvedloc.parent, cs->resolventry); @@ -1093,7 +1208,7 @@ nfs3_fresh_lookup (nfs3_call_state_t *cs) * same call_state. */ GF_FREE (oldresolventry); - +err: return ret; } @@ -1109,12 +1224,17 @@ nfs3svc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - status = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, + (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING), + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + status = nfs3_cbk_errno_status (op_ret, op_errno); goto xmit_res; } nfs3_fh_build_child_fh (&cs->parent, buf, &newfh); - oldinode = inode_link (inode, cs->resolvedloc.parent, cs->resolvedloc.name, buf); + oldinode = inode_link (inode, cs->resolvedloc.parent, + cs->resolvedloc.name, buf); xmit_res: /* Only send fresh lookup if it was a revalidate that failed. */ if ((op_ret == -1) && (nfs3_is_revalidate_lookup (cs))) { @@ -1122,7 +1242,7 @@ xmit_res: goto out; } - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, status, op_errno, &newfh); nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent); nfs3_call_state_wipe (cs); @@ -1149,7 +1269,10 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - status = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + status = nfs3_cbk_errno_status (op_ret, op_errno); goto xmit_res; } @@ -1172,7 +1295,7 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } xmit_res: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, status, op_errno, &newfh); nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent); nfs3_call_state_wipe (cs); @@ -1191,8 +1314,11 @@ nfs3_lookup_parentdir_resume (void *carg) nfs3_call_state_t *cs = NULL; inode_t *parent = NULL; - if (!carg) - return ret; + if (!carg) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Invalid argument," + " carg value NULL"); + return EINVAL; + } cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); @@ -1223,10 +1349,14 @@ nfs3_lookup_parentdir_resume (void *carg) if (!nfs3_fh_is_root_fh (&cs->fh)) { parent = inode_ref (cs->resolvedloc.parent); nfs_loc_wipe (&cs->resolvedloc); - ret = nfs_inode_loc_fill (parent, &cs->resolvedloc); + ret = nfs_inode_loc_fill (parent, &cs->resolvedloc, + NFS_RESOLVE_CREATE); - if (ret < 0) + if (ret < 0) { + gf_log (GF_NFS3, GF_LOG_ERROR, "nfs_inode_loc_fill" + " error"); goto errtostat; + } } ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, @@ -1237,7 +1367,7 @@ errtostat: nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, stat, -ret); nfs3_lookup_reply (cs->req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1257,14 +1387,25 @@ nfs3_lookup_resume (void *carg) int ret = -EFAULT; nfs_user_t nfu = {0, }; nfs3_call_state_t *cs = NULL; + struct nfs3_fh newfh = {{0},}; - if (!carg) - return ret; + if (!carg) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Invalid argument," + " carg value NULL"); + return EINVAL; + } cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); - nfs_request_user_init (&nfu, cs->req); cs->parent = cs->resolvefh; + + if (cs->hardresolved) { + stat = NFS3_OK; + nfs3_fh_build_child_fh (&cs->parent, &cs->stbuf, &newfh); + goto nfs3err; + } + + nfs_request_user_init (&nfu, cs->req); ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, nfs3svc_lookup_cbk, cs); if (ret < 0) @@ -1272,9 +1413,10 @@ nfs3_lookup_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, stat, -ret); - nfs3_lookup_reply (cs->req, stat, NULL, NULL, NULL); + nfs3_lookup_reply (cs->req, stat, &newfh, &cs->stbuf, + &cs->postparent); nfs3_call_state_wipe (cs); } @@ -1291,12 +1433,11 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name) struct nfs3_state *nfs3 = NULL; nfs3_call_state_t *cs = NULL; - if ((!req) || (!fh) || (!name)) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments"); - return -1; - } + GF_VALIDATE_OR_GOTO (GF_NFS3, req, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out); + GF_VALIDATE_OR_GOTO (GF_NFS3, name, out); - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "LOOKUP", fh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "LOOKUP", fh, name); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); if (nfs3_solaris_zerolen_fh (fh, fhlen)) @@ -1309,19 +1450,17 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name) nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->lookuptype = GF_NFS3_REVALIDATE; - if (!nfs3_is_parentdir_entry (name)) - ret = nfs3_fh_resolve_and_resume (cs, fh, name, - nfs3_lookup_resume); - else - ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, - nfs3_lookup_parentdir_resume); + ret = nfs3_fh_resolve_and_resume (cs, fh, name, + nfs3_lookup_resume); - if (ret < 0) + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "failed to start hard reslove"); stat = nfs3_errno_to_nfsstat3 (-ret); + } nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "LOOKUP", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_LOOKUP, stat, -ret); nfs3_lookup_reply (req, stat, NULL, NULL, NULL); @@ -1344,20 +1483,19 @@ nfs3svc_lookup (rpcsvc_request_t *req) lookup3args args; int ret = RPCSVC_ACTOR_ERROR; - if (!req) - return ret; + GF_VALIDATE_OR_GOTO (GF_NFS, req, rpcerr); nfs3_prep_lookup3args (&args, &fh, name); - if (xdr_to_lookup3args (req->msg, &args) <= 0) { + if (xdr_to_lookup3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_lookup (req, &fh, args.what.dir.data.data_len, name); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "LOOKUP procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1367,20 +1505,12 @@ rpcerr: int -nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf, - uint32_t accbits) +nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits, + int32_t reqaccbits) { access3res res; - uint64_t deviceid = 0; - gid_t *gidarr = NULL; - int gids = 0; - deviceid = nfs3_request_xlator_deviceid (req); - gidarr = nfs_rpcsvc_auth_unix_auxgids (req, &gids); - nfs3_fill_access3res (&res, status, buf, accbits, - nfs_rpcsvc_request_uid (req), - nfs_rpcsvc_request_gid (req), deviceid, gidarr, - gids); + nfs3_fill_access3res (&res, status, accbits, reqaccbits); nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_access3res); return 0; @@ -1389,19 +1519,22 @@ nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf, int32_t nfs3svc_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, dict_t *xdata) { nfsstat3 status = NFS3_OK; nfs3_call_state_t *cs = NULL; cs = frame->local; - if (op_ret == -1) - status = nfs3_errno_to_nfsstat3 (op_errno); - - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS", status, + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + status = nfs3_cbk_errno_status (op_ret, op_errno); + } + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_ACCESS, status, op_errno); - nfs3_access_reply (cs->req, status, buf, cs->accessbits); + nfs3_access_reply (cs->req, status, op_errno, cs->accessbits); nfs3_call_state_wipe (cs); return 0; @@ -1415,23 +1548,26 @@ nfs3_access_resume (void *carg) nfs_user_t nfu = {0, }; nfs3_call_state_t *cs = NULL; - if (!carg) - return ret; + if (!carg) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Invalid argument," + " carg value NULL"); + return EINVAL; + } cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); cs->fh = cs->resolvefh; nfs_request_user_init (&nfu, cs->req); - ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3svc_access_cbk, cs); + ret = nfs_access (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + cs->accessbits, nfs3svc_access_cbk, cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_ACCESS, stat, -ret); - nfs3_access_reply (cs->req, stat, NULL, 0); + nfs3_access_reply (cs->req, stat, 0, 0); nfs3_call_state_wipe (cs); ret = 0; } @@ -1449,10 +1585,9 @@ nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits) int ret = -EFAULT; nfs3_call_state_t *cs = NULL; - if ((!req) || (!fh)) - return -1; - - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "ACCESS", fh); + GF_VALIDATE_OR_GOTO (GF_NFS, req, out); + GF_VALIDATE_OR_GOTO (GF_NFS, fh, out); + nfs3_log_common_call (rpcsvc_request_xid (req), "ACCESS", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -1466,9 +1601,9 @@ nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "ACCESS", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_ACCESS, stat, -ret); - nfs3_access_reply (req, stat, NULL, 0); + nfs3_access_reply (req, stat, 0, 0); nfs3_call_state_wipe (cs); ret = 0; } @@ -1488,16 +1623,16 @@ nfs3svc_access (rpcsvc_request_t *req) return ret; nfs3_prep_access3args (&args, &fh); - if (xdr_to_access3args (req->msg, &args) <= 0) { + if (xdr_to_access3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_access (req, &fh, args.access); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "ACCESS procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1525,21 +1660,24 @@ nfs3_readlink_reply (rpcsvc_request_t *req, nfsstat3 stat, char *path, int32_t nfs3svc_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, const char *path, - struct iatt *buf) + struct iatt *buf, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } stat = NFS3_OK; nfs3err: - nfs3_log_readlink_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3_log_readlink_res (rpcsvc_request_xid (cs->req), stat, op_errno, (char *)path); nfs3_readlink_reply (cs->req, stat, (char *)path, buf); nfs3_call_state_wipe (cs); @@ -1569,8 +1707,8 @@ nfs3_readlink_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "READLINK", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_READLINK, stat, -ret); nfs3_readlink_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); } @@ -1593,7 +1731,7 @@ nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "READLINK", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "READLINK", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -1606,7 +1744,7 @@ nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "READLINK", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_READLINK, stat, -ret); nfs3_readlink_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1631,16 +1769,16 @@ nfs3svc_readlink (rpcsvc_request_t *req) return ret; nfs3_prep_readlink3args (&args, &fh); - if (xdr_to_readlink3args (req->msg, &args) <= 0) { + if (xdr_to_readlink3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_readlink (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READLINK procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1660,17 +1798,19 @@ nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count, deviceid = nfs3_request_xlator_deviceid (req); nfs3_fill_read3res (&res, stat, count, poststat, is_eof, deviceid); if (stat == NFS3_OK) { - nfs_xdr_vector_round_up (vec, vcount, count); + xdr_vector_round_up (vec, vcount, count); /* iob can be zero if the file size was zero. If so, op_ret * would be 0 and count = 0. */ + if (count != 0) { nfs3svc_submit_vector_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_read3res_nocopy, vec, vcount, iobref); } else - nfs3svc_submit_reply (req, (void *)&res, + + nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_read3res_nocopy); } else @@ -1685,7 +1825,8 @@ nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count, int32_t nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, - int32_t count, struct iatt *stbuf, struct iobref *iobref) + int32_t count, struct iatt *stbuf, struct iobref *iobref, + dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int is_eof = 0; @@ -1693,7 +1834,10 @@ nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto err; } else stat = NFS3_OK; @@ -1702,7 +1846,7 @@ nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this, is_eof = 1; err: - nfs3_log_read_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3_log_read_res (rpcsvc_request_xid (cs->req), stat, op_errno, op_ret, is_eof, vector, count); nfs3_read_reply (cs->req, stat, op_ret, vector, count, iobref, stbuf, is_eof); @@ -1732,7 +1876,7 @@ nfs3_read_fd_resume (void *carg) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "READ", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_READ, stat, -ret); nfs3_read_reply (cs->req, stat, 0, NULL, 0, NULL, NULL, 0); nfs3_call_state_wipe (cs); @@ -1748,19 +1892,25 @@ nfs3_read_resume (void *carg) nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -EFAULT; nfs3_call_state_t *cs = NULL; + fd_t *fd = NULL; if (!carg) return ret; cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); - ret = nfs3_file_open_and_resume (cs, nfs3_read_fd_resume); - if (ret < 0) - stat = nfs3_errno_to_nfsstat3 (-ret); + fd = fd_anonymous (cs->resolvedloc.inode); + if (!fd) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to create anonymous fd"); + goto nfs3err; + } + cs->fd = fd; + nfs3_read_fd_resume (cs); + ret = 0; nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "READ", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_READ, stat, -ret); nfs3_read_reply (cs->req, stat, 0, NULL,0, NULL, NULL, 0); nfs3_call_state_wipe (cs); @@ -1784,7 +1934,7 @@ nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, return -1; } - nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "READ", fh, offset, + nfs3_log_rw_call (rpcsvc_request_xid (req), "READ", fh, offset, count, -1); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -1800,7 +1950,7 @@ nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "READ", stat, + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_READ, stat, -ret); nfs3_read_reply (req, stat, 0, NULL,0, NULL, NULL, 0); nfs3_call_state_wipe (cs); @@ -1822,16 +1972,16 @@ nfs3svc_read (rpcsvc_request_t *req) return ret; nfs3_prep_read3args (&args, &fh); - if (xdr_to_read3args (req->msg, &args) <= 0) { + if (xdr_to_read3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_read (req, &fh, args.offset, args.count); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READ procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1860,21 +2010,24 @@ nfs3_write_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count, int32_t nfs3svc_write_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) + struct iatt *postbuf, dict_t *xdata) { struct nfs3_state *nfs3 = NULL; nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); - if (op_ret == -1) - stat = nfs3_errno_to_nfsstat3 (op_errno); - else + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); + } else stat = NFS3_OK; - nfs3_log_write_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3_log_write_res (rpcsvc_request_xid (cs->req), stat, op_errno, cs->maxcount, cs->writetype, nfs3->serverstart); nfs3_write_reply (cs->req, stat, cs->maxcount, cs->writetype, nfs3->serverstart, &cs->stbuf, postbuf); @@ -1883,41 +2036,6 @@ nfs3svc_write_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } -/* - * If this logic determines that the write should return a reply to the client - * after this function, the return value is -1 and the writetype is reset to - * the type of write we want to signify to the client. - * - * In case the write should continue to serve the request according to the type - * of stable write, a 0 is returned and writetype is left as it is. - */ -int -nfs3_write_how (int *writetype, int write_trusted, int sync_trusted) -{ - int ret = -1; - - if (*writetype == UNSTABLE) { - /* On an UNSTABLE write, only return STABLE when trusted-write - * is set. TW is also set when trusted-sync is set. - */ - if (write_trusted) - *writetype = FILE_SYNC; - - goto err; - } else if ((*writetype == DATA_SYNC) || (*writetype == FILE_SYNC)) { - - /* On a STABLE write, if sync-trusted is on, only then, return - * without syncing. - */ - if (sync_trusted) - goto err; - } - - ret = 0; -err: - return ret; -} - /* * Before going into the write reply logic, here is a matrix that shows the @@ -1953,55 +2071,33 @@ err: int32_t nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) + struct iatt *postbuf, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; - int ret = -EFAULT; - nfs_user_t nfu = {0, }; nfs3_call_state_t *cs = NULL; struct nfs3_state *nfs3 = NULL; - int write_trusted = 0; - int sync_trusted = 0; cs = frame->local; - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto err; } stat = NFS3_OK; cs->maxcount = op_ret; - write_trusted = nfs3_export_write_trusted (cs->nfs3state, - cs->resolvefh.exportid); - sync_trusted = nfs3_export_sync_trusted (cs->nfs3state, - cs->resolvefh.exportid); - ret = nfs3_write_how (&cs->writetype, write_trusted, sync_trusted); - if (ret == -1) - goto err; - - nfs_request_user_init (&nfu, cs->req); - /* Store the current preattr so that this can be used as the pre attr - * when fsync returns. We dont want to use the preattr in fsync because - * the write fop happened before the fsync. - */ - cs->stbuf = *prebuf; - ret = nfs_fsync (cs->nfsx, cs->vol, &nfu, cs->fd, 0, - nfs3svc_write_fsync_cbk, cs); - if (ret < 0) - stat = nfs3_errno_to_nfsstat3 (-ret); - err: - if (ret < 0) { - nfs3_log_write_res (nfs_rpcsvc_request_xid (cs->req), stat, - op_errno, cs->maxcount, cs->writetype, - nfs3->serverstart); - nfs3_write_reply (cs->req, stat, cs->maxcount, - cs->writetype, nfs3->serverstart, prebuf, - postbuf); - nfs3_call_state_wipe (cs); - } + nfs3_log_write_res (rpcsvc_request_xid (cs->req), stat, + op_errno, cs->maxcount, cs->writetype, + nfs3->serverstart); + nfs3_write_reply (cs->req, stat, cs->maxcount, + cs->writetype, nfs3->serverstart, prebuf, + postbuf); + nfs3_call_state_wipe (cs); return 0; } @@ -2029,8 +2125,9 @@ __nfs3_write_resume (nfs3_call_state_t *cs) * opaque data buffers to multiples of 4 bytes. */ cs->datavec.iov_len = cs->datacount; - ret = nfs_write (cs->nfsx, cs->vol, &nfu, cs->fd, cs->iob, &cs->datavec, - 1, cs->dataoffset, nfs3svc_write_cbk, cs); + ret = nfs_write (cs->nfsx, cs->vol, &nfu, cs->fd, cs->iobref, + &cs->datavec, 1, cs->dataoffset, nfs3svc_write_cbk, + cs); return ret; } @@ -2042,46 +2139,45 @@ nfs3_write_resume (void *carg) nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -EFAULT; nfs3_call_state_t *cs = NULL; + fd_t *fd = NULL; if (!carg) return ret; cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); - - ret = __nfs3_write_resume (cs); - if (ret < 0) - stat = nfs3_errno_to_nfsstat3 (-ret); -nfs3err: - if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "WRITE", - stat, -ret); - nfs3_write_reply (cs->req, stat, 0, cs->writetype, 0, NULL, - NULL); - nfs3_call_state_wipe (cs); + fd = fd_anonymous (cs->resolvedloc.inode); + if (!fd) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to create anonymous fd"); + goto nfs3err; } - return ret; -} + cs->fd = fd; /* Gets unrefd when the call state is wiped. */ -int -nfs3_write_open_resume (void *carg) -{ - nfsstat3 stat = NFS3ERR_SERVERFAULT; - int ret = -EFAULT; - nfs3_call_state_t *cs = NULL; - - if (!carg) - return ret; +/* + enum stable_how { + UNSTABLE = 0, + DATA_SYNC = 1, + FILE_SYNC = 2, + }; +*/ + switch (cs->writetype) { + case UNSTABLE: + break; + case DATA_SYNC: + fd->flags |= O_DSYNC; + break; + case FILE_SYNC: + fd->flags |= O_SYNC; + break; + } - cs = (nfs3_call_state_t *)carg; - nfs3_check_fh_resolve_status (cs, stat, nfs3err); - ret = nfs3_file_open_and_resume (cs, nfs3_write_resume); + ret = __nfs3_write_resume (cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "WRITE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_WRITE, stat, -ret); nfs3_write_reply (cs->req, stat, 0, cs->writetype, 0, NULL, NULL); @@ -2091,11 +2187,10 @@ nfs3err: } - int nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, count3 count, stable_how stable, struct iovec payload, - struct iobuf *iob) + struct iobref *iobref) { xlator_t *vol = NULL; nfsstat3 stat = NFS3ERR_SERVERFAULT; @@ -2108,7 +2203,7 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, return -1; } - nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "WRITE", fh, offset, + nfs3_log_rw_call (rpcsvc_request_xid (req), "WRITE", fh, offset, count, stable); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -2119,17 +2214,17 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, cs->datacount = count; cs->dataoffset = offset; cs->writetype = stable; - cs->iob = iob; + cs->iobref = iobref; cs->datavec = payload; - ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_write_open_resume); + ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_write_resume); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "WRITE", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_WRITE, stat, -ret); nfs3_write_reply (req, stat, 0, stable, 0, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2147,99 +2242,47 @@ out: int -nfs3svc_write_vecsizer (rpcsvc_request_t *req, ssize_t *readsize, int *newbuf) +nfs3svc_write_vecsizer (int state, ssize_t *readsize, char *base_addr, + char *curr_addr) { - ssize_t ret = RPCSVC_ACTOR_ERROR; - int state = 0; - uint32_t fhlen = 0; - uint32_t fhlen_n = 0; - write3args *args = NULL; - - if (!req) - return ret; + int ret = 0; + uint32_t fhlen = 0; + uint32_t fhlen_n = 0; - state = (long)nfs_rpcsvc_request_private (req); - *newbuf = 0; if (state == 0) { - nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READFHLEN); + ret = NFS3_VECWRITE_READFHLEN; *readsize = 4; - ret = 0; } else if (state == NFS3_VECWRITE_READFHLEN) { - fhlen_n = *(uint32_t *)req->msg.iov_base; + fhlen_n = *(uint32_t *)(curr_addr - 4); fhlen = ntohl (fhlen_n); - *readsize = nfs_xdr_length_round_up (fhlen, NFS3_FHSIZE); - nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READFH); - ret = 0; + *readsize = xdr_length_round_up (fhlen, NFS3_FHSIZE); + ret = NFS3_VECWRITE_READFH; } else if (state == NFS3_VECWRITE_READFH) { *readsize = NFS3_WRITE_POSTFH_SIZE; - nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READREST); - ret = 0; + ret = NFS3_VECWRITE_READREST; } else if (state == NFS3_VECWRITE_READREST) { - args = GF_CALLOC (1, sizeof (*args), gf_nfs_mt_write3args); - if (!args) - goto rpcerr; - - if (xdr_to_write3args_nocopy (req->msg, args, NULL) <= 0) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); - goto rpcerr; - } - nfs_rpcsvc_request_set_private (req, args); - ret = nfs_xdr_length_round_up (args->data.data_len, 1048576); - *readsize = ret; - *newbuf = 1; ret = 0; - } - -rpcerr: - return ret; -} - - -int -nfs3svc_write_vec (rpcsvc_request_t *req, struct iobuf *iob) -{ - write3args *args = NULL; - int ret = RPCSVC_ACTOR_ERROR; - struct iovec payload = {0, }; - struct nfs3_fh fh = {{0}, }; - - if ((!req) || (!iob)) - return ret; - - args = nfs_rpcsvc_request_private (req); - iobuf_to_iovec (iob, &payload); - iobuf_ref (iob); - memcpy (&fh, args->file.data.data_val, args->file.data.data_len); - ret = nfs3_write (req, &fh, args->offset, args->count, args->stable, - payload,iob); - xdr_free_write3args_nocopy (args); - GF_FREE (args); - if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { - gf_log (GF_NFS3, GF_LOG_ERROR, "WRITE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); - ret = RPCSVC_ACTOR_ERROR; - } + *readsize = 0; + } else + gf_log ("nfs", GF_LOG_ERROR, "state wrong"); return ret; } - int nfs3svc_write (rpcsvc_request_t *req) { struct nfs3_fh fh = {{0}, }; write3args args; int ret = RPCSVC_ACTOR_ERROR; - struct iovec payload = {0, }; if (!req) return ret; nfs3_prep_write3args (&args, &fh); - if (xdr_to_write3args_nocopy (req->msg, &args, &payload) <= 0) { + if (xdr_to_write3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } @@ -2248,12 +2291,12 @@ nfs3svc_write (rpcsvc_request_t *req) * ourselves because the RPC call handler who called us will unref its * own ref of the record's iobuf when it is done handling the request. */ - nfs_rpcsvc_request_record_ref (req); + ret = nfs3_write (req, &fh, args.offset, args.count, args.stable, - payload, nfs_rpcsvc_request_record_iob (req)); + req->msg[1], rpcsvc_request_iobref_ref (req)); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "WRITE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2282,20 +2325,23 @@ nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh, int32_t nfs3svc_create_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *preop, struct iatt *postop) + struct iatt *preop, struct iatt *postop, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_CREATE, stat, op_errno, &cs->fh); nfs3_create_reply (cs->req, stat, &cs->fh, postop, &cs->preparent, &cs->postparent); @@ -2309,20 +2355,26 @@ int32_t nfs3svc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -EFAULT; nfs_user_t nfu = {0, }; nfs3_call_state_t *cs = NULL; + inode_t *oldinode = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh); + oldinode = inode_link (inode, cs->resolvedloc.parent, + cs->resolvedloc.name, buf); /* Means no attributes were required to be set. */ if (!cs->setattr_valid) { @@ -2334,14 +2386,20 @@ nfs3svc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs->preparent = *preparent; cs->postparent = *postparent; nfs_request_user_init (&nfu, cs->req); + uuid_copy (cs->resolvedloc.gfid, inode->gfid); ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,&cs->stbuf, cs->setattr_valid, nfs3svc_create_setattr_cbk, cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: + if (oldinode) { + inode_lookup (oldinode); + inode_unref (oldinode); + } + if (ret < 0) { - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_CREATE, stat, op_errno, &cs->fh); nfs3_create_reply (cs->req, stat, &cs->fh, buf, preparent, postparent); @@ -2357,16 +2415,30 @@ nfs3_create_common (nfs3_call_state_t *cs) int ret = -EFAULT; int flags = 0; nfs_user_t nfu = {0, }; + uid_t uid = 0; + gid_t gid = 0; if (!cs) return ret; - if (cs->createmode == UNCHECKED) - flags = O_RDWR; - else if (cs->createmode == GUARDED) + if (cs->createmode == GUARDED) flags = (O_RDWR | O_EXCL); + else + flags = O_RDWR; - nfs_request_user_init (&nfu, cs->req); + if (gf_attr_uid_set (cs->setattr_valid)) { + uid = cs->stbuf.ia_uid; + cs->setattr_valid &= ~GF_SET_ATTR_UID; + } else + uid = rpcsvc_request_uid (cs->req); + + if (gf_attr_gid_set (cs->setattr_valid)) { + gid = cs->stbuf.ia_gid; + cs->setattr_valid &= ~GF_SET_ATTR_GID; + } else + gid = rpcsvc_request_gid (cs->req); + + nfs_request_primary_user_init (&nfu, cs->req, uid, gid); /* We can avoid sending the setattr call later if only the mode is * required to be set. This is possible because the create fop allows * us to specify a mode arg. @@ -2386,7 +2458,8 @@ nfs3_create_common (nfs3_call_state_t *cs) int32_t nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { int ret = -EFAULT; nfsstat3 stat = NFS3ERR_SERVERFAULT; @@ -2396,27 +2469,33 @@ nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; nfs_request_user_init (&nfu, cs->req); if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); ret = -op_errno; - stat = nfs3_errno_to_nfsstat3 (op_errno); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } if ((cs->stbuf.ia_mtime == buf->ia_mtime) && (cs->stbuf.ia_atime == buf->ia_atime)) { - gf_log (GF_NFS3, GF_LOG_DEBUG, "Create req retransmitted verf %x %x", + gf_log (GF_NFS3, GF_LOG_DEBUG, + "Create req retransmitted verf %x %x", cs->stbuf.ia_mtime, cs->stbuf.ia_atime); stat = NFS3_OK; nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh); } else { - gf_log (GF_NFS3, GF_LOG_DEBUG, "File already exist new_verf %x %x" - "old_verf %x %x", cs->stbuf.ia_mtime, cs->stbuf.ia_atime, + gf_log (GF_NFS3, GF_LOG_DEBUG, + "File already exist new_verf %x %x" + "old_verf %x %x", cs->stbuf.ia_mtime, + cs->stbuf.ia_atime, buf->ia_mtime, buf->ia_atime); stat = NFS3ERR_EXIST; } nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_CREATE, stat, op_errno); nfs3_create_reply (cs->req, stat, &cs->fh, buf, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2437,8 +2516,11 @@ nfs3_create_exclusive (nfs3_call_state_t *cs) /* Storing verifier as a mtime and atime attribute, to store it * in stable storage */ - cs->stbuf.ia_atime = (cs->cookieverf & 0xFFFFFFFF00000000); - cs->stbuf.ia_mtime = (cs->cookieverf & 0x00000000FFFFFFFF); + memcpy (&cs->stbuf.ia_atime, &cs->cookieverf, + sizeof (cs->stbuf.ia_atime)); + memcpy (&cs->stbuf.ia_mtime, + ((char *) &cs->cookieverf) + sizeof (cs->stbuf.ia_atime), + sizeof (cs->stbuf.ia_mtime)); cs->setattr_valid |= GF_SET_ATTR_ATIME; cs->setattr_valid |= GF_SET_ATTR_MTIME; nfs_request_user_init (&nfu, cs->req); @@ -2454,15 +2536,7 @@ nfs3_create_exclusive (nfs3_call_state_t *cs) goto nfs3err; } - if (cs->setattr_valid & GF_SET_ATTR_MODE) { - cs->setattr_valid &= ~GF_SET_ATTR_MODE; - ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - O_RDWR, cs->mode, nfs3svc_create_cbk, cs); - } else - ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->oploc, O_RDWR, - NFS_DEFAULT_CREATE_MODE, nfs3svc_create_cbk, - cs); - + ret = nfs3_create_common (cs); nfs3err: return ret; } @@ -2491,7 +2565,7 @@ nfs3_create_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_CREATE, stat, -ret); nfs3_create_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2513,7 +2587,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, if ((!req) || (!dirfh) || (!name) || (!sattr)) return -1; - nfs3_log_create_call (nfs_rpcsvc_request_xid (req), dirfh, name, mode); + nfs3_log_create_call (rpcsvc_request_xid (req), dirfh, name, mode); nfs3_validate_gluster_fh (dirfh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); @@ -2523,8 +2597,12 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->cookieverf = cverf; - cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, - &cs->mode); + /*In Exclusive create client is supposed to send cverf instead of + * sattr*/ + if (mode != EXCLUSIVE) + cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, + &cs->stbuf, + &cs->mode); cs->createmode = mode; cs->parent = *dirfh; @@ -2534,7 +2612,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "CREATE", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_CREATE, stat, -ret); nfs3_create_reply (req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2548,28 +2626,31 @@ out: int nfs3svc_create (rpcsvc_request_t *req) { - char name[NFS_PATH_MAX]; - struct nfs3_fh dirfh = {{0}, }; - create3args args; - int ret = RPCSVC_ACTOR_ERROR; - uint64_t cverf = 0; + char name[NFS_PATH_MAX]; + struct nfs3_fh dirfh = {{0}, }; + create3args args; + int ret = RPCSVC_ACTOR_ERROR; + uint64_t cverf = 0; + uint64_t *cval; if (!req) return ret; nfs3_prep_create3args (&args, &dirfh, name); - if (xdr_to_create3args (req->msg, &args) <= 0) { + if (xdr_to_create3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } - cverf = *(uint64_t *)args.how.createhow3_u.verf; + cval = (uint64_t *)args.how.createhow3_u.verf; + cverf = *cval; + ret = nfs3_create (req, &dirfh, name, args.how.mode, &args.how.createhow3_u.obj_attributes, cverf); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "CREATE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2597,20 +2678,23 @@ nfs3_mkdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh, int32_t nfs3svc_mkdir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *preop, struct iatt *postop) + struct iatt *preop, struct iatt *postop, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR, stat, op_errno, &cs->fh); nfs3_mkdir_reply (cs->req, stat, &cs->fh, postop, &cs->preparent, &cs->postparent); @@ -2624,7 +2708,7 @@ int32_t nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -EFAULT; @@ -2633,7 +2717,10 @@ nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } @@ -2655,7 +2742,7 @@ nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3err: if (ret < 0) { - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR", + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR, stat, op_errno, &cs->fh); nfs3_mkdir_reply (cs->req, stat, &cs->fh, buf, preparent, postparent); @@ -2694,7 +2781,7 @@ nfs3_mkdir_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR, stat, -ret); nfs3_mkdir_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2720,7 +2807,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, return -1; } - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "MKDIR", dirfh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "MKDIR", dirfh, name); nfs3_validate_gluster_fh (dirfh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -2739,7 +2826,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "MKDIR", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_MKDIR, stat, -ret); nfs3_mkdir_reply (req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2761,16 +2848,16 @@ nfs3svc_mkdir (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_mkdir3args (&args, &dirfh, name); - if (xdr_to_mkdir3args (req->msg, &args) <= 0) { + if (xdr_to_mkdir3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_mkdir (req, &dirfh, name, &args.attributes); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "MKDIR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2801,14 +2888,17 @@ int32_t nfs3svc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } @@ -2816,7 +2906,7 @@ nfs3svc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "SYMLINK", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_SYMLINK, stat, op_errno, &cs->fh); nfs3_symlink_reply (cs->req, stat, &cs->fh, buf, preparent, postparent); @@ -2846,8 +2936,8 @@ nfs3_symlink_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "SYMLINK", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_SYMLINK, stat, -ret); nfs3_symlink_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); } @@ -2871,7 +2961,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, return -1; } - nfs3_log_symlink_call (nfs_rpcsvc_request_xid (req), dirfh, name, + nfs3_log_symlink_call (rpcsvc_request_xid (req), dirfh, name, target); nfs3_validate_gluster_fh (dirfh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -2895,7 +2985,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "SYMLINK", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_SYMLINK, stat, -ret); nfs3_symlink_reply (req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2921,9 +3011,9 @@ nfs3svc_symlink (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_symlink3args (&args, &dirfh, name, target); - if (xdr_to_symlink3args (req->msg, &args) <= 0) { + if (xdr_to_symlink3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } @@ -2931,7 +3021,7 @@ nfs3svc_symlink (rpcsvc_request_t *req) &args.symlink.symlink_attributes); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "SYMLINK procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2960,20 +3050,23 @@ nfs3_mknod_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh, int32_t nfs3svc_mknod_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *preop, struct iatt *postop) + struct iatt *preop, struct iatt *postop, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD, stat, op_errno, &cs->fh); nfs3_mknod_reply (cs->req, stat, &cs->fh, postop, &cs->preparent, &cs->postparent); @@ -2987,7 +3080,7 @@ int32_t nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -1; @@ -2996,7 +3089,10 @@ nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } @@ -3018,7 +3114,7 @@ nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD", + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD, stat, op_errno, &cs->fh); nfs3_mknod_reply (cs->req, stat, &cs->fh, buf, preparent, @@ -3117,7 +3213,7 @@ nfs3_mknod_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD, stat, -ret); nfs3_mknod_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3144,7 +3240,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name, return -1; } - nfs3_log_mknod_call (nfs_rpcsvc_request_xid (req), fh, name, + nfs3_log_mknod_call (rpcsvc_request_xid (req), fh, name, nodedata->type); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -3160,13 +3256,15 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name, case NF3BLK: cs->devnums = nodedata->mknoddata3_u.device.spec; sattr = &nodedata->mknoddata3_u.device.dev_attributes; - cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, + cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, + &cs->stbuf, &cs->mode); break; case NF3SOCK: case NF3FIFO: sattr = &nodedata->mknoddata3_u.pipe_attributes; - cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, + cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, + &cs->stbuf, &cs->mode); break; default: @@ -3181,7 +3279,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "MKNOD", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_MKNOD, stat, -ret); nfs3_mknod_reply (req, stat, NULL, NULL, NULL, NULL); /* Ret must be 0 after this so that the caller does not @@ -3206,16 +3304,16 @@ nfs3svc_mknod (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_mknod3args (&args, &fh, name); - if (xdr_to_mknod3args (req->msg, &args) <= 0) { + if (xdr_to_mknod3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_mknod (req, &fh, name, &args.what); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "MKNOD procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3242,31 +3340,23 @@ nfs3_remove_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent int32_t nfs3svc_remove_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; - fd_t *openfd = NULL; nfs3_call_state_t *cs = NULL; - struct nfs3_state *nfs3 = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); - goto do_not_unref_cached_fd; + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); } - stat = NFS3_OK; - /* Close any cached fds so that when any currently active write - * finishes, the file is finally removed. - */ - openfd = fd_lookup (cs->resolvedloc.inode, 0); - nfs3 = nfs_rpcsvc_request_program_private (cs->req); - if (openfd) { - fd_unref (openfd); - nfs3_fdcache_remove (nfs3, openfd); - } - -do_not_unref_cached_fd: - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "REMOVE", stat, + + if (op_ret == 0) + stat = NFS3_OK; + + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_REMOVE, stat, op_errno); nfs3_remove_reply (cs->req, stat, preparent, postparent); nfs3_call_state_wipe (cs); @@ -3315,7 +3405,7 @@ nfs3_remove_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "REMOVE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_REMOVE, stat, -ret); nfs3_remove_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3339,7 +3429,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) return -1; } - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "REMOVE", fh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "REMOVE", fh, name); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -3355,7 +3445,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "REMOVE", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_REMOVE, stat, -ret); nfs3_remove_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3380,16 +3470,16 @@ nfs3svc_remove (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_remove3args (&args, &fh, name); - if (xdr_to_remove3args (req->msg, &args) <= 0) { + if (xdr_to_remove3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_remove (req, &fh, name); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "REMOVE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3416,19 +3506,22 @@ nfs3_rmdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent, int32_t nfs3svc_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; - if (op_ret == -1) - stat = nfs3_errno_to_nfsstat3 (op_errno); - else { + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); + } else { stat = NFS3_OK; } - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RMDIR", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RMDIR, stat, op_errno); nfs3_rmdir_reply (cs->req, stat, preparent, postparent); nfs3_call_state_wipe (cs); @@ -3457,7 +3550,7 @@ nfs3_rmdir_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RMDIR", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RMDIR, stat, -ret); nfs3_rmdir_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3482,7 +3575,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) return -1; } - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "RMDIR", fh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "RMDIR", fh, name); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -3498,7 +3591,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "RMDIR", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_RMDIR, stat, -ret); nfs3_rmdir_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3523,16 +3616,16 @@ nfs3svc_rmdir (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_rmdir3args (&args, &fh, name); - if (xdr_to_rmdir3args (req->msg, &args) <= 0) { + if (xdr_to_rmdir3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_rmdir (req, &fh, name); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "RMDIR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3565,34 +3658,26 @@ int32_t nfs3svc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, - struct iatt *prenewparent, struct iatt *postnewparent) + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t *xdata) { int ret = -EFAULT; nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; - fd_t *openfd = NULL; cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: rename %s -> %s => -1 (%s)", + rpcsvc_request_xid (cs->req), cs->oploc.path, + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } stat = NFS3_OK; - /* Close any cached fds so that when any currently active writes to the - * dst finish, the file is finally removed. - * - * This logic works because we know resolvedloc contains dst, which is - * resolved after src - */ - openfd = fd_lookup (cs->resolvedloc.inode, 0); - if (openfd) { - fd_unref (openfd); - nfs3_fdcache_remove (cs->nfs3state, openfd); - } - nfs3err: - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME, stat, -ret); nfs3_rename_reply (cs->req, stat, buf, preoldparent, postoldparent, prenewparent, postnewparent); @@ -3623,7 +3708,7 @@ nfs3_rename_resume_dst (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME, stat, -ret); nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3651,6 +3736,7 @@ nfs3_rename_resume_src (void *carg) */ nfs_loc_copy (&cs->oploc, &cs->resolvedloc); nfs_loc_wipe (&cs->resolvedloc); + GF_FREE (cs->resolventry); ret = nfs3_fh_resolve_and_resume (cs, &cs->fh, cs->pathname, nfs3_rename_resume_dst); @@ -3659,7 +3745,7 @@ nfs3_rename_resume_src (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME, stat, -ret); nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3684,7 +3770,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname, return -1; } - nfs3_log_rename_call (nfs_rpcsvc_request_xid (req), olddirfh, oldname, + nfs3_log_rename_call (rpcsvc_request_xid (req), olddirfh, oldname, newdirfh, newname); nfs3_validate_gluster_fh (olddirfh, stat, nfs3err); nfs3_validate_gluster_fh (newdirfh, stat, nfs3err); @@ -3714,7 +3800,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "RENAME", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_RENAME, stat, -ret); nfs3_rename_reply (req, stat, NULL, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3741,16 +3827,16 @@ nfs3svc_rename (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_rename3args (&args, &olddirfh, oldname, &newdirfh, newname); - if (xdr_to_rename3args (req->msg, &args) <= 0) { + if (xdr_to_rename3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_rename (req, &olddirfh, oldname, &newdirfh, newname); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "RENAME procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3779,18 +3865,22 @@ int32_t nfs3svc_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; - if (op_ret == -1) - stat = nfs3_errno_to_nfsstat3 (op_errno); - else + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: link %s <- %s => -1 (%s)", + rpcsvc_request_xid (cs->req), cs->oploc.path, + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); + } else stat = NFS3_OK; - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK, stat, op_errno); nfs3_link_reply (cs->req, stat, buf, preparent, postparent); nfs3_call_state_wipe (cs); @@ -3821,7 +3911,7 @@ nfs3_link_resume_lnk (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK, stat, -ret); nfs3_link_reply (cs->req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3852,7 +3942,7 @@ nfs3_link_resume_tgt (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK, stat, -ret); nfs3_link_reply (cs->req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3901,7 +3991,7 @@ nfs3_link (rpcsvc_request_t *req, struct nfs3_fh *targetfh, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "LINK", stat, + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_LINK, stat, -ret); nfs3_link_reply (req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3926,16 +4016,16 @@ nfs3svc_link (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_link3args (&args, &targetfh, &dirfh, newpath); - if (xdr_to_link3args (req->msg, &args) <= 0) { + if (xdr_to_link3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_link (req, &targetfh, &dirfh, newpath); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "LINK procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3984,7 +4074,8 @@ nfs3_readdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *dirfh, int32_t nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int is_eof = 0; @@ -3992,7 +4083,10 @@ nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto nfs3err; } @@ -4007,14 +4101,14 @@ nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: if (cs->maxcount == 0) { - nfs3_log_readdir_res (nfs_rpcsvc_request_xid (cs->req), stat, + nfs3_log_readdir_res (rpcsvc_request_xid (cs->req), stat, op_errno, (uintptr_t)cs->fd, cs->dircount, is_eof); nfs3_readdir_reply (cs->req, stat, &cs->parent, (uintptr_t)cs->fd, buf, &cs->entries, cs->dircount, is_eof); } else { - nfs3_log_readdirp_res (nfs_rpcsvc_request_xid (cs->req), stat, + nfs3_log_readdirp_res (rpcsvc_request_xid (cs->req), stat, op_errno, (uintptr_t)cs->fd, cs->dircount, cs->maxcount, is_eof); nfs3_readdirp_reply (cs->req, stat, &cs->parent, @@ -4034,7 +4128,8 @@ nfs3err: int32_t nfs3svc_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *entries) + int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, + dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -EFAULT; @@ -4043,7 +4138,10 @@ nfs3svc_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { - stat = nfs3_errno_to_nfsstat3 (op_errno); + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto err; } @@ -4063,12 +4161,12 @@ err: goto ret; if (cs->maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "READDIR", stat, op_errno); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_READDIR, stat, op_errno); nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "READDIRP", stat, op_errno); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_READDIRP, stat, op_errno); nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0, 0); } @@ -4111,7 +4209,7 @@ nfs3_readdir_read_resume (void *carg) cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); ret = nfs3_verify_dircookie (nfs3, cs->fd, cs->cookie, cs->cookieverf, &stat); if (ret < 0) /* Stat already set by verifier function above. */ @@ -4123,13 +4221,13 @@ nfs3_readdir_read_resume (void *carg) nfs3err: if (ret < 0) { if (cs->maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "READDIR", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_READDIR, stat, -ret); nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "READDIRP", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_READDIRP, stat, -ret); nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0, 0); } @@ -4140,32 +4238,72 @@ nfs3err: } +int32_t +nfs3svc_readdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, + dict_t *xdata) +{ + /* + * We don't really need this, it's just an artifact of forcing the + * opendir to happen. + */ + if (fd) { + fd_unref(fd); + } + + return 0; +} + + int nfs3_readdir_open_resume (void *carg) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -EFAULT; nfs3_call_state_t *cs = NULL; + nfs_user_t nfu = {0, }; if (!carg) return ret; cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); - ret = nfs3_dir_open_and_resume (cs, nfs3_readdir_read_resume); + cs->fd = fd_anonymous (cs->resolvedloc.inode); + if (!cs->fd) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Faile to create anonymous fd"); + goto nfs3err; + } + + /* + * NFS client will usually send us a readdirp without an opendir, + * which would cause us to skip our usual self-heal checks which occur + * in opendir for native protocol. To make sure those checks do happen, + * our most reliable option is to do our own opendir for any readdirp + * at the beginning of the directory. + */ + if (cs->cookie == 0) { + nfs_request_user_init (&nfu, cs->req); + ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + nfs3svc_readdir_opendir_cbk, cs); + if (ret < 0) { + gf_log (GF_NFS3, GF_LOG_ERROR, "auto-opendir failed"); + } + } + + ret = nfs3_readdir_read_resume (cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { if (cs->maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "READDIR", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_READDIR, stat, -ret); nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "READDIRP", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_READDIRP, stat, -ret); nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0, 0); } @@ -4192,7 +4330,7 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie, return -1; } - nfs3_log_readdir_call (nfs_rpcsvc_request_xid (req), fh, dircount, + nfs3_log_readdir_call (rpcsvc_request_xid (req), fh, dircount, maxcount); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -4213,13 +4351,13 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie, nfs3err: if (ret < 0) { if (maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), - "READDIR", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (req), + NFS3_READDIR, stat, -ret); nfs3_readdir_reply (req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), - "READDIRP", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (req), + NFS3_READDIRP, stat, -ret); nfs3_readdirp_reply (req, stat, NULL, 0, NULL, NULL, 0, 0, 0); } @@ -4241,21 +4379,23 @@ nfs3svc_readdir (rpcsvc_request_t *req) struct nfs3_fh fh = {{0},}; int ret = RPCSVC_ACTOR_ERROR; uint64_t verf = 0; + uint64_t *cval; if (!req) return ret; nfs3_prep_readdir3args (&ra, &fh); - if (xdr_to_readdir3args (req->msg, &ra) <= 0) { + if (xdr_to_readdir3args (req->msg[0], &ra) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } + cval = (uint64_t *) ra.cookieverf; + verf = *cval; - verf = *(uint64_t *)ra.cookieverf; ret = nfs3_readdir (req, &fh, ra.cookie, verf, ra.count, 0); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READDIR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4271,22 +4411,24 @@ nfs3svc_readdirp (rpcsvc_request_t *req) struct nfs3_fh fh = {{0},}; int ret = RPCSVC_ACTOR_ERROR; uint64_t cverf = 0; + uint64_t *cval; if (!req) return ret; nfs3_prep_readdirp3args (&ra, &fh); - if (xdr_to_readdirp3args (req->msg, &ra) <= 0) { + if (xdr_to_readdirp3args (req->msg[0], &ra) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } + cval = (uint64_t *) ra.cookieverf; + cverf = *cval; - cverf = *(uint64_t *)ra.cookieverf; ret = nfs3_readdir (req, &fh, ra.cookie, cverf, ra.dircount, ra.maxcount); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READDIRP procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4312,18 +4454,22 @@ nfs3_fsstat_reply (rpcsvc_request_t *req, nfsstat3 stat, struct statvfs *fsbuf, int32_t nfs3_fsstat_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; - if (op_ret == -1) - stat = nfs3_errno_to_nfsstat3 (op_errno); - else + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); + } else stat = NFS3_OK; - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT, stat, op_errno); nfs3_fsstat_reply (cs->req, stat, &cs->fsstat, buf); nfs3_call_state_wipe (cs); @@ -4333,7 +4479,8 @@ nfs3_fsstat_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct statvfs *buf) + int32_t op_ret, int32_t op_errno, struct statvfs *buf, + dict_t *xdata) { nfs_user_t nfu = {0, }; int ret = -EFAULT; @@ -4342,8 +4489,11 @@ nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs = frame->local; if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); ret = -op_errno; - stat = nfs3_errno_to_nfsstat3 (op_errno); + stat = nfs3_cbk_errno_status (op_ret, op_errno); goto err; } @@ -4359,7 +4509,7 @@ nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT, stat, -ret); nfs3_fsstat_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4391,7 +4541,7 @@ nfs3_fsstat_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT, stat, -ret); nfs3_fsstat_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4416,7 +4566,7 @@ nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "FSSTAT", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "FSSTAT", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -4429,7 +4579,7 @@ nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "FSTAT", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_FSSTAT, stat, -ret); nfs3_fsstat_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4453,16 +4603,16 @@ nfs3svc_fsstat (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_fsstat3args (&args, &fh); - if (xdr_to_fsstat3args (req->msg, &args) <= 0) { + if (xdr_to_fsstat3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_fsstat (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "FSTAT procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4479,7 +4629,7 @@ nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot) uint64_t deviceid = 0; deviceid = nfs3_request_xlator_deviceid (req); - nfs3 = nfs_rpcsvc_request_program_private (req); + nfs3 = rpcsvc_request_program_private (req); nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, deviceid); nfs3svc_submit_reply (req, &res, @@ -4490,19 +4640,23 @@ nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot) int32_t nfs3svc_fsinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { nfsstat3 status = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; cs = frame->local; - if (op_ret == -1) - status = nfs3_errno_to_nfsstat3 (op_errno); - else + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + status = nfs3_cbk_errno_status (op_ret, op_errno); + }else status = NFS3_OK; - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSINFO", status, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSINFO, status, op_errno); nfs3_fsinfo_reply (cs->req, status, buf); @@ -4535,7 +4689,7 @@ nfs3_fsinfo_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSINFO", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSINFO, stat, -ret); nfs3_fsinfo_reply (cs->req, stat, NULL); nfs3_call_state_wipe (cs); @@ -4559,7 +4713,7 @@ nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "FSINFO", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "FSINFO", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -4572,7 +4726,7 @@ nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "FSINFO", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_FSINFO, stat, -ret); nfs3_fsinfo_reply (req, stat, NULL); nfs3_call_state_wipe (cs); @@ -4594,16 +4748,16 @@ nfs3svc_fsinfo (rpcsvc_request_t *req) return ret; nfs3_prep_fsinfo3args (&args, &root); - if (xdr_to_fsinfo3args (req->msg, &args) <= 0) { + if (xdr_to_fsinfo3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding arguments"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_fsinfo (req, &root); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "FSINFO procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4628,16 +4782,20 @@ nfs3_pathconf_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf) int32_t nfs3svc_pathconf_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { struct iatt *sbuf = NULL; nfs3_call_state_t *cs = NULL; nfsstat3 stat = NFS3ERR_SERVERFAULT; cs = frame->local; - if (op_ret == -1) - stat = nfs3_errno_to_nfsstat3 (op_errno); - else { + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); + } else { /* If stat fop failed, we can still send the other components * in a pathconf reply. */ @@ -4645,7 +4803,7 @@ nfs3svc_pathconf_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; } - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "PATHCONF", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_PATHCONF, stat, op_errno); nfs3_pathconf_reply (cs->req, stat, sbuf); nfs3_call_state_wipe (cs); @@ -4674,8 +4832,8 @@ nfs3_pathconf_resume (void *carg) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), - "PATHCONF", stat, -ret); + nfs3_log_common_res (rpcsvc_request_xid (cs->req), + NFS3_PATHCONF, stat, -ret); nfs3_pathconf_reply (cs->req, stat, NULL); nfs3_call_state_wipe (cs); } @@ -4697,7 +4855,7 @@ nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "PATHCONF", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "PATHCONF", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -4710,7 +4868,7 @@ nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "PATHCONF", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_PATHCONF, stat, -ret); nfs3_pathconf_reply (req, stat, NULL); nfs3_call_state_wipe (cs); @@ -4734,16 +4892,16 @@ nfs3svc_pathconf (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_pathconf3args (&args, &fh); - if (xdr_to_pathconf3args (req->msg, &args) <= 0) { + if (xdr_to_pathconf3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_pathconf (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "PATHCONF procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4769,23 +4927,25 @@ nfs3_commit_reply (rpcsvc_request_t *req, nfsstat3 stat, uint64_t wverf, int32_t nfs3svc_commit_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *prebuf, - struct iatt *postbuf) + int32_t op_ret, int32_t op_errno, dict_t *xdata) { nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; struct nfs3_state *nfs3 = NULL; cs = frame->local; - if (op_ret == -1) - stat = nfs3_errno_to_nfsstat3 (op_errno); - else + if (op_ret == -1) { + gf_log (GF_NFS, GF_LOG_WARNING, + "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req), + cs->resolvedloc.path, strerror (op_errno)); + stat = nfs3_cbk_errno_status (op_ret, op_errno); + } else stat = NFS3_OK; - nfs3 = nfs_rpcsvc_request_program_private (cs->req); - nfs3_log_commit_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3 = rpcsvc_request_program_private (cs->req); + nfs3_log_commit_res (rpcsvc_request_xid (cs->req), stat, op_errno, nfs3->serverstart); - nfs3_commit_reply (cs->req, stat, nfs3->serverstart, prebuf, postbuf); + nfs3_commit_reply (cs->req, stat, nfs3->serverstart, NULL, NULL); nfs3_call_state_wipe (cs); return 0; @@ -4812,14 +4972,14 @@ nfs3_commit_resume (void *carg) } nfs_request_user_init (&nfu, cs->req); - ret = nfs_fsync (cs->nfsx, cs->vol, &nfu, cs->fd, 0, + ret = nfs_flush (cs->nfsx, cs->vol, &nfu, cs->fd, nfs3svc_commit_cbk, cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "COMMIT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_COMMIT, stat, -ret); nfs3_commit_reply (cs->req, stat, cs->nfs3state->serverstart, NULL, NULL); @@ -4827,7 +4987,7 @@ nfs3err: ret = 0; } - return ret; + return 0; } @@ -4843,13 +5003,18 @@ nfs3_commit_open_resume (void *carg) cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); + cs->fd = fd_anonymous (cs->resolvedloc.inode); + if (!cs->fd) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to create anonymous fd."); + goto nfs3err; + } - ret = nfs3_file_open_and_resume (cs, nfs3_commit_resume); + ret = nfs3_commit_resume (cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "COMMIT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_COMMIT, stat, -ret); nfs3_commit_reply (cs->req, stat, 0, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4875,7 +5040,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, return -1; } - nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "COMMIT", fh, offset, + nfs3_log_rw_call (rpcsvc_request_xid (req), "COMMIT", fh, offset, count, -1); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -4893,7 +5058,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "COMMIT", + nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_COMMIT, stat, -ret); nfs3_commit_reply (req, stat, 0, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4915,16 +5080,16 @@ nfs3svc_commit (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_commit3args (&args, &fh); - if (xdr_to_commit3args (req->msg, &args) <= 0) { + if (xdr_to_commit3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_commit (req, &fh, args.offset, args.count); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "COMMIT procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4934,28 +5099,28 @@ rpcerr: rpcsvc_actor_t nfs3svc_actors[NFS3_PROC_COUNT] = { - {"NULL", NFS3_NULL, nfs3svc_null, NULL, NULL}, - {"GETATTR", NFS3_GETATTR, nfs3svc_getattr,NULL, NULL}, - {"SETATTR", NFS3_SETATTR, nfs3svc_setattr,NULL, NULL}, - {"LOOKUP", NFS3_LOOKUP, nfs3svc_lookup, NULL, NULL}, - {"ACCESS", NFS3_ACCESS, nfs3svc_access, NULL, NULL}, - {"READLINK", NFS3_READLINK, nfs3svc_readlink,NULL, NULL}, - {"READ", NFS3_READ, nfs3svc_read, NULL, NULL}, - {"WRITE", NFS3_WRITE, nfs3svc_write, nfs3svc_write_vec, nfs3svc_write_vecsizer}, - {"CREATE", NFS3_CREATE, nfs3svc_create, NULL, NULL}, - {"MKDIR", NFS3_MKDIR, nfs3svc_mkdir, NULL, NULL}, - {"SYMLINK", NFS3_SYMLINK, nfs3svc_symlink,NULL, NULL}, - {"MKNOD", NFS3_MKNOD, nfs3svc_mknod, NULL, NULL}, - {"REMOVE", NFS3_REMOVE, nfs3svc_remove, NULL, NULL}, - {"RMDIR", NFS3_RMDIR, nfs3svc_rmdir, NULL, NULL}, - {"RENAME", NFS3_RENAME, nfs3svc_rename, NULL, NULL}, - {"LINK", NFS3_LINK, nfs3svc_link, NULL, NULL}, - {"READDIR", NFS3_READDIR, nfs3svc_readdir,NULL, NULL}, - {"READDIRPLUS", NFS3_READDIRP, nfs3svc_readdirp,NULL, NULL}, - {"FSSTAT", NFS3_FSSTAT, nfs3svc_fsstat, NULL, NULL}, - {"FSINFO", NFS3_FSINFO, nfs3svc_fsinfo, NULL, NULL}, - {"PATHCONF", NFS3_PATHCONF, nfs3svc_pathconf,NULL, NULL}, - {"COMMIT", NFS3_COMMIT, nfs3svc_commit, NULL, NULL} + {"NULL", NFS3_NULL, nfs3svc_null, NULL, 0, DRC_IDEMPOTENT}, + {"GETATTR", NFS3_GETATTR, nfs3svc_getattr, NULL, 0, DRC_IDEMPOTENT}, + {"SETATTR", NFS3_SETATTR, nfs3svc_setattr, NULL, 0, DRC_NON_IDEMPOTENT}, + {"LOOKUP", NFS3_LOOKUP, nfs3svc_lookup, NULL, 0, DRC_IDEMPOTENT}, + {"ACCESS", NFS3_ACCESS, nfs3svc_access, NULL, 0, DRC_IDEMPOTENT}, + {"READLINK", NFS3_READLINK, nfs3svc_readlink, NULL, 0, DRC_IDEMPOTENT}, + {"READ", NFS3_READ, nfs3svc_read, NULL, 0, DRC_IDEMPOTENT}, + {"WRITE", NFS3_WRITE, nfs3svc_write, nfs3svc_write_vecsizer, 0, DRC_NON_IDEMPOTENT}, + {"CREATE", NFS3_CREATE, nfs3svc_create, NULL, 0, DRC_NON_IDEMPOTENT}, + {"MKDIR", NFS3_MKDIR, nfs3svc_mkdir, NULL, 0, DRC_NON_IDEMPOTENT}, + {"SYMLINK", NFS3_SYMLINK, nfs3svc_symlink, NULL, 0, DRC_NON_IDEMPOTENT}, + {"MKNOD", NFS3_MKNOD, nfs3svc_mknod, NULL, 0, DRC_NON_IDEMPOTENT}, + {"REMOVE", NFS3_REMOVE, nfs3svc_remove, NULL, 0, DRC_NON_IDEMPOTENT}, + {"RMDIR", NFS3_RMDIR, nfs3svc_rmdir, NULL, 0, DRC_NON_IDEMPOTENT}, + {"RENAME", NFS3_RENAME, nfs3svc_rename, NULL, 0, DRC_NON_IDEMPOTENT}, + {"LINK", NFS3_LINK, nfs3svc_link, NULL, 0, DRC_NON_IDEMPOTENT}, + {"READDIR", NFS3_READDIR, nfs3svc_readdir, NULL, 0, DRC_IDEMPOTENT}, + {"READDIRPLUS", NFS3_READDIRP, nfs3svc_readdirp, NULL, 0, DRC_IDEMPOTENT}, + {"FSSTAT", NFS3_FSSTAT, nfs3svc_fsstat, NULL, 0, DRC_IDEMPOTENT}, + {"FSINFO", NFS3_FSINFO, nfs3svc_fsinfo, NULL, 0, DRC_IDEMPOTENT}, + {"PATHCONF", NFS3_PATHCONF, nfs3svc_pathconf, NULL, 0, DRC_IDEMPOTENT}, + {"COMMIT", NFS3_COMMIT, nfs3svc_commit, NULL, 0, DRC_IDEMPOTENT} }; @@ -4964,8 +5129,6 @@ rpcsvc_program_t nfs3prog = { .prognum = NFS_PROGRAM, .progver = NFS_V3, .progport = GF_NFS3_PORT, - .progaddrfamily = AF_INET, - .proghost = NULL, .actors = nfs3svc_actors, .numactors = NFS3_PROC_COUNT, @@ -4974,21 +5137,48 @@ rpcsvc_program_t nfs3prog = { .min_auth = AUTH_NULL, }; +/* + * This function rounds up the input value to multiple of 4096. Min and Max + * supported I/O size limits are 4KB (GF_NFS3_FILE_IO_SIZE_MIN) and + * 1MB (GF_NFS3_FILE_IO_SIZE_MAX). + */ +void +nfs3_iosize_roundup_4KB (uint64_t *ioszptr) +{ + uint64_t iosize; + uint64_t iopages; + + if (!ioszptr) + return; + + iosize = *ioszptr; + iopages = (iosize + GF_NFS3_IO_SIZE -1) >> GF_NFS3_IO_SHIFT; + iosize = (iopages * GF_NFS3_IO_SIZE); + + /* Double check - boundary conditions */ + if (iosize < GF_NFS3_FILE_IO_SIZE_MIN) { + iosize = GF_NFS3_FILE_IO_SIZE_MIN; + } else if (iosize > GF_NFS3_FILE_IO_SIZE_MAX) { + iosize = GF_NFS3_FILE_IO_SIZE_MAX; + } + + *ioszptr = iosize; +} int -nfs3_init_options (struct nfs3_state *nfs3, xlator_t *nfsx) +nfs3_init_options (struct nfs3_state *nfs3, dict_t *options) { int ret = -1; char *optstr = NULL; uint64_t size64 = 0; - if ((!nfs3) || (!nfsx)) + if ((!nfs3) || (!options)) return -1; /* nfs3.read-size */ nfs3->readsize = GF_NFS3_RTPREF; - if (dict_get (nfsx->options, "nfs3.read-size")) { - ret = dict_get_str (nfsx->options, "nfs3.read-size", &optstr); + if (dict_get (options, "nfs3.read-size")) { + ret = dict_get_str (options, "nfs3.read-size", &optstr); if (ret < 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read " " option: nfs3.read-size"); @@ -4997,19 +5187,21 @@ nfs3_init_options (struct nfs3_state *nfs3, xlator_t *nfsx) } ret = gf_string2bytesize (optstr, &size64); - nfs3->readsize = size64; if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to format" " option: nfs3.read-size"); ret = -1; goto err; } + + nfs3_iosize_roundup_4KB (&size64); + nfs3->readsize = size64; } /* nfs3.write-size */ nfs3->writesize = GF_NFS3_WTPREF; - if (dict_get (nfsx->options, "nfs3.write-size")) { - ret = dict_get_str (nfsx->options, "nfs3.write-size", &optstr); + if (dict_get (options, "nfs3.write-size")) { + ret = dict_get_str (options, "nfs3.write-size", &optstr); if (ret < 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read " " option: nfs3.write-size"); @@ -5018,19 +5210,21 @@ nfs3_init_options (struct nfs3_state *nfs3, xlator_t *nfsx) } ret = gf_string2bytesize (optstr, &size64); - nfs3->writesize = size64; if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to format" " option: nfs3.write-size"); ret = -1; goto err; } + + nfs3_iosize_roundup_4KB (&size64); + nfs3->writesize = size64; } /* nfs3.readdir.size */ nfs3->readdirsize = GF_NFS3_DTPREF; - if (dict_get (nfsx->options, "nfs3.readdir-size")) { - ret = dict_get_str (nfsx->options,"nfs3.readdir-size", &optstr); + if (dict_get (options, "nfs3.readdir-size")) { + ret = dict_get_str (options,"nfs3.readdir-size", &optstr); if (ret < 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read" " option: nfs3.readdir-size"); @@ -5039,15 +5233,16 @@ nfs3_init_options (struct nfs3_state *nfs3, xlator_t *nfsx) } ret = gf_string2bytesize (optstr, &size64); - nfs3->readdirsize = size64; if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to format" " option: nfs3.readdir-size"); ret = -1; goto err; } - } + nfs3_iosize_roundup_4KB (&size64); + nfs3->readdirsize = size64; + } /* We want to use the size of the biggest param for the io buffer size. */ @@ -5058,7 +5253,7 @@ nfs3_init_options (struct nfs3_state *nfs3, xlator_t *nfsx) nfs3->iobsize = nfs3->readdirsize; /* But this is the true size of each iobuf. We need this size to - * accomodate the NFS headers also in the same buffer. */ + * accommodate the NFS headers also in the same buffer. */ nfs3->iobsize = nfs3->iobsize * 2; /* mem-factor */ @@ -5068,9 +5263,10 @@ err: return ret; } - int -nfs3_init_subvolume_options (struct nfs3_state *nfs3, struct nfs3_export *exp) +nfs3_init_subvolume_options (xlator_t *nfsx, + struct nfs3_export *exp, + dict_t *options) { int ret = -1; char *optstr = NULL; @@ -5078,14 +5274,20 @@ nfs3_init_subvolume_options (struct nfs3_state *nfs3, struct nfs3_export *exp) char *name = NULL; gf_boolean_t boolt = _gf_false; uuid_t volumeid = {0, }; - dict_t *options = NULL; - if ((!exp) || (!nfs3)) + if ((!nfsx) || (!exp)) return -1; - options = nfs3->nfsx->options; + /* For init, fetch options from xlator but for + * reconfigure, take the parameter */ + if (!options) + options = nfsx->options; + + if (!options) + return (-1); + uuid_clear (volumeid); - if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) + if (gf_nfs_dvm_off (nfs_state (nfsx))) goto no_dvm; ret = snprintf (searchkey, 1024, "nfs3.%s.volume-id",exp->subvol->name); @@ -5251,7 +5453,7 @@ nfs3_init_subvolume (struct nfs3_state *nfs3, xlator_t *subvol) INIT_LIST_HEAD (&exp->explist); gf_log (GF_NFS3, GF_LOG_TRACE, "Initing state: %s", exp->subvol->name); - ret = nfs3_init_subvolume_options (nfs3, exp); + ret = nfs3_init_subvolume_options (nfs3->nfsx, exp, NULL); if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init subvol"); goto exp_free; @@ -5303,7 +5505,7 @@ nfs3_init_state (xlator_t *nfsx) struct nfs3_state *nfs3 = NULL; int ret = -1; unsigned int localpool = 0; - + struct nfs_state *nfs = NULL; if (!nfsx) return NULL; @@ -5315,7 +5517,8 @@ nfs3_init_state (xlator_t *nfsx) return NULL; } - ret = nfs3_init_options (nfs3, nfsx); + nfs = nfsx->private; + ret = nfs3_init_options (nfs3, nfsx->options); if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init options"); goto ret; @@ -5347,6 +5550,13 @@ nfs3_init_state (xlator_t *nfsx) LOCK_INIT (&nfs3->fdlrulock); nfs3->fdcount = 0; + ret = rpcsvc_create_listeners (nfs->rpcsvc, nfsx->options, nfsx->name); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners"); + goto free_localpool; + } + + nfs->nfs3state = nfs3; ret = 0; free_localpool: @@ -5382,4 +5592,39 @@ nfs3svc_init (xlator_t *nfsx) return &nfs3prog; } +int +nfs3_reconfigure_state (xlator_t *nfsx, dict_t *options) +{ + int ret = -1; + struct nfs3_export *exp = NULL; + struct nfs_state *nfs = NULL; + struct nfs3_state *nfs3 = NULL; + + if ((!nfsx) || (!nfsx->private) || (!options)) + goto out; + + nfs = (struct nfs_state *)nfsx->private; + nfs3 = nfs->nfs3state; + if (!nfs3) + goto out; + + ret = nfs3_init_options (nfs3, options); + if (ret) { + gf_log (GF_NFS3, GF_LOG_ERROR, + "Failed to reconfigure options"); + goto out; + } + list_for_each_entry (exp, &nfs3->exports, explist) { + ret = nfs3_init_subvolume_options (nfsx, exp, options); + if (ret) { + gf_log (GF_NFS3, GF_LOG_ERROR, + "Failed to reconfigure subvol options"); + goto out; + } + } + + ret = 0; +out: + return ret; +} |
