summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/nfs3.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/nfs/server/src/nfs3.c')
-rw-r--r--xlators/nfs/server/src/nfs3.c1026
1 files changed, 564 insertions, 462 deletions
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index d78360502..f914c3193 100644
--- a/xlators/nfs/server/src/nfs3.c
+++ b/xlators/nfs/server/src/nfs3.c
@@ -2,19 +2,10 @@
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 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
- General Public License for more details.
-
- You should have received a copy of the GNU 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,6 +23,7 @@
#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"
@@ -216,47 +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 buf[256]; \
+ char exportid[256], gfid[256]; \
+ rpc_transport_t *trans = NULL; \
volume = nfs3_fh_to_xlator ((nfs3state), handle); \
if (!volume) { \
- uuid_unparse (handle->exportid, buf); \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to map " \
- "FH to vol, exportid=%s", buf); \
+ 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); \
- 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)) { \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad 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]; \
+ 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->fh.gfid, gfid); \
- sprintf (buf, "%s : %s", xlatorp ? \
- xlatorp->name : "ERR", gfid); \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Unable to resolve FH"\
- ": %s", buf); \
+ 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; \
} \
@@ -265,16 +270,20 @@ out:
#define nfs3_check_new_fh_resolve_status(cst, nfstat, erlabl) \
do { \
xlator_t *xlatorp = NULL; \
- char buf[256], gfid[256]; \
+ 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->fh.gfid, gfid); \
- sprintf (buf, "%s : %s", xlatorp ? \
- xlatorp->name : "ERR", gfid); \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Unable to resolve FH"\
- ": %s", buf); \
+ &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; \
} \
@@ -435,11 +444,9 @@ nfs3_call_state_wipe (nfs3_call_state_t *cs)
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);
@@ -450,6 +457,8 @@ nfs3_call_state_wipe (nfs3_call_state_t *cs)
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 (cs);
/* Already refd by fd_lookup, so no need to ref again. */
@@ -487,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");
@@ -538,23 +549,18 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc)
iobref = iobref_new ();
if (!iobref) {
- iobuf_unref (iob);
gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new()");
goto ret;
}
- iobref_add (iobref, 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);
-
- /* 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);
- iobref_unref (iobref);
-
if (ret == -1) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed");
goto ret;
@@ -562,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;
}
@@ -593,19 +607,14 @@ nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg,
new_iobref = 1;
}
- iobref_add (iobref, 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, payload, vcount, iobref);
-
- /* 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);
- if (new_iobref)
- iobref_unref (iobref);
-
if (ret == -1) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed");
goto ret;
@@ -613,6 +622,14 @@ nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg,
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;
}
@@ -677,14 +694,23 @@ nfs3svc_getattr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
+ /*
+ * 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.
+ */
+
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_errno_to_nfsstat3 (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), "GETATTR",
+ nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_GETATTR,
status, op_errno);
nfs3_getattr_reply (cs->req, status, buf);
@@ -696,7 +722,8 @@ 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;
@@ -707,10 +734,10 @@ nfs3svc_getattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- status = nfs3_errno_to_nfsstat3 (op_errno);
+ status = nfs3_cbk_errno_status (op_ret, op_errno);
}
- nfs3_log_common_res (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);
@@ -727,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;
@@ -739,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 (__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));
@@ -756,8 +814,8 @@ nfs3_getattr_resume (void *carg)
nfs3err:
if (ret < 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "GETATTR", stat, -ret);
- nfs3_getattr_reply (cs->req, stat, NULL);
+ NFS3_GETATTR, stat, -ret);
+ nfs3_getattr_reply (cs->req, stat, &cs->stbuf);
nfs3_call_state_wipe (cs);
ret = 0;
}
@@ -791,7 +849,7 @@ nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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;
@@ -849,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;
@@ -860,7 +918,7 @@ nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
@@ -875,7 +933,7 @@ nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
nfs3err:
- nfs3_log_common_res (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);
@@ -887,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;
@@ -900,28 +958,22 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (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);
@@ -936,7 +988,7 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs3err:
if (ret < 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "SETATTR", stat, op_errno);
+ NFS3_SETATTR, stat, op_errno);
nfs3_setattr_reply (cs->req, stat, prebuf, postop);
nfs3_call_state_wipe (cs);
}
@@ -948,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;
@@ -961,7 +1014,7 @@ nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
@@ -982,7 +1035,7 @@ nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs3err:
if (ret < 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "SETATTR", stat, op_errno);
+ NFS3_SETATTR, stat, op_errno);
nfs3_setattr_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -1005,14 +1058,9 @@ 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);
@@ -1020,7 +1068,7 @@ nfs3_setattr_resume (void *carg)
nfs3err:
if (ret < 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "SETATTR", stat, -ret);
+ NFS3_SETATTR, stat, -ret);
nfs3_setattr_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -1076,7 +1124,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -1180,7 +1228,7 @@ nfs3svc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
(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_errno_to_nfsstat3 (op_errno);
+ status = nfs3_cbk_errno_status (op_ret, op_errno);
goto xmit_res;
}
@@ -1194,7 +1242,7 @@ xmit_res:
goto out;
}
- nfs3_log_newfh_res (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);
@@ -1224,7 +1272,7 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- status = nfs3_errno_to_nfsstat3 (op_errno);
+ status = nfs3_cbk_errno_status (op_ret, op_errno);
goto xmit_res;
}
@@ -1247,7 +1295,7 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
xmit_res:
- nfs3_log_newfh_res (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);
@@ -1266,7 +1314,11 @@ nfs3_lookup_parentdir_resume (void *carg)
nfs3_call_state_t *cs = NULL;
inode_t *parent = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, carg, nfs3err);
+ 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);
@@ -1297,7 +1349,8 @@ 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) {
gf_log (GF_NFS3, GF_LOG_ERROR, "nfs_inode_loc_fill"
@@ -1314,7 +1367,7 @@ errtostat:
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -1334,13 +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},};
- GF_VALIDATE_OR_GOTO (GF_NFS3, carg, nfs3err);
+ 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)
@@ -1348,9 +1413,10 @@ nfs3_lookup_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
}
@@ -1384,12 +1450,8 @@ 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) {
gf_log (GF_NFS, GF_LOG_ERROR, "failed to start hard reslove");
@@ -1398,7 +1460,7 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -1443,11 +1505,12 @@ rpcerr:
int
-nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits)
+nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits,
+ int32_t reqaccbits)
{
access3res res;
- nfs3_fill_access3res (&res, status, accbits);
+ nfs3_fill_access3res (&res, status, accbits, reqaccbits);
nfs3svc_submit_reply (req, &res,
(nfs3_serializer)xdr_serialize_access3res);
return 0;
@@ -1456,7 +1519,7 @@ nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits)
int32_t
nfs3svc_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
nfsstat3 status = NFS3_OK;
nfs3_call_state_t *cs = NULL;
@@ -1467,11 +1530,11 @@ nfs3svc_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- status = nfs3_errno_to_nfsstat3 (op_errno);
+ status = nfs3_cbk_errno_status (op_ret, op_errno);
}
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), "ACCESS", status,
+ nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_ACCESS, status,
op_errno);
- nfs3_access_reply (cs->req, status, op_errno);
+ nfs3_access_reply (cs->req, status, op_errno, cs->accessbits);
nfs3_call_state_wipe (cs);
return 0;
@@ -1485,7 +1548,11 @@ nfs3_access_resume (void *carg)
nfs_user_t nfu = {0, };
nfs3_call_state_t *cs = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, carg, nfs3err);
+ 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);
@@ -1498,9 +1565,9 @@ nfs3_access_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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, 0);
+ nfs3_access_reply (cs->req, stat, 0, 0);
nfs3_call_state_wipe (cs);
ret = 0;
}
@@ -1534,9 +1601,9 @@ nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), "ACCESS",
+ nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_ACCESS,
stat, -ret);
- nfs3_access_reply (req, stat, 0);
+ nfs3_access_reply (req, stat, 0, 0);
nfs3_call_state_wipe (cs);
ret = 0;
}
@@ -1593,7 +1660,7 @@ 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;
@@ -1603,7 +1670,7 @@ nfs3svc_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
@@ -1641,7 +1708,7 @@ nfs3_readlink_resume (void *carg)
nfs3err:
if (ret < 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "READLINK", stat, -ret);
+ NFS3_READLINK, stat, -ret);
nfs3_readlink_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -1677,7 +1744,7 @@ nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -1758,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;
@@ -1769,7 +1837,7 @@ nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto err;
} else
stat = NFS3_OK;
@@ -1808,7 +1876,7 @@ nfs3_read_fd_resume (void *carg)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -1824,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 (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);
@@ -1876,7 +1950,7 @@ nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -1936,7 +2010,7 @@ 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;
@@ -1949,7 +2023,7 @@ nfs3svc_write_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
} else
stat = NFS3_OK;
@@ -1962,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
@@ -2032,15 +2071,11 @@ 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 = rpcsvc_request_program_private (cs->req);
@@ -2048,42 +2083,21 @@ nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (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 (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;
}
@@ -2125,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 (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 (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);
@@ -2174,7 +2187,6 @@ nfs3err:
}
-
int
nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
count3 count, stable_how stable, struct iovec payload,
@@ -2206,13 +2218,13 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
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 (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);
@@ -2230,17 +2242,18 @@ out:
int
-nfs3svc_write_vecsizer (int state, ssize_t *readsize, char *addr)
+nfs3svc_write_vecsizer (int state, ssize_t *readsize, char *base_addr,
+ char *curr_addr)
{
- int ret = 0;
- uint32_t fhlen = 0;
- uint32_t fhlen_n = 0;
+ int ret = 0;
+ uint32_t fhlen = 0;
+ uint32_t fhlen_n = 0;
if (state == 0) {
ret = NFS3_VECWRITE_READFHLEN;
*readsize = 4;
} else if (state == NFS3_VECWRITE_READFHLEN) {
- fhlen_n = *(uint32_t *)(addr - 4);
+ fhlen_n = *(uint32_t *)(curr_addr - 4);
fhlen = ntohl (fhlen_n);
*readsize = xdr_length_round_up (fhlen, NFS3_FHSIZE);
ret = NFS3_VECWRITE_READFH;
@@ -2291,12 +2304,6 @@ rpcerr:
return ret;
}
-int
-nfs3svc_write_vec (rpcsvc_request_t *req, struct iovec *payload,
- int payload_count, struct iobref *iobref)
-{
- return nfs3svc_write (req);
-}
int
nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh,
@@ -2318,7 +2325,7 @@ 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;
@@ -2328,13 +2335,13 @@ nfs3svc_create_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (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);
@@ -2348,23 +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) {
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (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) {
@@ -2376,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 (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);
@@ -2399,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.
@@ -2428,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;
@@ -2442,7 +2473,7 @@ nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"%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;
}
@@ -2464,7 +2495,7 @@ nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -2505,16 +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->resolvedloc,
- O_RDWR,
- NFS_DEFAULT_CREATE_MODE, nfs3svc_create_cbk,
- cs);
-
+ ret = nfs3_create_common (cs);
nfs3err:
return ret;
}
@@ -2543,7 +2565,7 @@ nfs3_create_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -2590,7 +2612,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -2622,13 +2644,7 @@ nfs3svc_create (rpcsvc_request_t *req)
}
cval = (uint64_t *)args.how.createhow3_u.verf;
- if (cval)
- cverf = *cval;
- else {
- gf_log(GF_NFS3, GF_LOG_ERROR,
- "Error getting createverf3 from args");
- goto rpcerr;
- }
+ cverf = *cval;
ret = nfs3_create (req, &dirfh, name, args.how.mode,
&args.how.createhow3_u.obj_attributes, cverf);
@@ -2662,7 +2678,7 @@ 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;
@@ -2672,13 +2688,13 @@ nfs3svc_mkdir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (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);
@@ -2692,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;
@@ -2704,7 +2720,7 @@ nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
@@ -2726,7 +2742,7 @@ nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs3err:
if (ret < 0) {
- nfs3_log_newfh_res (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);
@@ -2765,7 +2781,7 @@ nfs3_mkdir_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -2810,7 +2826,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -2872,7 +2888,7 @@ 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;
@@ -2882,7 +2898,7 @@ nfs3svc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
@@ -2890,7 +2906,7 @@ nfs3svc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (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);
@@ -2921,7 +2937,7 @@ nfs3_symlink_resume (void *carg)
nfs3err:
if (ret < 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "SYMLINK", stat, -ret);
+ NFS3_SYMLINK, stat, -ret);
nfs3_symlink_reply (cs->req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -2969,7 +2985,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3034,7 +3050,7 @@ 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;
@@ -3044,13 +3060,13 @@ nfs3svc_mknod_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (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);
@@ -3064,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;
@@ -3076,7 +3092,7 @@ nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
@@ -3098,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 (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,
@@ -3197,7 +3213,7 @@ nfs3_mknod_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3263,7 +3279,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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
@@ -3324,34 +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) {
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
- goto do_not_unref_cached_fd;
+ 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 = 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 (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);
@@ -3400,7 +3405,7 @@ nfs3_remove_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3440,7 +3445,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3501,7 +3506,7 @@ 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;
@@ -3511,12 +3516,12 @@ nfs3svc_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
} else {
stat = NFS3_OK;
}
- nfs3_log_common_res (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);
@@ -3545,7 +3550,7 @@ nfs3_rmdir_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3586,7 +3591,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3653,12 +3658,12 @@ 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) {
@@ -3666,25 +3671,13 @@ nfs3svc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"%x: rename %s -> %s => -1 (%s)",
rpcsvc_request_xid (cs->req), cs->oploc.path,
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (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 (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);
@@ -3715,7 +3708,7 @@ nfs3_rename_resume_dst (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3752,7 +3745,7 @@ nfs3_rename_resume_src (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3807,7 +3800,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3872,7 +3865,7 @@ 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;
@@ -3883,11 +3876,11 @@ nfs3svc_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"%x: link %s <- %s => -1 (%s)",
rpcsvc_request_xid (cs->req), cs->oploc.path,
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
} else
stat = NFS3_OK;
- nfs3_log_common_res (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);
@@ -3918,7 +3911,7 @@ nfs3_link_resume_lnk (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3949,7 +3942,7 @@ nfs3_link_resume_tgt (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -3998,7 +3991,7 @@ nfs3_link (rpcsvc_request_t *req, struct nfs3_fh *targetfh,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -4081,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;
@@ -4092,7 +4086,7 @@ nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto nfs3err;
}
@@ -4134,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;
@@ -4146,7 +4141,7 @@ nfs3svc_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto err;
}
@@ -4167,11 +4162,11 @@ err:
if (cs->maxcount == 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "READDIR", stat, op_errno);
+ NFS3_READDIR, stat, op_errno);
nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0);
} else {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "READDIRP", stat, op_errno);
+ NFS3_READDIRP, stat, op_errno);
nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0, 0);
}
@@ -4227,12 +4222,12 @@ nfs3err:
if (ret < 0) {
if (cs->maxcount == 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "READDIR", stat, -ret);
+ NFS3_READDIR, stat, -ret);
nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0);
} else {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "READDIRP", stat, -ret);
+ NFS3_READDIRP, stat, -ret);
nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0, 0);
}
@@ -4243,19 +4238,59 @@ 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);
@@ -4263,12 +4298,12 @@ nfs3err:
if (ret < 0) {
if (cs->maxcount == 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "READDIR", stat, -ret);
+ NFS3_READDIR, stat, -ret);
nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0);
} else {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "READDIRP", stat, -ret);
+ NFS3_READDIRP, stat, -ret);
nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0, 0);
}
@@ -4317,12 +4352,12 @@ nfs3err:
if (ret < 0) {
if (maxcount == 0) {
nfs3_log_common_res (rpcsvc_request_xid (req),
- "READDIR", stat, -ret);
+ NFS3_READDIR, stat, -ret);
nfs3_readdir_reply (req, stat, NULL, 0, NULL, NULL, 0,
0);
} else {
nfs3_log_common_res (rpcsvc_request_xid (req),
- "READDIRP", stat, -ret);
+ NFS3_READDIRP, stat, -ret);
nfs3_readdirp_reply (req, stat, NULL, 0, NULL, NULL, 0,
0, 0);
}
@@ -4354,16 +4389,8 @@ nfs3svc_readdir (rpcsvc_request_t *req)
rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
-
cval = (uint64_t *) ra.cookieverf;
-
- if (cval)
- verf = *cval;
- else {
- gf_log(GF_NFS3, GF_LOG_ERROR,
- "Error getting cookieverf from readdir args");
- goto rpcerr;
- }
+ verf = *cval;
ret = nfs3_readdir (req, &fh, ra.cookie, verf, ra.count, 0);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
@@ -4394,16 +4421,8 @@ nfs3svc_readdirp (rpcsvc_request_t *req)
rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
-
cval = (uint64_t *) ra.cookieverf;
-
- if (cval)
- cverf = *cval;
- else {
- gf_log (GF_NFS3, GF_LOG_ERROR,
- "Error getting cookieverf from readdirp args");
- goto rpcerr;
- }
+ cverf = *cval;
ret = nfs3_readdir (req, &fh, ra.cookie, cverf, ra.dircount,
ra.maxcount);
@@ -4435,7 +4454,8 @@ 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;
@@ -4445,11 +4465,11 @@ nfs3_fsstat_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
} else
stat = NFS3_OK;
- nfs3_log_common_res (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);
@@ -4459,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;
@@ -4472,7 +4493,7 @@ nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"%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;
}
@@ -4488,7 +4509,7 @@ nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -4520,7 +4541,7 @@ nfs3_fsstat_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -4558,7 +4579,7 @@ nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -4619,7 +4640,8 @@ 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;
@@ -4630,11 +4652,11 @@ nfs3svc_fsinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- status = nfs3_errno_to_nfsstat3 (op_errno);
+ status = nfs3_cbk_errno_status (op_ret, op_errno);
}else
status = NFS3_OK;
- nfs3_log_common_res (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);
@@ -4667,7 +4689,7 @@ nfs3_fsinfo_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -4704,7 +4726,7 @@ nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -4760,7 +4782,8 @@ 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;
@@ -4771,7 +4794,7 @@ nfs3svc_pathconf_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (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.
@@ -4780,7 +4803,7 @@ nfs3svc_pathconf_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
}
- nfs3_log_common_res (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);
@@ -4810,7 +4833,7 @@ nfs3_pathconf_resume (void *carg)
nfs3err:
if (ret < 0) {
nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- "PATHCONF", stat, -ret);
+ NFS3_PATHCONF, stat, -ret);
nfs3_pathconf_reply (cs->req, stat, NULL);
nfs3_call_state_wipe (cs);
}
@@ -4845,7 +4868,7 @@ nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -4904,8 +4927,7 @@ 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;
@@ -4916,14 +4938,14 @@ nfs3svc_commit_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (GF_NFS, GF_LOG_WARNING,
"%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_errno_to_nfsstat3 (op_errno);
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
} else
stat = NFS3_OK;
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;
@@ -4950,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 (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);
@@ -4965,7 +4987,7 @@ nfs3err:
ret = 0;
}
- return ret;
+ return 0;
}
@@ -4981,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 (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);
@@ -5031,7 +5058,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (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);
@@ -5072,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}
};
@@ -5110,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");
@@ -5133,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");
@@ -5154,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");
@@ -5175,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.
*/
@@ -5204,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;
@@ -5214,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);
@@ -5387,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;
@@ -5452,7 +5518,7 @@ nfs3_init_state (xlator_t *nfsx)
}
nfs = nfsx->private;
- ret = nfs3_init_options (nfs3, nfsx);
+ ret = nfs3_init_options (nfs3, nfsx->options);
if (ret == -1) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init options");
goto ret;
@@ -5484,12 +5550,13 @@ nfs3_init_state (xlator_t *nfsx)
LOCK_INIT (&nfs3->fdlrulock);
nfs3->fdcount = 0;
- rpcsvc_create_listeners (nfs->rpcsvc, nfsx->options, nfsx->name);
+ 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:
@@ -5525,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;
+}