diff options
Diffstat (limited to 'api/src/glfs-master.c')
| -rw-r--r-- | api/src/glfs-master.c | 45 | 
1 files changed, 38 insertions, 7 deletions
diff --git a/api/src/glfs-master.c b/api/src/glfs-master.c index e6c46e3610b..09a92b7f060 100644 --- a/api/src/glfs-master.c +++ b/api/src/glfs-master.c @@ -22,26 +22,57 @@  #include "xlator.h"  #include "glusterfs.h" +  #include "glfs-internal.h"  int  glfs_graph_setup (struct glfs *fs, glusterfs_graph_t *graph)  { -	if (fs->active_subvol == graph->top) -		return 0; +	xlator_t      *new_subvol = NULL; +	xlator_t      *old_subvol = NULL; +	inode_table_t *itable = NULL; +	int            ret = -1; + +	new_subvol = graph->top; +	/* This is called in a bottom-up context, it should specifically +	   NOT be glfs_lock() +	*/  	pthread_mutex_lock (&fs->mutex);  	{ -		fs->active_subvol = graph->top; -		pthread_cond_broadcast (&fs->cond); +		if (new_subvol->switched || +		    new_subvol == fs->active_subvol || +		    new_subvol == fs->next_subvol) { +			/* Spurious CHILD_UP event on old graph */ +			ret = 0; +			goto unlock; +		} + +		if (!new_subvol->itable) { +			itable = inode_table_new (131072, new_subvol); +			if (!itable) { +				errno = ENOMEM; +				ret = -1; +				goto unlock; +			} + +			new_subvol->itable = itable; +		} + +		old_subvol = fs->next_subvol; +		fs->next_subvol = new_subvol; +		fs->next_subvol->winds++; /* first ref */ +		ret = 0;  	} +unlock:  	pthread_mutex_unlock (&fs->mutex); -	gf_log ("glfs-master", GF_LOG_INFO, "switched to graph %s (%d)", -		uuid_utoa ((unsigned char *)graph->graph_uuid), graph->id); +	if (old_subvol) +		/* wasn't picked up so far, skip */ +		glfs_subvol_done (fs, old_subvol); -	return 0; +	return ret;  }  | 
