diff --git a/pyanaconda/constants.py b/pyanaconda/constants.py
index cb25e69..c083322 100644
--- a/pyanaconda/constants.py
+++ b/pyanaconda/constants.py
@@ -31,25 +31,6 @@ DISPATCH_FORWARD = 1
 DISPATCH_DEFAULT = None
 DISPATCH_WAITING = 2
 
-# different types of partition requests
-# REQUEST_PREEXIST is a placeholder for a pre-existing partition on the system
-# REQUEST_NEW is a request for a partition which will be automatically
-#              created based on various constraints on size, drive, etc
-# REQUEST_RAID is a request for a raid device
-# REQUEST_PROTECTED is a preexisting partition which can't change
-#              (harddrive install, harddrive with the isos on it)
-#
-REQUEST_PREEXIST = 1
-REQUEST_NEW = 2
-REQUEST_RAID = 4
-REQUEST_PROTECTED = 8
-REQUEST_VG = 16 # volume group
-REQUEST_LV = 32 # logical volume
-
-# XXX this is made up and used by the size spinner; should just be set with
-# a callback
-MAX_PART_SIZE = 1024*1024*1024
-
 # install key related constants
 SKIP_KEY = -50
 
@@ -64,8 +45,6 @@ productArch = product.productArch
 bugzillaUrl = product.bugUrl
 isFinal = product.isFinal
 
-lvmErrorOutput = "/tmp/lvmout"
-
 exceptionText = _("An unhandled exception has occurred.  This "
                   "is most likely a bug.  Please save a copy of "
                   "the detailed exception and file a bug report")
diff --git a/pyanaconda/iw/partition_dialog_gui.py b/pyanaconda/iw/partition_dialog_gui.py
index d05bfdb..20e864d 100644
--- a/pyanaconda/iw/partition_dialog_gui.py
+++ b/pyanaconda/iw/partition_dialog_gui.py
@@ -35,6 +35,26 @@ from pyanaconda.partIntfHelpers import *
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
 
+def max_part_size(storage, request):
+    max_size = 0
+
+    if request.req_start_sector is not None:
+        max_len = request.end_sector - request.start_sector + 1
+        sector_size = request.req_disks[0].format.partedDevice.sectorSize
+        max_size = (max_len * sector_size) / (1024.0 * 1024.0)
+    else:
+        disks = request.req_disks
+        if not disks:
+            disks = storage.partitioned[:]
+
+        for disk in disks:
+            sector_size = disk.format.partedDevice.sectorSize
+            max_sectors = disk.format.partedDisk.maxPartitionLength
+            max_size = max(max_size,
+                           (max_sectors * sector_size)/(1024.0 * 1024.0))
+
+    return max_size
+
 class PartitionEditor:
     def sizespinchangedCB(self, widget, fillmaxszsb):
 	size = widget.get_value_as_int()
@@ -65,7 +85,8 @@ class PartitionEditor:
 				      label=_("Fill all space _up "
 					      "to (MB):"))
 	maxsizeAdj = gtk.Adjustment(value = 1, lower = 1,
-				    upper = MAX_PART_SIZE, step_incr = 1)
+				    upper=max_part_size(self.storage, request),
+                                    step_incr = 1)
 	fillmaxszsb = gtk.SpinButton(maxsizeAdj, digits = 0)
 	fillmaxszsb.set_property('numeric', True)
 	fillunlimrb = gtk.RadioButton(group=fixedrb,
@@ -87,9 +108,13 @@ class PartitionEditor:
 	    fixedrb.set_active(1)
 
 	sizeoptiontable.attach(fixedrb, 0, 1, 0, 1)
-	sizeoptiontable.attach(fillmaxszrb, 0, 1, 1, 2)
-	sizeoptiontable.attach(fillmaxszsb, 1, 2, 1, 2)
-	sizeoptiontable.attach(fillunlimrb, 0, 1, 2, 3)
+
+        sizeoptiontable.attach(fillmaxszrb, 0, 1, 1, 2)
+        sizeoptiontable.attach(fillmaxszsb, 1, 2, 1, 2)
+        sizeoptiontable.attach(fillunlimrb, 0, 1, 2, 3)
+
+        if request.req_start_sector is not None:
+            sizeoptionable.set_sensitive(0)
 
 	frame.add(sizeoptiontable)
 
@@ -510,7 +535,9 @@ class PartitionEditor:
             lbl = createAlignedLabel(_("_Size (MB):"))
             maintable.attach(lbl, 0, 1, row, row + 1)
             sizeAdj = gtk.Adjustment(value = 1, lower = 1,
-                                     upper = MAX_PART_SIZE, step_incr = 1)
+                                     upper = max_part_size(self.storage,
+                                                           self.origrequest),
+                                     step_incr = 1)
             self.sizespin = gtk.SpinButton(sizeAdj, digits = 0)
             self.sizespin.set_property('numeric', True)
 
@@ -553,7 +580,8 @@ class PartitionEditor:
                 self.primonlycheckbutton.set_active(1)
 
             # only show if we have something other than primary
-            if self.storage.extendedPartitionsSupported():
+            if self.storage.extendedPartitionsSupported() and \
+               not self.origrequest.req_start_sector:
                 maintable.attach(self.primonlycheckbutton, 0, 2, row, row+1)
                 row = row + 1
 
diff --git a/pyanaconda/iw/partition_gui.py b/pyanaconda/iw/partition_gui.py
index c62d0a6..0c037e5 100644
--- a/pyanaconda/iw/partition_gui.py
+++ b/pyanaconda/iw/partition_gui.py
@@ -49,6 +49,7 @@ from pyanaconda.partIntfHelpers import *
 from pyanaconda.constants import *
 from partition_ui_helpers_gui import *
 from pyanaconda.storage.partitioning import doPartitioning
+from pyanaconda.storage.partitioning import addPartitionWithStartSector
 from pyanaconda.storage.devicelibs import lvm
 from pyanaconda.storage.devices import devicePathToName, PartitionDevice
 from pyanaconda.storage.devices import deviceNameToDiskByPath
@@ -414,7 +415,7 @@ class DiskStripeGraph(StripeGraph):
                 partName = devicePathToName(part.getDeviceNodeName())
                 o_part = self.storage.devicetree.getDeviceByName(partName)
             else:
-                o_part = None
+                o_part = (part.geometry.start, part.geometry.end)
 
             slice = Slice(stripe, partstr, stype, xoffset, xlength,
                     dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
@@ -1109,8 +1110,8 @@ class PartitionWindow(InstallWindow):
             return
 
         # The selected slice is a free slice if the object contained in it is
-        # None.
-        if sel_slice.obj != None:
+        # an int.
+        if not isinstance(sel_slice.obj, tuple):
             # This is not a free slice, we should call treeActivateCB
             return self.treeActivateCB()
         else:
@@ -1125,7 +1126,17 @@ class PartitionWindow(InstallWindow):
             stripe_dev = disp_stripe.obj
             if stripe_dev.partitioned:
                 tempformat = self.storage.defaultFSType
-                device = self.storage.newPartition(fmt_type=tempformat)
+
+                # Edit the partition here, but no growing.
+                # Add it directly instead of calling doPartitioning.
+                size = (stripe_dev.partedDevice.sectorSize * (sel_slice.obj[1] - sel_slice.obj[0] + 1)) / (1024.0 * 1024.0)
+                device = self.storage.newPartition(fmt_type=tempformat,
+                                                   size=size,
+                                                   parents=[stripe_dev])
+
+                device.req_start_sector = sel_slice.obj[0]
+                device.req_end_sector = sel_slice.obj[1]
+
                 self.editPartition(device, isNew = True)
 
             elif isinstance(stripe_dev, storage.LVMVolumeGroupDevice):
@@ -1645,6 +1656,10 @@ class PartitionWindow(InstallWindow):
                 # XXX we should handle exceptions here
                 self.anaconda.storage.devicetree.registerAction(action)
 
+            if device.req_start_sector and actions:
+                # add this partition now
+                addPartitionWithStartSector(device, self.anaconda.storage)
+
             if self.refresh(justRedraw=not actions):
                 # autopart failed -- cancel the actions and try to get
                 # back to previous state
diff --git a/pyanaconda/storage/devices.py b/pyanaconda/storage/devices.py
index eac7eb7..99617b7 100644
--- a/pyanaconda/storage/devices.py
+++ b/pyanaconda/storage/devices.py
@@ -1071,6 +1071,8 @@ class PartitionDevice(StorageDevice):
         self.req_base_size = 0
         self.req_max_size = 0
         self.req_base_weight = 0
+        self.req_start_sector = None
+        self.req_end_sector = None
 
         self._bootable = False
 
diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py
index 487ec81..940619c 100644
--- a/pyanaconda/storage/partitioning.py
+++ b/pyanaconda/storage/partitioning.py
@@ -801,6 +801,47 @@ def removeNewPartitions(disks, partitions):
             log.debug("removing empty extended partition from %s" % disk.name)
             disk.format.partedDisk.removePartition(extended)
 
+def addPartitionWithStartSector(request):
+    """ Add a partition to disklabel given a starting sector.
+
+        If the partition has a req_start_sector it should also have a single
+        disk in req_disks and it should not be growable.
+
+        Return the partition we just added.
+    """
+    disk = request.req_disks[0]
+    disklabel = disk.format
+
+    # figure out the free region the geometry is in
+    free_list = getFreeRegions([disk])
+    free = None
+    for f in free_list:
+        if free.containsSector(request.req_start_sector):
+            free = f
+            break
+
+    if not free:
+        raise PartitioningError("Failed to identify free region on disk %s"
+                                "containing sector %d"
+                                % (disk.name, request.req_start_sector))
+
+    # figure out the partition type based on that and whatever else
+    # FIXME: for now, this is not aware of extended/logical partitions
+    if disklabel.partedDisk.primaryPartitionCount >= disklabel.partedDisk.maxPrimaryPartitionCount:
+        raise PartitioningError("I don't know or care about logical/extended partitions")
+
+    partition = addPartition(disklabel, free, parted.PARTITION_NORMAL,
+                             request.size)
+
+    # this one sets the name
+    request.partedPartition = partition
+    request.disk = disk
+
+    # parted modifies the partition in the process of adding it to
+    # the disk, so we need to grab the latest version...
+    partition = disklabel.partedDisk.getPartitionByPath(_part.path)
+    request.partedPartition = partition
+
 def addPartition(disklabel, free, part_type, size):
     """ Return new partition after adding it to the specified disk.
 
@@ -965,6 +1006,10 @@ def doPartitioning(storage, bootloader=None):
             partitions.remove(part)
             continue
 
+        if part.req_start_sector:
+            # requests with a start sector have already been allocated
+            partitions.remove(part)
+
         if not part.exists:
             # start over with flexible-size requests
             part.req_size = part.req_base_size
