diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 2658d45..93f509b 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -1073,6 +1073,7 @@ g_drive_can_start
 g_drive_can_start_degraded
 g_drive_can_stop
 g_drive_can_poll_for_media
+g_drive_get_is_locked
 g_drive_poll_for_media
 g_drive_poll_for_media_finish
 g_drive_has_media
@@ -1086,6 +1087,12 @@ g_drive_start
 g_drive_start_finish
 g_drive_stop
 g_drive_stop_finish
+g_drive_obtain_lock_sync
+g_drive_obtain_lock_async
+g_drive_obtain_lock_finish
+g_drive_release_lock_sync
+g_drive_release_lock_async
+g_drive_release_lock_finish
 g_drive_enumerate_identifiers
 g_drive_get_identifier
 <SUBSECTION Standard>
diff --git a/gio/gdrive.c b/gio/gdrive.c
index 5d6efdc..8ea9d75 100644
--- a/gio/gdrive.c
+++ b/gio/gdrive.c
@@ -27,7 +27,7 @@
 #include "gasyncresult.h"
 #include "gioerror.h"
 #include "glibintl.h"
-
+#include "gcancellable.h"
 
 /**
  * SECTION:gdrive
@@ -865,3 +865,188 @@ g_drive_stop_finish (GDrive        *drive,
 
   return (* iface->stop_finish) (drive, result, error);
 }
+
+/**
+ * g_drive_obtain_lock_async:
+ * @drive: a #GDrive.
+ * @flags: #GDriveLockFlags.
+ * @reason: (allow-none): a string specifying the reason why the @drive is locked.
+ *          It should be kept simple and straight to the point. %NULL to ignore.
+ * @cancellable: optional #GCancellable or %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: the data to pass to callback function.
+ *
+ * Tries to obtain asynchronously an (advisory) lock on the drive.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * g_drive_obtain_lock_finish() to get the result of the operation.
+ *
+ * Since: 2.26
+ */
+void
+g_drive_obtain_lock (GDrive              *drive,
+                     GDriveLockFlags      flags,
+                     const gchar         *reason,
+                     GCancellable        *cancellable,
+                     GAsyncReadyCallback  callback,
+                     gpointer             user_data)
+{
+  GDriveIface *iface;
+
+  g_return_if_fail (G_IS_DRIVE (drive));
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->obtain_lock == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   _("drive doesn't implement asynchronous locking"));
+      return;
+    }
+
+  (* iface->obtain_lock) (drive, flags, reason, cancellable, callback, user_data);
+}
+
+/**
+ * g_drive_obtain_lock_finish:
+ * @drive: a #GDrive.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes trying to obtain a lock on a drive.
+ *
+ * If the drive is already locked by another application, the code will be
+ * @G_IO_ERROR_LOCKED and the message will be set to the reason given
+ * by the application currently holding the lock.
+ *
+ * Returns: 0 on error. Otherwise a cookie that must be saved to unlock the
+ *          drive later with g_drive_release_lock().
+ *
+ * Since: 2.26
+ */
+guint
+g_drive_obtain_lock_finish (GDrive        *drive,
+                            GAsyncResult  *result,
+                            GError       **error)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), 0);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), 0);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return 0;
+    }
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  return (* iface->obtain_lock_finish) (drive, result, error);
+}
+
+/**
+ * g_drive_release_lock_async:
+ * @drive: a #GDrive.
+ * @cookie: the cookie returned by g_drive_obtain_lock() or
+ *          g_drive_obtain_lock_finish() on success.
+ * @cancellable: optional #GCancellable or NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: the data to pass to @callback function.
+ *
+ * Asynchronously releases the lock that was held by the caller on the drive.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * g_drive_release_lock_finish() to get the result of the operation.
+ *
+ * Since: 2.26
+ */
+void
+g_drive_release_lock (GDrive              *drive,
+                      guint                cookie,
+                      GCancellable        *cancellable,
+                      GAsyncReadyCallback  callback,
+                      gpointer             user_data)
+{
+  GDriveIface *iface;
+
+  g_return_if_fail (G_IS_DRIVE (drive));
+  g_return_if_fail (cookie != 0);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->release_lock == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   _("drive doesn't implement releasing lock asynchronously"));
+      return;
+    }
+
+  (* iface->release_lock) (drive, cookie, cancellable, callback, user_data);
+}
+
+/**
+ * g_drive_release_lock_finish:
+ * @drive: a #GDrive.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL.
+ *
+ * Finishes releasing a lock held on a drive.
+ *
+ * Returns: %TRUE if the lock has been released successfully.
+ *     %FALSE otherwise.
+ *
+ * Since: 2.26
+ */
+gboolean
+g_drive_release_lock_finish (GDrive        *drive,
+                             GAsyncResult  *result,
+                             GError       **error)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return FALSE;
+    }
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  return (* iface->release_lock_finish) (drive, result, error);
+}
+
+/**
+ * g_drive_get_is_locked:
+ * @drive: a #GDrive.
+ *
+ * Checks whether @drive is currently locked.
+ *
+ * You can connect to GDrive::changed signal to check for changes and be
+ * notified when the drive gets locked or unlocked.
+ *
+ * Returns: %TRUE if the drive is currently locked, %FALSE otherwise.
+ *
+ * Since: 2.26
+ */
+gboolean
+g_drive_get_is_locked (GDrive *drive)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->is_locked == NULL)
+    return FALSE;
+
+  return (* iface->is_locked) (drive);
+}
diff --git a/gio/gdrive.h b/gio/gdrive.h
index b4bfc03..7b61b43 100644
--- a/gio/gdrive.h
+++ b/gio/gdrive.h
@@ -71,6 +71,11 @@ G_BEGIN_DECLS
  * @stop_button: Signal emitted when the physical stop button (if any) of a drive have been pressed. Since 2.22.
  * @eject_with_operation: Starts ejecting a #GDrive using a #GMountOperation. Since 2.22.
  * @eject_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22.
+ * @is_locked: Returns whether the #GDrive is currently locked. Since 2.26.
+ * @obtain_lock: Obtains a lock on the #GDrive. Since 2.26.
+ * @obtain_lock_finish: Finishes an obtain_lock operation. Since 2.26.
+ * @release_lock: Releases a lock on the #GDrive. Since 2.26.
+ * @release_lock_finish: Finishes a release_lock operation. Since 2.26.
  *
  * Interface for creating #GDrive implementations.
  */
@@ -139,6 +144,27 @@ struct _GDriveIface
   gboolean (* stop_finish)              (GDrive              *drive,
                                          GAsyncResult        *result,
                                          GError             **error);
+
+  gboolean (* is_locked)                (GDrive              *drive);
+  void     (* obtain_lock)              (GDrive              *drive,
+                                         GDriveLockFlags      flags,
+                                         const gchar         *reason,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data);
+  guint    (* obtain_lock_finish)       (GDrive              *drive,
+                                         GAsyncResult        *result,
+                                         GError             **error);
+
+  void     (* release_lock)             (GDrive              *drive,
+                                         guint                cookie,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data);
+  gboolean (* release_lock_finish)      (GDrive              *drive,
+                                         GAsyncResult        *result,
+                                         GError             **error);
+
   /* signal, not VFunc */
   void     (* stop_button)              (GDrive              *drive);
 
@@ -210,16 +236,34 @@ gboolean g_drive_stop_finish              (GDrive               *drive,
                                            GAsyncResult         *result,
                                            GError              **error);
 
-void        g_drive_eject_with_operation      (GDrive              *drive,
-                                               GMountUnmountFlags   flags,
-                                               GMountOperation     *mount_operation,
-                                               GCancellable        *cancellable,
-                                               GAsyncReadyCallback  callback,
-                                               gpointer             user_data);
-gboolean    g_drive_eject_with_operation_finish (GDrive            *drive,
-                                               GAsyncResult        *result,
-                                               GError             **error);
+void     g_drive_eject_with_operation      (GDrive              *drive,
+                                            GMountUnmountFlags   flags,
+                                            GMountOperation     *mount_operation,
+                                            GCancellable        *cancellable,
+                                            GAsyncReadyCallback  callback,
+                                            gpointer             user_data);
+gboolean g_drive_eject_with_operation_finish (GDrive            *drive,
+                                              GAsyncResult        *result,
+                                              GError             **error);
 
+gboolean g_drive_get_is_locked         (GDrive                 *drive);
+void     g_drive_obtain_lock           (GDrive                 *drive,
+                                        GDriveLockFlags         flags,
+                                        const gchar            *reason,
+                                        GCancellable           *cancellable,
+                                        GAsyncReadyCallback     callback,
+                                        gpointer                user_data);
+guint    g_drive_obtain_lock_finish    (GDrive                 *drive,
+                                        GAsyncResult           *result,
+                                        GError                **error);
+void     g_drive_release_lock          (GDrive                 *drive,
+                                        guint                   cookie,
+                                        GCancellable           *cancellable,
+                                        GAsyncReadyCallback     callback,
+                                        gpointer                user_data);
+gboolean g_drive_release_lock_finish   (GDrive                 *drive,
+                                        GAsyncResult           *result,
+                                        GError                **error);
 G_END_DECLS
 
 #endif /* __G_DRIVE_H__ */
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 15212ec..d38aeb1 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -295,6 +295,11 @@ g_drive_start_finish
 g_drive_can_stop
 g_drive_stop
 g_drive_stop_finish
+g_drive_get_is_locked
+g_drive_obtain_lock
+g_drive_obtain_lock_finish
+g_drive_release_lock
+g_drive_release_lock_finish
 #ifndef G_DISABLE_DEPRECATED
 g_drive_eject
 g_drive_eject_finish
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 10eedfd..5f1c02a 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -277,6 +277,19 @@ typedef enum {
 } GDriveStartStopType;
 
 /**
+ * GDriveLockFlags:
+ * @G_DRIVE_LOCK_NONE: No flags set.
+ *
+ * Flags used when trying to obtain a lock on a drive.
+ *
+ * Since 2.26
+ */
+typedef enum
+{
+  G_DRIVE_LOCK_NONE = 0,
+} GDriveLockFlags;
+
+/**
  * GFileCopyFlags:
  * @G_FILE_COPY_NONE: No flags set.
  * @G_FILE_COPY_OVERWRITE: Overwrite any existing files
@@ -444,6 +457,8 @@ typedef enum {
  * @G_IO_ERROR_PROXY_NEED_AUTH: Proxy server needs authentication. Since 2.26
  * @G_IO_ERROR_PROXY_NOT_ALLOWED: Proxy connection is not allowed by ruleset.
  *     Since 2.26
+ * @G_IO_ERROR_LOCKED: The resource (drive, volume, ...) is locked by another
+ *     process. Since 2.26.
  *
  * Error codes returned by GIO functions.
  *
@@ -492,7 +507,8 @@ typedef enum {
   G_IO_ERROR_PROXY_FAILED,
   G_IO_ERROR_PROXY_AUTH_FAILED,
   G_IO_ERROR_PROXY_NEED_AUTH,
-  G_IO_ERROR_PROXY_NOT_ALLOWED
+  G_IO_ERROR_PROXY_NOT_ALLOWED,
+  G_IO_ERROR_LOCKED,
 } GIOErrorEnum;
 
 
