summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/nfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/nfs/server/src/nfs.c')
-rw-r--r--xlators/nfs/server/src/nfs.c379
1 files changed, 296 insertions, 83 deletions
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
index 431765332..3fa46662f 100644
--- a/xlators/nfs/server/src/nfs.c
+++ b/xlators/nfs/server/src/nfs.c
@@ -169,7 +169,7 @@ ret:
int
-nfs_subvolume_started (struct nfs_state *nfs, xlator_t *xl)
+__is_nfs_subvolume_lookup_sent (struct nfs_state *nfs, xlator_t *xl)
{
int x = 0;
int started = 0;
@@ -177,16 +177,32 @@ nfs_subvolume_started (struct nfs_state *nfs, xlator_t *xl)
if ((!nfs) || (!xl))
return 1;
+ for (;x < nfs->allsubvols; ++x) {
+ if (!((&nfs->subvols[x])->subvol == xl))
+ continue;
+
+ if (gf_nfs_subvolume_lookupsent (&nfs->subvols[x])) {
+ started = 1;
+ goto out;
+ }
+ }
+out:
+ return started;
+}
+
+
+int
+is_nfs_subvolume_lookup_sent (struct nfs_state *nfs, xlator_t *xl)
+{
+ int started = 0;
+
+ if ((!nfs) || (!xl))
+ return 1;
+
LOCK (&nfs->svinitlock);
{
- for (;x < nfs->allsubvols; ++x) {
- if (nfs->initedxl[x] == xl) {
- started = 1;
- goto unlock;
- }
- }
+ started = __is_nfs_subvolume_lookup_sent (nfs, xl);
}
-unlock:
UNLOCK (&nfs->svinitlock);
return started;
@@ -194,27 +210,187 @@ unlock:
int
-nfs_subvolume_set_started (struct nfs_state *nfs, xlator_t *xl)
+__is_nfs_subvolume_started (struct nfs_state *nfs, xlator_t *xl)
{
int x = 0;
+ int started = 0;
+
+ if ((!nfs) || (!xl))
+ return 1;
+
+ for (;x < nfs->allsubvols; ++x) {
+ if (!((&nfs->subvols[x])->subvol == xl))
+ continue;
+
+ if (gf_nfs_subvolume_started (&nfs->subvols[x])) {
+ started = 1;
+ goto out;
+ }
+ }
+out:
+ return started;
+}
+
+
+int
+is_nfs_subvolume_started (struct nfs_state *nfs, xlator_t *xl)
+{
+ int started = 0;
if ((!nfs) || (!xl))
return 1;
LOCK (&nfs->svinitlock);
{
- for (;x < nfs->allsubvols; ++x) {
- if (nfs->initedxl[x] == NULL) {
- nfs->initedxl[x] = xl;
- ++nfs->upsubvols;
- gf_log (GF_NFS, GF_LOG_DEBUG, "Starting up: %s "
- ", vols started till now: %d", xl->name,
- nfs->upsubvols);
- goto unlock;
- }
- }
+ started = __is_nfs_subvolume_started (nfs, xl);
+ }
+ UNLOCK (&nfs->svinitlock);
+
+ return started;
+}
+
+
+int
+__nfs_subvolume_lookup_again_later (struct nfs_state *nfs, xlator_t *xl)
+{
+ int x = 0;
+ struct nfs_subvolume *sv = NULL;
+
+ if ((!nfs) || (!xl))
+ return -1;
+
+ for (;x < nfs->allsubvols; ++x) {
+ if (((&nfs->subvols[x])->subvol == xl)) {
+ sv = &nfs->subvols[x];
+ break;
+ }
+ }
+
+ if (!sv)
+ goto err;
+ gf_log (GF_NFS, GF_LOG_TRACE, "Will lookup subvol later: %s",
+ xl->name);
+ sv->status = GF_NFS_SUBVOLUME_NOTSTARTED;
+err:
+ return 0;
+}
+
+
+int
+__nfs_subvolume_start (struct nfs_state *nfs, xlator_t *xl)
+{
+ int x = 0;
+ int ret = 0;
+ struct nfs_subvolume *sv = NULL;
+
+ if ((!nfs) || (!xl))
+ return -1;
+
+ for (;x < nfs->allsubvols; ++x) {
+ if (((&nfs->subvols[x])->subvol == xl)) {
+ sv = &nfs->subvols[x];
+ break;
+ }
+ }
+
+ if (!sv) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "Could not find subvol slot");
+ goto err;
+ }
+
+ /* If the subvolume got disconnected or sent a CHILD-DOWN between the
+ * lookup fop and the lookup callback.
+ */
+ if (gf_nfs_subvolume_notstarted (sv)) {
+ goto err;
+ }
+
+ sv->status = GF_NFS_SUBVOLUME_STARTED;
+ ++nfs->upsubvols;
+ gf_log (GF_NFS, GF_LOG_DEBUG, "Starting up: %s, vols started till now: "
+ "%d", xl->name, nfs->upsubvols);
+
+ if (gf_nfs_all_subvolumes_started (nfs)) {
+ nfs->subvols_started = 1;
+ gf_log (GF_NFS, GF_LOG_INFO, "All exports up");
+ ret = nfs_init_versions (nfs, nfs->nfsx);
+ if (ret == -1)
+ gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to initialize "
+ "protocols");
+ }
+err:
+ return 0;
+}
+
+
+int
+nfs_subvolume_start (struct nfs_state *nfs, xlator_t *xl)
+{
+ if ((!nfs) || (!xl))
+ return 1;
+
+ LOCK (&nfs->svinitlock);
+ {
+ __nfs_subvolume_start (nfs, xl);
+ }
+ UNLOCK (&nfs->svinitlock);
+
+ return 0;
+}
+
+
+int
+__nfs_subvolume_lookup_sent (struct nfs_state *nfs, xlator_t *xl)
+{
+ struct nfs_subvolume *sv = NULL;
+ int x = 0;
+
+ if ((!nfs) || (!xl))
+ return -1;
+
+ for (;x < nfs->allsubvols; ++x) {
+ if (((&nfs->subvols[x])->subvol == xl)) {
+ sv = &nfs->subvols[x];
+ break;
+ }
+ }
+
+ if (sv) {
+ sv->status = GF_NFS_SUBVOLUME_LOOKUPSENT;
+ } else
+ gf_log (GF_NFS, GF_LOG_ERROR, "Could not find subvol slot: %s",
+ xl->name);
+
+ return 0;
+}
+
+
+int
+nfs_subvolume_lookup_sent (struct nfs_state *nfs, xlator_t *xl)
+{
+ if ((!nfs) || (!xl))
+ return 1;
+
+ LOCK (&nfs->svinitlock);
+ {
+ __nfs_subvolume_lookup_sent (nfs, xl);
+ }
+ UNLOCK (&nfs->svinitlock);
+
+ return 0;
+}
+
+
+int
+nfs_subvolume_lookup_again_later (struct nfs_state *nfs, xlator_t *xl)
+{
+ if ((!nfs) || (!xl))
+ return 1;
+
+ LOCK (&nfs->svinitlock);
+ {
+ __nfs_subvolume_lookup_again_later (nfs, xl);
}
-unlock:
UNLOCK (&nfs->svinitlock);
return 0;
@@ -227,36 +403,71 @@ nfs_start_subvol_lookup_cbk (call_frame_t *frame, void *cookie,
inode_t *inode, struct iatt *buf, dict_t *xattr,
struct iatt *postparent)
{
+ struct nfs_state *nfs = frame->local;
+
if (op_ret == -1) {
gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to lookup root: %s",
strerror (op_errno));
+ nfs_subvolume_lookup_again_later (nfs, (xlator_t *)cookie);
goto err;
}
- gf_log (GF_NFS, GF_LOG_TRACE, "Started %s", ((xlator_t *)cookie)->name);
+ nfs_subvolume_start (nfs, (xlator_t *)cookie);
err:
return 0;
}
int
+__nfs_startup_subvolume_check (struct nfs_state *nfs, xlator_t *xl)
+{
+ int ret = 0;
+
+ if (__is_nfs_subvolume_started (nfs, xl)) {
+ gf_log (GF_NFS,GF_LOG_TRACE, "Subvolume already started: %s",
+ xl->name);
+ ret = 1;
+ goto out;
+ }
+
+ if (__is_nfs_subvolume_lookup_sent (nfs, xl)) {
+ gf_log (GF_NFS,GF_LOG_TRACE,"Subvolume lookup already sent: %s",
+ xl->name);
+ ret = 1;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+int
nfs_startup_subvolume (xlator_t *nfsx, xlator_t *xl)
{
- int ret = -1;
- loc_t rootloc = {0, };
- nfs_user_t nfu = {0, };
+ int ret = -1;
+ loc_t rootloc = {0, };
+ nfs_user_t nfu = {0, };
+ struct nfs_state *nfs = NULL;
if ((!nfsx) || (!xl))
return -1;
- if (nfs_subvolume_started (nfsx->private, xl)) {
- gf_log (GF_NFS,GF_LOG_TRACE, "Subvolume already started: %s",
- xl->name);
- ret = 0;
- goto err;
+ nfs = nfsx->private;
+ LOCK (&nfs->svinitlock);
+ {
+ ret = __nfs_startup_subvolume_check (nfsx->private, xl);
+ if (ret)
+ goto unlock;
+
+ __nfs_subvolume_lookup_sent (nfs, xl);
}
+unlock:
+ UNLOCK (&nfs->svinitlock);
+
+ if (ret)
+ goto err;
- nfs_subvolume_set_started (nfsx->private, xl);
ret = nfs_inode_loc_fill (xl->itable->root, &rootloc);
if (ret == -1) {
gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init root loc");
@@ -279,35 +490,6 @@ err:
return ret;
}
-int
-nfs_startup_subvolumes (xlator_t *nfsx)
-{
- int ret = -1;
- xlator_list_t *cl = NULL;
- struct nfs_state *nfs = NULL;
-
- if (!nfsx)
- return -1;
-
- nfs = nfsx->private;
- cl = nfs->subvols;
- while (cl) {
- gf_log (GF_NFS, GF_LOG_DEBUG, "Starting subvolume: %s",
- cl->xlator->name);
- ret = nfs_startup_subvolume (nfsx, cl->xlator);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to start-up "
- "xlator: %s", cl->xlator->name);
- goto err;
- }
- cl = cl->next;
- }
-
- ret = 0;
-err:
- return ret;
-}
-
int
nfs_init_subvolume (struct nfs_state *nfs, xlator_t *xl)
@@ -333,17 +515,19 @@ err:
int
nfs_init_subvolumes (struct nfs_state *nfs, xlator_list_t *cl)
{
- int ret = -1;
- unsigned int lrusize = 0;
- int svcount = 0;
+ int ret = -1;
+ unsigned int lrusize = 0;
+ int svcount = 0;
+ int x = 0;
+ xlator_list_t *tmpcl = NULL;
+ struct nfs_subvolume *sv = NULL;
if ((!nfs) || (!cl))
return -1;
lrusize = nfs->memfactor * GF_NFS_INODE_LRU_MULT;
- nfs->subvols = cl;
gf_log (GF_NFS, GF_LOG_TRACE, "inode table lru: %d", lrusize);
-
+ tmpcl = cl;
while (cl) {
gf_log (GF_NFS, GF_LOG_DEBUG, "Initing subvolume: %s",
cl->xlator->name);
@@ -358,16 +542,23 @@ nfs_init_subvolumes (struct nfs_state *nfs, xlator_list_t *cl)
}
LOCK_INIT (&nfs->svinitlock);
- nfs->initedxl = GF_CALLOC (svcount, sizeof (xlator_t *),
- gf_nfs_mt_xlator_t );
- if (!nfs->initedxl) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to allocated inited xls");
+ nfs->subvols = GF_CALLOC (svcount, sizeof (struct nfs_subvolume),
+ gf_nfs_mt_subvolumes);
+ if (!nfs->subvols) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "Failed to allocate subvol list");
ret = -1;
goto err;
}
- gf_log (GF_NFS, GF_LOG_TRACE, "Inited volumes: %d", svcount);
+ cl = tmpcl;
nfs->allsubvols = svcount;
+ for (;x < nfs->allsubvols; x++) {
+ sv = &nfs->subvols[x];
+ sv->subvol = cl->xlator;
+ sv->status = GF_NFS_SUBVOLUME_NOTSTARTED;
+ }
+
+ gf_log (GF_NFS, GF_LOG_TRACE, "inited volumes: %d", svcount);
ret = 0;
err:
return ret;
@@ -482,6 +673,7 @@ nfs_init_state (xlator_t *this)
return NULL;
}
+ nfs->nfsx = this;
/* RPC service needs to be started before NFS versions can be
* inited. */
nfs->rpcsvc = nfs_rpcsvc_init (this->ctx, this->options);
@@ -580,33 +772,48 @@ err:
int
+nfs_disable_subvolume (xlator_t *nfsx, xlator_t *xl)
+{
+ struct nfs_state *nfs = NULL;
+
+ if ((!nfsx) || (!xl))
+ return -1;
+
+ nfs = nfsx->private;
+ gf_log (GF_NFS, GF_LOG_TRACE, "Disabling subvolume: %s", xl->name);
+ LOCK (&nfs->svinitlock);
+ {
+ if (!__is_nfs_subvolume_started (nfsx->private, xl)) {
+ gf_log (GF_NFS,GF_LOG_TRACE, "Subvolume not started, "
+ "no point disabling: %s", xl->name);
+ goto unlock;
+ }
+ --nfs->upsubvols;
+ __nfs_subvolume_lookup_again_later (nfs, xl);
+ }
+unlock:
+ UNLOCK (&nfs->svinitlock);
+
+ return 0;
+}
+
+
+int
notify (xlator_t *this, int32_t event, void *data, ...)
{
struct nfs_state *nfs = NULL;
xlator_t *subvol = NULL;
- int ret = -1;
nfs = (struct nfs_state *)this->private;
subvol = (xlator_t *)data;
- gf_log (GF_NFS, GF_LOG_TRACE, "Notification received: %d",
- event);
+ gf_log (GF_NFS, GF_LOG_TRACE, "Notification received: %s",
+ glusterfs_strevent (event));
switch (event)
{
case GF_EVENT_CHILD_UP:
{
nfs_startup_subvolume (this, subvol);
- if ((nfs->upsubvols == nfs->allsubvols) &&
- (!nfs->subvols_started)) {
- nfs->subvols_started = 1;
- gf_log (GF_NFS, GF_LOG_TRACE, "All children up,"
- " starting RPC");
- ret = nfs_init_versions (nfs, this);
- if (ret == -1)
- gf_log (GF_NFS, GF_LOG_CRITICAL,
- "Failed to initialize "
- "protocols");
- }
break;
}
@@ -615,6 +822,12 @@ notify (xlator_t *this, int32_t event, void *data, ...)
default_notify (this, GF_EVENT_PARENT_UP, data);
break;
}
+
+ case GF_EVENT_CHILD_DOWN:
+ {
+ nfs_disable_subvolume (this, subvol);
+ break;
+ }
}
return 0;