summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-10-19 10:41:54 -0400
committerSteve Dickson <steved@redhat.com>2012-10-22 09:44:02 -0400
commit9fae1474f1f79c2c7f222a40dff6d3d4681a9115 (patch)
treeebbca3e53642daf3445bba152d41478a2bf80b41
parent62ee38804c60c5875ce3c78674419ee137deb8db (diff)
downloadnfs-utils-9fae1474f1f79c2c7f222a40dff6d3d4681a9115.zip
nfs-utils-9fae1474f1f79c2c7f222a40dff6d3d4681a9115.tar.gz
nfs-utils-9fae1474f1f79c2c7f222a40dff6d3d4681a9115.tar.xz
mountd: Dynamically allocate exportent that represents junctions
We're now duplicating a real exportent with arbitrary export options to create a junction exportent. After a dupexportent() call, several of the structure's fields can point to dynamically allocated memory. We have to be careful about not orphaning that memory. What's more, returning a pointer to a static structure is as 90's as a bad mullet. It's more straightforward to allocate the exportent dynamically and release it when we are through with it. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--utils/mountd/cache.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index 9c2b972..457fc9c 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -968,30 +968,36 @@ out_false:
/*
* Duplicate the junction's parent's export options and graft in
* the fslocdata we constructed from the locations list.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *create_junction_exportent(struct exportent *parent,
const char *junction, const char *fslocdata, int ttl)
{
- static struct exportent ee;
+ static struct exportent *eep;
- dupexportent(&ee, parent);
- strcpy(ee.e_path, junction);
- ee.e_hostname = strdup(parent->e_hostname);
- if (ee.e_hostname == NULL)
- goto out_nomem;
- free(ee.e_uuid);
- ee.e_uuid = NULL;
- ee.e_ttl = (unsigned int)ttl;
-
- free(ee.e_fslocdata);
- ee.e_fslocmethod = FSLOC_REFER;
- ee.e_fslocdata = strdup(fslocdata);
- if (ee.e_fslocdata == NULL)
+ eep = (struct exportent *)malloc(sizeof(*eep));
+ if (eep == NULL)
goto out_nomem;
- return &ee;
+ dupexportent(eep, parent);
+ strcpy(eep->e_path, junction);
+ eep->e_hostname = strdup(parent->e_hostname);
+ if (eep->e_hostname == NULL) {
+ free(eep);
+ goto out_nomem;
+ }
+ free(eep->e_uuid);
+ eep->e_uuid = NULL;
+ eep->e_ttl = (unsigned int)ttl;
+
+ free(eep->e_fslocdata);
+ eep->e_fslocdata = strdup(fslocdata);
+ if (eep->e_fslocdata == NULL) {
+ free(eep->e_hostname);
+ free(eep);
+ goto out_nomem;
+ }
+ eep->e_fslocmethod = FSLOC_REFER;
+ return eep;
out_nomem:
xlog(L_ERROR, "%s: No memory", __func__);
@@ -1001,8 +1007,6 @@ out_nomem:
/*
* Walk through the set of FS locations and build an exportent.
* Returns pointer to an exportent if "junction" refers to a junction.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *locations_to_export(struct jp_ops *ops,
nfs_fsloc_set_t locations, const char *junction,
@@ -1022,8 +1026,6 @@ static struct exportent *locations_to_export(struct jp_ops *ops,
* Retrieve locations information in "junction" and dump it to the
* kernel. Returns pointer to an exportent if "junction" refers
* to a junction.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *invoke_junction_ops(void *handle, char *dom,
const char *junction, struct addrinfo *ai)
@@ -1085,8 +1087,6 @@ out:
* Load the junction plug-in, then try to resolve "pathname".
* Returns pointer to an initialized exportent if "junction"
* refers to a junction, or NULL if not.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *lookup_junction(char *dom, const char *pathname,
struct addrinfo *ai)
@@ -1165,7 +1165,14 @@ static void nfsd_export(FILE *f)
dump_to_cache(f, dom, path, NULL);
}
} else {
- dump_to_cache(f, dom, path, lookup_junction(dom, path, ai));
+ struct exportent *eep;
+
+ eep = lookup_junction(dom, path, ai);
+ dump_to_cache(f, dom, path, eep);
+ if (eep != NULL) {
+ exportent_release(eep);
+ free(eep);
+ }
}
out:
xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);