diff --git a/lib/backend.py b/lib/backend.py
index 51a06bbfaa3e28d3df162bf72f83e725ac674b8d..b18906738de9b4982164118120078aca7b037dc3 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -2443,7 +2443,7 @@ def OSEnvironment(instance, inst_os, debug=0):
   return result
 
 
-def BlockdevGrow(disk, amount, dryrun):
+def BlockdevGrow(disk, amount, dryrun, backingstore):
   """Grow a stack of block devices.
 
   This function is called recursively, with the childrens being the
@@ -2456,6 +2456,9 @@ def BlockdevGrow(disk, amount, dryrun):
   @type dryrun: boolean
   @param dryrun: whether to execute the operation in simulation mode
       only, without actually increasing the size
+  @param backingstore: whether to execute the operation on backing storage
+      only, or on "logical" storage only; e.g. DRBD is logical storage,
+      whereas LVM, file, RBD are backing storage
   @rtype: (status, result)
   @return: a tuple with the status of the operation (True/False), and
       the errors message if status is False
@@ -2466,7 +2469,7 @@ def BlockdevGrow(disk, amount, dryrun):
     _Fail("Cannot find block device %s", disk)
 
   try:
-    r_dev.Grow(amount, dryrun)
+    r_dev.Grow(amount, dryrun, backingstore)
   except errors.BlockDeviceError, err:
     _Fail("Failed to grow block device: %s", err, exc=True)
 
diff --git a/lib/bdev.py b/lib/bdev.py
index 6c16da4250f590ef9e1e7fd1bd93d45a2414c2f9..3bb3f115dd39a8e2748326493f3d20a113f07f98 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -338,7 +338,7 @@ class BlockDev(object):
     for child in self._children:
       child.SetInfo(text)
 
-  def Grow(self, amount, dryrun):
+  def Grow(self, amount, dryrun, backingstore):
     """Grow the block device.
 
     @type amount: integer
@@ -346,6 +346,9 @@ class BlockDev(object):
     @type dryrun: boolean
     @param dryrun: whether to execute the operation in simulation mode
         only, without actually increasing the size
+    @param backingstore: whether to execute the operation on backing storage
+        only, or on "logical" storage only; e.g. DRBD is logical storage,
+        whereas LVM, file, RBD are backing storage
 
     """
     raise NotImplementedError
@@ -768,10 +771,12 @@ class LogicalVolume(BlockDev):
       _ThrowError("Command: %s error: %s - %s", result.cmd, result.fail_reason,
                   result.output)
 
-  def Grow(self, amount, dryrun):
+  def Grow(self, amount, dryrun, backingstore):
     """Grow the logical volume.
 
     """
+    if not backingstore:
+      return
     if self.pe_size is None or self.stripe_count is None:
       if not self.Attach():
         _ThrowError("Can't attach to LV during Grow()")
@@ -2070,7 +2075,7 @@ class DRBD8(BaseDRBD):
     cls._InitMeta(aminor, meta.dev_path)
     return cls(unique_id, children, size, params)
 
-  def Grow(self, amount, dryrun):
+  def Grow(self, amount, dryrun, backingstore):
     """Resize the DRBD device and its backing storage.
 
     """
@@ -2078,9 +2083,10 @@ class DRBD8(BaseDRBD):
       _ThrowError("drbd%d: Grow called while not attached", self._aminor)
     if len(self._children) != 2 or None in self._children:
       _ThrowError("drbd%d: cannot grow diskless device", self.minor)
-    self._children[0].Grow(amount, dryrun)
-    if dryrun:
-      # DRBD does not support dry-run mode, so we'll return here
+    self._children[0].Grow(amount, dryrun, backingstore)
+    if dryrun or backingstore:
+      # DRBD does not support dry-run mode and is not backing storage,
+      # so we'll return here
       return
     result = utils.RunCmd(["drbdsetup", self.dev_path, "resize", "-s",
                            "%dm" % (self.size + amount)])
@@ -2163,12 +2169,14 @@ class FileStorage(BlockDev):
     # TODO: implement rename for file-based storage
     _ThrowError("Rename is not supported for file-based storage")
 
-  def Grow(self, amount, dryrun):
+  def Grow(self, amount, dryrun, backingstore):
     """Grow the file
 
     @param amount: the amount (in mebibytes) to grow with
 
     """
+    if not backingstore:
+      return
     # Check that the file exists
     self.Assemble()
     current_size = self.GetActualSize()
@@ -2339,7 +2347,7 @@ class PersistentBlockDevice(BlockDev):
     """
     pass
 
-  def Grow(self, amount, dryrun):
+  def Grow(self, amount, dryrun, backingstore):
     """Grow the logical volume.
 
     """
@@ -2605,7 +2613,7 @@ class RADOSBlockDevice(BlockDev):
     """
     pass
 
-  def Grow(self, amount, dryrun):
+  def Grow(self, amount, dryrun, backingstore):
     """Grow the Volume.
 
     @type amount: integer
@@ -2615,6 +2623,8 @@ class RADOSBlockDevice(BlockDev):
         only, without actually increasing the size
 
     """
+    if not backingstore:
+      return
     if not self.Attach():
       _ThrowError("Can't attach to rbd device during Grow()")
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 3a22ef53a4e83dff317f45f620a304b871196dc6..e5f0451f780d6fab3e32d6d62d859b699c1f1305 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -11683,23 +11683,23 @@ class LUInstanceGrowDisk(LogicalUnit):
     for node in instance.all_nodes:
       self.cfg.SetDiskID(disk, node)
       result = self.rpc.call_blockdev_grow(node, (disk, instance), self.delta,
-                                           True)
+                                           True, True)
       result.Raise("Grow request failed to node %s" % node)
 
     # We know that (as far as we can test) operations across different
-    # nodes will succeed, time to run it for real
+    # nodes will succeed, time to run it for real on the backing storage
     for node in instance.all_nodes:
       self.cfg.SetDiskID(disk, node)
       result = self.rpc.call_blockdev_grow(node, (disk, instance), self.delta,
-                                           False)
+                                           False, True)
       result.Raise("Grow request failed to node %s" % node)
 
-      # TODO: Rewrite code to work properly
-      # DRBD goes into sync mode for a short amount of time after executing the
-      # "resize" command. DRBD 8.x below version 8.0.13 contains a bug whereby
-      # calling "resize" in sync mode fails. Sleeping for a short amount of
-      # time is a work-around.
-      time.sleep(5)
+    # And now execute it for logical storage, on the primary node
+    node = instance.primary_node
+    self.cfg.SetDiskID(disk, node)
+    result = self.rpc.call_blockdev_grow(node, (disk, instance), self.delta,
+                                         False, False)
+    result.Raise("Grow request failed to node %s" % node)
 
     disk.RecordGrow(self.delta)
     self.cfg.Update(instance, feedback_fn)
diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py
index 35c5a490c149644ddcd66ecd9cdf3e8e3efe67f1..2d2fcaca4b2732ceda35f2fb2f3a3b686d23a27c 100644
--- a/lib/rpc_defs.py
+++ b/lib/rpc_defs.py
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -393,7 +393,9 @@ _BLOCKDEV_CALLS = [
     ("cf_bdev", ED_SINGLE_DISK_DICT_DP, None),
     ("amount", None, None),
     ("dryrun", None, None),
-    ], None, None, "Request a snapshot of the given block device"),
+    ("backingstore", None, None),
+    ], None, None, "Request growing of the given block device by a"
+   " given amount"),
   ("blockdev_export", SINGLE, None, TMO_1DAY, [
     ("cf_bdev", ED_SINGLE_DISK_DICT_DP, None),
     ("dest_node", None, None),
diff --git a/lib/server/noded.py b/lib/server/noded.py
index d95680a55655827b119abd7b0bc1887ed75cd375..ae7be3216c13449ac06a32b4551cd27a04f85b54 100644
--- a/lib/server/noded.py
+++ b/lib/server/noded.py
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
+# Copyright (C) 2006, 2007, 2010, 2011, 2012 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -332,10 +332,14 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     """Grow a stack of devices.
 
     """
+    if len(params) < 4:
+      raise ValueError("Received only 3 parameters in blockdev_grow,"
+                       " old master?")
     cfbd = objects.Disk.FromDict(params[0])
     amount = params[1]
     dryrun = params[2]
-    return backend.BlockdevGrow(cfbd, amount, dryrun)
+    backingstore = params[3]
+    return backend.BlockdevGrow(cfbd, amount, dryrun, backingstore)
 
   @staticmethod
   def perspective_blockdev_close(params):