diff --git a/glib/gutils.c b/glib/gutils.c
index eb44f179f..b26a52820 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -2171,6 +2171,8 @@ g_format_size (guint64 size)
  *     suffixes. IEC units should only be used for reporting things with
  *     a strong "power of 2" basis, like RAM sizes or RAID stripe sizes.
  *     Network and storage sizes should be reported in the normal SI units.
+ * @G_FORMAT_SIZE_BITS: use bits units. Cannot be used with
+ * @G_FORMAT_SIZE_IEC_UNITS.
  *
  * Flags to modify the format of the string returned by g_format_size_full().
  */
@@ -2199,6 +2201,8 @@ g_format_size_full (guint64          size,
 {
   GString *string;
 
+  g_assert(!(flags & (G_FORMAT_SIZE_IEC_UNITS | G_FORMAT_SIZE_BITS)));
+
   string = g_string_new (NULL);
 
   if (flags & G_FORMAT_SIZE_IEC_UNITS)
@@ -2228,6 +2232,34 @@ g_format_size_full (guint64          size,
       else
         g_string_printf (string, _("%.1f EiB"), (gdouble) size / (gdouble) EXBIBYTE_FACTOR);
     }
+  else if (flags & G_FORMAT_SIZE_BITS)
+    {
+      if (size < KILOBYTE_FACTOR)
+        {
+          g_string_printf (string,
+                           g_dngettext(GETTEXT_PACKAGE, "%u bit", "%u bits", (guint) size),
+                           (guint) size);
+          flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
+        }
+
+      else if (size < MEGABYTE_FACTOR)
+        g_string_printf (string, _("%.1f kb"), (gdouble) size / (gdouble) KILOBYTE_FACTOR);
+
+      else if (size < GIGABYTE_FACTOR)
+        g_string_printf (string, _("%.1f Mb"), (gdouble) size / (gdouble) MEGABYTE_FACTOR);
+
+      else if (size < TERABYTE_FACTOR)
+        g_string_printf (string, _("%.1f Gb"), (gdouble) size / (gdouble) GIGABYTE_FACTOR);
+
+      else if (size < PETABYTE_FACTOR)
+        g_string_printf (string, _("%.1f Tb"), (gdouble) size / (gdouble) TERABYTE_FACTOR);
+
+      else if (size < EXABYTE_FACTOR)
+        g_string_printf (string, _("%.1f Pb"), (gdouble) size / (gdouble) PETABYTE_FACTOR);
+
+      else
+        g_string_printf (string, _("%.1f Eb"), (gdouble) size / (gdouble) EXABYTE_FACTOR);
+    }
   else
     {
       if (size < KILOBYTE_FACTOR)
@@ -2278,19 +2310,27 @@ g_format_size_full (guint64          size,
        */
       guint plural_form = size < 1000 ? size : size % 1000 + 1000;
 
-      /* Second problem: we need to translate the string "%u byte" and
-       * "%u bytes" for pluralisation, but the correct number format to
+      /* Second problem: we need to translate the string "%u byte/bit" and
+       * "%u bytes/bits" for pluralisation, but the correct number format to
        * use for a gsize is different depending on which architecture
        * we're on.
        *
-       * Solution: format the number separately and use "%s bytes" on
+       * Solution: format the number separately and use "%s bytes/bits" on
        * all platforms.
        */
       const gchar *translated_format;
       gchar *formatted_number;
 
-      /* Translators: the %s in "%s bytes" will always be replaced by a number. */
-      translated_format = g_dngettext(GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
+      if (flags & G_FORMAT_SIZE_BITS)
+        {
+          /* Translators: the %s in "%s bits" will always be replaced by a number. */
+          translated_format = g_dngettext(GETTEXT_PACKAGE, "%s bit", "%s bits", plural_form);
+        }
+      else
+        {
+          /* Translators: the %s in "%s bytes" will always be replaced by a number. */
+          translated_format = g_dngettext(GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
+        }
       /* XXX: Windows doesn't support the "'" format modifier, so we
        * must not use it there.  Instead, just display the number
        * without separation.  Bug #655336 is open until a solution is
diff --git a/glib/gutils.h b/glib/gutils.h
index 356c64370..d98325ef3 100644
--- a/glib/gutils.h
+++ b/glib/gutils.h
@@ -181,7 +181,8 @@ typedef enum
 {
   G_FORMAT_SIZE_DEFAULT     = 0,
   G_FORMAT_SIZE_LONG_FORMAT = 1 << 0,
-  G_FORMAT_SIZE_IEC_UNITS   = 1 << 1
+  G_FORMAT_SIZE_IEC_UNITS   = 1 << 1,
+  G_FORMAT_SIZE_BITS        = 2 << 1
 } GFormatSizeFlags;
 
 GLIB_AVAILABLE_IN_2_30
diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c
index 2fe22cc0e..4c21ba752 100644
--- a/glib/tests/fileutils.c
+++ b/glib/tests/fileutils.c
@@ -551,6 +551,22 @@ test_format_size_for_display (void)
   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_IEC_UNITS), "227.4 MiB");
   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_DEFAULT), "238.5 MB");
   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_LONG_FORMAT), "238.5 MB (238472938 bytes)");
+
+
+  check_string (g_format_size_full (0, G_FORMAT_SIZE_BITS), "0 bit");
+  check_string (g_format_size_full (1, G_FORMAT_SIZE_BITS), "1 bit");
+  check_string (g_format_size_full (2, G_FORMAT_SIZE_BITS), "2 bits");
+
+  check_string (g_format_size_full (2000ULL, G_FORMAT_SIZE_BITS), "2.0 kb");
+  check_string (g_format_size_full (2000ULL * 1000, G_FORMAT_SIZE_BITS), "2.0 Mb");
+  check_string (g_format_size_full (2000ULL * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Gb");
+  check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Tb");
+  check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Pb");
+  check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Eb");
+
+  check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS), "238.5 Mb");
+  check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_LONG_FORMAT), "238.5 Mb (238472938 bits)");
+
 }
 
 static void
