diff --git a/NEWS b/NEWS
index 50373e3335b9a7c2eacc4b83a01c044be877c27c..d8cfeffa5caacbce2acfdb3307f791904063ef87 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ documents those changes that are of interest to users and admins.
 ==============================
  -- Added new partition option AllocNodes which controls the hosts from 
     which jobs can be submitted to this partition. From Matthieu Hautreux, CEA.
+ -- Better support the --contiguous option for job allocations.
 
 * Changes in SLURM 1.4.0-pre12
 ==============================
diff --git a/doc/man/man1/salloc.1 b/doc/man/man1/salloc.1
index d074dbe089a11a4d64bacafd45db1a7feec0a7bd..d1784ba23fffd8230bd3cb6a502e253eb5bf6ce9 100644
--- a/doc/man/man1/salloc.1
+++ b/doc/man/man1/salloc.1
@@ -1,4 +1,4 @@
-.TH "salloc" "1" "SLURM 2.0" "February 2009" "SLURM Commands"
+.TH "salloc" "1" "SLURM 2.0" "April 2009" "SLURM Commands"
 .SH "NAME"
 .LP 
 salloc \- Obtain a SLURM job allocation (a set of nodes), execute a command, 
@@ -126,8 +126,9 @@ An arbitrary comment.
 
 .TP
 \fB\-\-contiguous\fR
-Demand a contiguous range of nodes. The default is "yes". Specify
-\-\-contiguous=no if a contiguous range of nodes is not required.
+If set, then the allocated nodes must form a contiguous set.
+Not honored with the \fBtopology/tree\fR or \fBtopology/3d_torus\fR
+plugins, both of which can modify the node ordering.  
 
 .TP
 \fB\-\-cpu_bind\fR=[{\fIquiet,verbose\fR},]\fItype\fR
diff --git a/doc/man/man1/sbatch.1 b/doc/man/man1/sbatch.1
index 763541bf7740b11228a1f0c04602ff950570e4e4..5239532eb6df52d2323f4512348f3c5afcf78bd2 100644
--- a/doc/man/man1/sbatch.1
+++ b/doc/man/man1/sbatch.1
@@ -1,4 +1,4 @@
-.TH "sbatch" "1" "SLURM 2.0" "March 2009" "SLURM Commands"
+.TH "sbatch" "1" "SLURM 2.0" "April 2009" "SLURM Commands"
 .SH "NAME"
 .LP 
 sbatch \- Submit a batch script to SLURM.
@@ -203,8 +203,9 @@ An arbitrary comment.
 
 .TP
 \fB\-\-contiguous\fR
-Demand a contiguous range of nodes. The default is "yes". Specify
-\-\-contiguous=no if a contiguous range of nodes is not required.
+If set, then the allocated nodes must form a contiguous set.
+Not honored with the \fBtopology/tree\fR or \fBtopology/3d_torus\fR
+plugins, both of which can modify the node ordering.
 
 .TP 
 \fB\-D\fR, \fB\-\-workdir\fR[=]<\fIdirectory\fR>
diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index 726169230656503e150bd93a3d713e6382d939ef..2b6434f9a04c23ca1f086fa6a6886b990ac21254 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -1,4 +1,4 @@
-.TH SRUN "1" "March 2009" "srun 2.0" "slurm components"
+.TH SRUN "1" "April 2009" "srun 2.0" "slurm components"
 
 .SH "NAME"
 srun \- run parallel jobs
@@ -265,8 +265,10 @@ An arbitrary comment.
 
 .TP
 \fB\-\-contiguous\fR
-Demand a contiguous range of nodes. The default is "yes". Specify
-\-\-contiguous=no if a contiguous range of nodes is not a constraint.
+If set, then the job's allocated nodes must form a contiguous set.
+Not honored with the \fBtopology/tree\fR or \fBtopology/3d_torus\fR
+plugins, both of which can modify the node ordering.
+Not honored for a job step's allocation.
 
 .TP
 \fB\-\-core\fR=\fItype\fR
diff --git a/src/plugins/select/cons_res/job_test.c b/src/plugins/select/cons_res/job_test.c
index 8aa93c5f93dd18480d2511d3c19e756fe0daacde..7e003273c91d3b1393a55e37399176d33e6134de 100644
--- a/src/plugins/select/cons_res/job_test.c
+++ b/src/plugins/select/cons_res/job_test.c
@@ -1043,7 +1043,13 @@ static int _eval_nodes(struct job_record *job_ptr, bitstr_t *node_map,
 		best_fit_req = -1;	/* first required node, -1 if none */
 		for (i = 0; i < consec_index; i++) {
 			if (consec_nodes[i] == 0)
-				continue;
+				continue;	/* no usable nodes here */
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap &&
+			    (consec_req[i] == -1))
+				break;  /* not required nodes */
+
 			sufficient = (consec_cpus[i] >= rem_cpus) &&
 				     _enough_nodes(consec_nodes[i], rem_nodes,
 						   min_nodes, req_nodes);
@@ -1064,6 +1070,23 @@ static int _eval_nodes(struct job_record *job_ptr, bitstr_t *node_map,
 				best_fit_req = consec_req[i];
 				best_fit_sufficient = sufficient;
 			}
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap) {
+				/* Must wait for all required nodes to be 
+				 * in a single consecutive block */
+				int j, other_blocks = 0;
+				for (j = (i+1); j < consec_index; j++) {
+					if (consec_req[j] != -1) {
+						other_blocks = 1;
+						break;
+					}
+				}
+				if (other_blocks) {
+					best_fit_nodes = 0;
+					break;
+				}
+			}
 		}
 		if (best_fit_nodes == 0)
 			break;
diff --git a/src/plugins/select/linear/select_linear.c b/src/plugins/select/linear/select_linear.c
index 76d87c29dcbb215661015a5196bf772c3b61437b..14acb9436bbddbe5993678de2aa35f71a9d5db97 100644
--- a/src/plugins/select/linear/select_linear.c
+++ b/src/plugins/select/linear/select_linear.c
@@ -978,10 +978,16 @@ static int _job_test(struct job_record *job_ptr, bitstr_t *bitmap,
 		best_fit_req = -1;	/* first required node, -1 if none */
 		for (i = 0; i < consec_index; i++) {
 			if (consec_nodes[i] == 0)
-				continue;
-			sufficient = (consec_cpus[i] >= rem_cpus)
-			&& _enough_nodes(consec_nodes[i], rem_nodes,
-					 min_nodes, req_nodes);
+				continue;	/* no usable nodes here */
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap &&
+			    (consec_req[i] == -1))
+				break;	/* not required nodes */
+
+			sufficient = (consec_cpus[i] >= rem_cpus) &&
+				     _enough_nodes(consec_nodes[i], rem_nodes,
+						   min_nodes, req_nodes);
 
 			/* if first possibility OR */
 			/* contains required nodes OR */
@@ -1000,6 +1006,23 @@ static int _job_test(struct job_record *job_ptr, bitstr_t *bitmap,
 				best_fit_req = consec_req[i];
 				best_fit_sufficient = sufficient;
 			}
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap) {
+				/* Must wait for all required nodes to be 
+				 * in a single consecutive block */
+				int j, other_blocks = 0;
+				for (j = (i+1); j < consec_index; j++) {
+					if (consec_req[j] != -1) {
+						other_blocks = 1;
+						break;
+					}
+				}
+				if (other_blocks) {
+					best_fit_nodes = 0;
+					break;
+				}
+			}
 		}
 		if (best_fit_nodes == 0)
 			break;