diff options
Diffstat (limited to 'xlators/nfs/server/src/mount3.c')
| -rw-r--r-- | xlators/nfs/server/src/mount3.c | 117 |
1 files changed, 91 insertions, 26 deletions
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index 8639d7a7f..b0824bf10 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.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 @@ -83,15 +74,27 @@ typedef ssize_t (*mnt3_serializer) (struct iovec outmsg, void *args); extern void * mount3udp_thread (void *argv); +static inline void +mnt3_export_free (struct mnt3_export *exp) +{ + if (!exp) + return; + + if (exp->exptype == MNT3_EXPTYPE_DIR) + FREE_HOSTSPEC (exp); + GF_FREE (exp->expname); + GF_FREE (exp); +} /* Generic reply function for MOUNTv3 specific replies. */ int mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc) { - struct iovec outmsg = {0, }; - struct iobuf *iob = NULL; - struct mount3_state *ms = NULL; - int ret = -1; + struct iovec outmsg = {0, }; + struct iobuf *iob = NULL; + struct mount3_state *ms = NULL; + int ret = -1; + ssize_t msglen = 0; struct iobref *iobref = NULL; if (!req) @@ -117,7 +120,12 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc) /* Use the given serializer to translate the give C structure in arg * to XDR format which will be written into the buffer in outmsg. */ - outmsg.iov_len = sfunc (outmsg, arg); + msglen = sfunc (outmsg, arg); + if (msglen < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "Failed to encode message"); + goto ret; + } + outmsg.iov_len = msglen; iobref = iobref_new (); if (iobref == NULL) { @@ -125,12 +133,14 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc) goto ret; } - iobref_add (iobref, iob); + ret = iobref_add (iobref, iob); + if (ret) { + gf_log (GF_MNT, 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); - iobuf_unref (iob); - iobref_unref (iobref); if (ret == -1) { gf_log (GF_MNT, GF_LOG_ERROR, "Reply submission failed"); goto ret; @@ -138,6 +148,11 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc) ret = 0; ret: + if (NULL != iob) + iobuf_unref (iob); + if (NULL != iobref) + iobref_unref (iobref); + return ret; } @@ -576,6 +591,7 @@ __mnt3_get_volume_id (struct mount3_state *ms, xlator_t *mntxl, if ((!ms) || (!mntxl)) return ret; + LOCK (&ms->mountlock); list_for_each_entry (exp, &ms->exportlist, explist) { if (exp->vol == mntxl) { uuid_copy (volumeid, exp->volumeid); @@ -585,6 +601,7 @@ __mnt3_get_volume_id (struct mount3_state *ms, xlator_t *mntxl, } out: + UNLOCK (&ms->mountlock); return ret; } @@ -1231,6 +1248,7 @@ mnt3_mntpath_to_export (struct mount3_state *ms, char *dirpath) if ((!ms) || (!dirpath)) return NULL; + LOCK (&ms->mountlock); list_for_each_entry (exp, &ms->exportlist, explist) { /* Search for the an exact match with the volume */ @@ -1244,6 +1262,7 @@ mnt3_mntpath_to_export (struct mount3_state *ms, char *dirpath) gf_log (GF_MNT, GF_LOG_DEBUG, "Export not found"); foundexp: + UNLOCK (&ms->mountlock); return found; } @@ -1272,7 +1291,7 @@ mnt3_check_client_net (struct mount3_state *ms, rpcsvc_request_t *req, gai_strerror (ret)); } - ret = rpcsvc_auth_check (svc->options, targetxl->name, trans); + ret = rpcsvc_auth_check (svc, targetxl->name, trans); if (ret == RPCSVC_AUTH_REJECT) { gf_log (GF_MNT, GF_LOG_INFO, "Peer %s not allowed", peer); goto err; @@ -1800,6 +1819,10 @@ mnt3_xlchildren_to_exports (rpcsvc_t *svc, struct mount3_state *ms) return NULL; nfs = (struct nfs_state *)ms->nfsx->private; + if (!nfs) + return NULL; + + LOCK (&ms->mountlock); list_for_each_entry(ent, &ms->exportlist, explist) { /* If volume is not started yet, do not list it for tools like @@ -1857,6 +1880,7 @@ mnt3_xlchildren_to_exports (rpcsvc_t *svc, struct mount3_state *ms) ret = 0; free_list: + UNLOCK (&ms->mountlock); if (ret == -1) { xdr_free_exports_list (first); first = NULL; @@ -2189,8 +2213,9 @@ mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath, ret = snprintf (exp->expname, alloclen, "/%s", xl->name); } if (ret < 0) { - gf_log (xl->name, GF_LOG_WARNING, - "failed to get the export name"); + gf_log (xl->name, GF_LOG_ERROR, + "Failed to set the export name"); + goto err; } /* Just copy without discrimination, we'll determine whether to * actually use it when a mount request comes in and a file handle @@ -2204,8 +2229,7 @@ mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath, err: /* On failure free exp and it's members.*/ if (NULL != exp) { - FREE_HOSTSPEC (exp); - GF_FREE (exp); + mnt3_export_free (exp); exp = NULL; } @@ -2692,3 +2716,44 @@ mnt1svc_init (xlator_t *nfsx) err: return NULL; } + +int +mount_reconfigure_state (xlator_t *nfsx, dict_t *options) +{ + int ret = -1; + struct nfs_state *nfs = NULL; + struct mount3_state *ms = NULL; + struct mnt3_export *exp = NULL; + struct mnt3_export *texp = NULL; + + if ((!nfsx) || (!options)) + return (-1); + + nfs = (struct nfs_state *)nfs_state (nfsx); + if (!nfs) + return (-1); + + ms = nfs->mstate; + if (!ms) + return (-1); + + /* + * Free() up the old export list. mnt3_init_options() will + * rebuild the export list from scratch. Do it with locking + * to avoid unnecessary race conditions. + */ + LOCK (&ms->mountlock); + list_for_each_entry_safe (exp, texp, &ms->exportlist, explist) { + list_del (&exp->explist); + mnt3_export_free (exp); + } + ret = mnt3_init_options (ms, options); + UNLOCK (&ms->mountlock); + + if (ret < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "Options reconfigure failed"); + return (-1); + } + + return (0); +} |
