diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
index 1746bd8..e098dec 100644
--- a/daemon/gvfsbackend.c
+++ b/daemon/gvfsbackend.c
@@ -268,6 +268,24 @@ g_vfs_backend_get_daemon (GVfsBackend *backend)
   return backend->priv->daemon;
 }
 
+gint
+g_vfs_backend_get_n_active_channels (GVfsBackend *backend)
+{
+  return g_vfs_daemon_get_n_channel_sources (backend->priv->daemon);
+}
+
+void
+g_vfs_backend_close_active_channels (GVfsBackend *backend)
+{
+  GList *l, *channels;
+
+  channels = g_vfs_daemon_get_channel_sources (backend->priv->daemon);
+  for (l = channels; l; l = l->next)
+    {
+      g_vfs_channel_close (G_VFS_CHANNEL (l->data));
+    }
+  g_list_free (channels);
+}
 
 void
 g_vfs_backend_set_display_name (GVfsBackend *backend,
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index c99d18b..e0915ee 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -94,9 +94,11 @@ struct _GVfsBackendClass
    */
 
   void     (*unmount)           (GVfsBackend *backend,
-				 GVfsJobUnmount *job);
+				 GVfsJobUnmount *job,
+				 GMountUnmountFlags flags);
   gboolean (*try_unmount)       (GVfsBackend *backend,
-				 GVfsJobUnmount *job);
+				 GVfsJobUnmount *job,
+				 GMountUnmountFlags flags);
   void     (*mount)             (GVfsBackend *backend,
 				 GVfsJobMount *job,
 				 GMountSpec *mount_spec,
@@ -399,6 +401,8 @@ const char *g_vfs_backend_get_stable_name                (GVfsBackend        *ba
 const char *g_vfs_backend_get_icon_name                  (GVfsBackend        *backend);
 GMountSpec *g_vfs_backend_get_mount_spec                 (GVfsBackend        *backend);
 GVfsDaemon *g_vfs_backend_get_daemon                     (GVfsBackend        *backend);
+gint        g_vfs_backend_get_n_active_channels          (GVfsBackend        *backend);
+void        g_vfs_backend_close_active_channels          (GVfsBackend        *backend);
 
 void        g_vfs_backend_add_auto_info                  (GVfsBackend           *backend,
 							  GFileAttributeMatcher *matcher,
diff --git a/daemon/gvfsbackendarchive.c b/daemon/gvfsbackendarchive.c
index ae8f63d..d1a0880 100644
--- a/daemon/gvfsbackendarchive.c
+++ b/daemon/gvfsbackendarchive.c
@@ -561,7 +561,8 @@ do_mount (GVfsBackend *backend,
 
 static void
 do_unmount (GVfsBackend *backend,
-	    GVfsJobUnmount *job)
+	    GVfsJobUnmount *job, 
+	    GMountUnmountFlags flags)
 {
   GVfsBackendArchive *ba = G_VFS_BACKEND_ARCHIVE (backend);
 
diff --git a/daemon/gvfsbackendcdda.c b/daemon/gvfsbackendcdda.c
index 24ba0c2..8d19587 100644
--- a/daemon/gvfsbackendcdda.c
+++ b/daemon/gvfsbackendcdda.c
@@ -348,7 +348,8 @@ try_mount (GVfsBackend *backend,
 
 static void
 do_unmount (GVfsBackend *backend,
-            GVfsJobUnmount *job)
+            GVfsJobUnmount *job, 
+	    GMountUnmountFlags flags)
 {
   GError *error;
   GVfsBackendCdda *cdda_backend = G_VFS_BACKEND_CDDA (backend);
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
index 788c8ac..edf691b 100644
--- a/daemon/gvfsbackendftp.c
+++ b/daemon/gvfsbackendftp.c
@@ -1443,7 +1443,8 @@ try_mount (GVfsBackend *backend,
 
 static void
 do_unmount (GVfsBackend *   backend,
-	    GVfsJobUnmount *job)
+	    GVfsJobUnmount *job,
+	    GMountUnmountFlags flags)
 {
   GVfsBackendFtp *ftp = G_VFS_BACKEND_FTP (backend);
   FtpConnection *conn;
diff --git a/daemon/gvfsbackendgphoto2.c b/daemon/gvfsbackendgphoto2.c
index 44b0ca9..7a1e30e 100644
--- a/daemon/gvfsbackendgphoto2.c
+++ b/daemon/gvfsbackendgphoto2.c
@@ -1628,7 +1628,8 @@ try_mount (GVfsBackend *backend,
 
 static void
 do_unmount (GVfsBackend *backend,
-            GVfsJobUnmount *job)
+            GVfsJobUnmount *job, 
+	    GMountUnmountFlags flags)
 {
   GError *error;
   GVfsBackendGphoto2 *gphoto2_backend = G_VFS_BACKEND_GPHOTO2 (backend);
diff --git a/daemon/gvfsbackendlocaltest.c b/daemon/gvfsbackendlocaltest.c
index ac30adc..17b00b8 100644
--- a/daemon/gvfsbackendlocaltest.c
+++ b/daemon/gvfsbackendlocaltest.c
@@ -253,7 +253,7 @@ do_mount (GVfsBackend *backend,
 
 
 static void
-do_unmount (GVfsBackend *backend, GVfsJobUnmount *job)
+do_unmount (GVfsBackend *backend, GVfsJobUnmount *job, GMountUnmountFlags flags)
 {
   GVfsBackendLocalTest *op_backend;
 
diff --git a/daemon/gvfschannel.c b/daemon/gvfschannel.c
index 01c40e6..f87a547 100644
--- a/daemon/gvfschannel.c
+++ b/daemon/gvfschannel.c
@@ -702,3 +702,9 @@ g_vfs_channel_get_current_seq_nr (GVfsChannel *channel)
 {
   return channel->priv->current_job_seq_nr;
 }
+
+void
+g_vfs_channel_close (GVfsChannel *channel)
+{
+  g_vfs_channel_connection_closed (channel);
+}
diff --git a/daemon/gvfschannel.h b/daemon/gvfschannel.h
index f60b20a..399c9d0 100644
--- a/daemon/gvfschannel.h
+++ b/daemon/gvfschannel.h
@@ -80,6 +80,7 @@ void              g_vfs_channel_send_reply         (GVfsChannel
 						    GVfsDaemonSocketProtocolReply *reply,
 						    const void                    *data,
 						    gsize                          data_len);
+void              g_vfs_channel_close              (GVfsChannel                   *channel);
 guint32           g_vfs_channel_get_current_seq_nr (GVfsChannel                   *channel);
 
 /* TODO: i/o priority? */
diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c
index f9f5276..8d4bc37 100644
--- a/daemon/gvfsdaemon.c
+++ b/daemon/gvfsdaemon.c
@@ -40,6 +40,7 @@
 #include <gvfsdaemonprotocol.h>
 #include <gvfsdaemonutils.h>
 #include <gvfsjobmount.h>
+#include <gvfschannel.h>
 #include <gdbusutils.h>
 
 enum {
@@ -64,6 +65,7 @@ struct _GVfsDaemon
   GHashTable *registered_paths;
   GList *jobs;
   GList *job_sources;
+  guint n_channel_sources;
 
   guint exit_tag;
   
@@ -335,6 +337,9 @@ job_source_closed_callback (GVfsJobSource *job_source,
   g_signal_handlers_disconnect_by_func (job_source,
 					(GCallback)job_source_closed_callback,
 					daemon);
+
+  if (G_VFS_IS_CHANNEL (job_source))
+    daemon->n_channel_sources--;
   
   g_object_unref (job_source);
 
@@ -360,6 +365,33 @@ g_vfs_daemon_re_register_job_sources (GVfsDaemon *daemon)
   g_mutex_unlock (daemon->lock);
 }
 
+gint
+g_vfs_daemon_get_n_channel_sources (GVfsDaemon *daemon)
+{
+  return daemon->n_channel_sources;
+}
+
+GList *
+g_vfs_daemon_get_channel_sources (GVfsDaemon *daemon)
+{
+  GList *l, *retval = NULL;
+
+  if (daemon->n_channel_sources <= 0)
+    return NULL;
+  
+  g_mutex_lock (daemon->lock);
+
+  for (l = daemon->job_sources; l != NULL; l = l->next)
+    {
+      if (G_VFS_IS_CHANNEL (l->data))
+        retval = g_list_prepend (retval, l->data);
+    }
+  
+  g_mutex_unlock (daemon->lock);
+
+  return retval;
+}
+
 void
 g_vfs_daemon_add_job_source (GVfsDaemon *daemon,
 			     GVfsJobSource *job_source)
@@ -378,6 +410,9 @@ g_vfs_daemon_add_job_source (GVfsDaemon *daemon,
   g_signal_connect (job_source, "closed",
 		    (GCallback)job_source_closed_callback, daemon);
   
+  if (G_VFS_IS_CHANNEL (job_source))
+    daemon->n_channel_sources++;
+  
   g_mutex_unlock (daemon->lock);
 }
 
diff --git a/daemon/gvfsdaemon.h b/daemon/gvfsdaemon.h
index f40f216..3925dd5 100644
--- a/daemon/gvfsdaemon.h
+++ b/daemon/gvfsdaemon.h
@@ -51,25 +51,27 @@ struct _GVfsDaemonClass
 
 GType g_vfs_daemon_get_type (void) G_GNUC_CONST;
 
-GVfsDaemon *g_vfs_daemon_new             (gboolean                       main_daemon,
-					  gboolean                       replace);
-void        g_vfs_daemon_set_max_threads (GVfsDaemon                    *daemon,
-					  gint                           max_threads);
-void        g_vfs_daemon_add_job_source  (GVfsDaemon                    *daemon,
-					  GVfsJobSource                 *job_source);
-void        g_vfs_daemon_queue_job       (GVfsDaemon                    *daemon,
-					  GVfsJob                       *job);
-void        g_vfs_daemon_register_path   (GVfsDaemon                    *daemon,
-					  const char                    *obj_path,
-					  DBusObjectPathMessageFunction  callback,
-					  gpointer                       user_data);
-void        g_vfs_daemon_unregister_path (GVfsDaemon                    *daemon,
-					  const char                    *obj_path);
-void        g_vfs_daemon_initiate_mount  (GVfsDaemon                    *daemon,
-					  GMountSpec                    *mount_spec,
-					  GMountSource                  *mount_source,
-					  gboolean                       is_automount,
-					  DBusMessage                   *request);
+GVfsDaemon *g_vfs_daemon_new                   (gboolean                       main_daemon,
+						gboolean                       replace);
+void        g_vfs_daemon_set_max_threads       (GVfsDaemon                    *daemon,
+						gint                           max_threads);
+void        g_vfs_daemon_add_job_source        (GVfsDaemon                    *daemon,
+						GVfsJobSource                 *job_source);
+gint        g_vfs_daemon_get_n_channel_sources (GVfsDaemon                    *daemon);
+GList      *g_vfs_daemon_get_channel_sources   (GVfsDaemon                    *daemon);
+void        g_vfs_daemon_queue_job             (GVfsDaemon                    *daemon,
+						GVfsJob                       *job);
+void        g_vfs_daemon_register_path         (GVfsDaemon                    *daemon,
+						const char                    *obj_path,
+						DBusObjectPathMessageFunction  callback,
+						gpointer                       user_data);
+void        g_vfs_daemon_unregister_path       (GVfsDaemon                    *daemon,
+						const char                    *obj_path);
+void        g_vfs_daemon_initiate_mount        (GVfsDaemon                    *daemon,
+						GMountSpec                    *mount_spec,
+						GMountSource                  *mount_source,
+						gboolean                       is_automount,
+						DBusMessage                   *request);
 
 G_END_DECLS
 
diff --git a/daemon/gvfsjobunmount.c b/daemon/gvfsjobunmount.c
index 6493856..5fe2d92 100644
--- a/daemon/gvfsjobunmount.c
+++ b/daemon/gvfsjobunmount.c
@@ -77,14 +77,33 @@ g_vfs_job_unmount_new (DBusConnection *connection,
 		       GVfsBackend *backend)
 {
   GVfsJobUnmount *job;
+  DBusError derror;
+  guint32 flags;
 
   g_print ("g_vfs_job_unmount_new request: %p\n", message);
-  
+
+  dbus_error_init (&derror);
+  if (!dbus_message_get_args (message, &derror,
+			      DBUS_TYPE_UINT32, &flags,
+			      0))
+    {
+      DBusMessage *reply;
+      
+      reply = dbus_message_new_error (message,
+				      derror.name,
+				      derror.message);
+      dbus_error_free (&derror);
+      dbus_connection_send (connection, reply, NULL);
+
+      return NULL;
+    }
+
   job = g_object_new (G_VFS_TYPE_JOB_UNMOUNT,
 		      "message", message,
 		      "connection", connection,
 		      NULL);
 
+  job->flags = (GMountUnmountFlags)flags;
   job->backend = backend;
   
   return G_VFS_JOB (job);
@@ -97,7 +116,8 @@ run (GVfsJob *job)
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
 
   class->unmount (op_job->backend,
-		  op_job);
+		  op_job,
+		  op_job->flags);
 }
 
 static gboolean
@@ -105,7 +125,27 @@ try (GVfsJob *job)
 {
   GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job);
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
+  gint n_channels;
 
+  n_channels = g_vfs_backend_get_n_active_channels (op_job->backend);
+  if (n_channels > 0)
+    {
+      if (op_job->flags & G_MOUNT_UNMOUNT_FORCE)
+        {
+	  g_vfs_backend_close_active_channels (op_job->backend);
+	}
+      else
+        {
+	  g_vfs_job_failed (G_VFS_JOB (job),
+			    G_IO_ERROR, G_IO_ERROR_BUSY,
+			    ngettext ("File system is busy: %d operation currently active",
+				      "File system is busy: %d operations currently active",
+				      n_channels),
+			    n_channels);
+	  return TRUE;
+	}
+    }
+  
   if (class->try_unmount == NULL)
     {
       if (class->unmount == NULL)
@@ -119,7 +159,8 @@ try (GVfsJob *job)
     }
 
   return class->try_unmount (op_job->backend,
-			     op_job);
+			     op_job,
+			     op_job->flags);
 }
 
 static void
diff --git a/daemon/gvfsjobunmount.h b/daemon/gvfsjobunmount.h
index aaa18db..0f50f97 100644
--- a/daemon/gvfsjobunmount.h
+++ b/daemon/gvfsjobunmount.h
@@ -43,6 +43,7 @@ struct _GVfsJobUnmount
 {
   GVfsJobDBus parent_instance;
 
+  GMountUnmountFlags flags;
   GVfsBackend *backend;
 };
 
diff --git a/programs/gvfs-mount.c b/programs/gvfs-mount.c
index 65e2ac4..b242386 100644
--- a/programs/gvfs-mount.c
+++ b/programs/gvfs-mount.c
@@ -41,6 +41,7 @@ static GMainLoop *main_loop;
 
 static gboolean mount_mountable = FALSE;
 static gboolean mount_unmount = FALSE;
+static gboolean mount_force_unmount = FALSE;
 static gboolean mount_list = FALSE;
 static gboolean mount_list_info = FALSE;
 static const char *unmount_scheme = NULL;
@@ -50,6 +51,7 @@ static const GOptionEntry entries[] =
   { "mountable", 'm', 0, G_OPTION_ARG_NONE, &mount_mountable, "Mount as mountable", NULL },
   { "unmount", 'u', 0, G_OPTION_ARG_NONE, &mount_unmount, "Unmount", NULL},
   { "unmount-scheme", 's', 0, G_OPTION_ARG_STRING, &unmount_scheme, "Unmount all mounts with the given scheme", NULL},
+  { "force", 'f', 0, G_OPTION_ARG_NONE, &mount_force_unmount, "Force unmount", NULL},
   { "list", 'l', 0, G_OPTION_ARG_NONE, &mount_list, "List", NULL},
   { "list-info", 'i', 0, G_OPTION_ARG_NONE, &mount_list_info, "List extra information", NULL},
   { NULL }
@@ -239,6 +241,7 @@ static void
 unmount (GFile *file)
 {
   GMount *mount;
+  GMountUnmountFlags flags = 0;
   GError *error = NULL;
 
   if (file == NULL)
@@ -251,7 +254,10 @@ unmount (GFile *file)
       return;
     }
 
-  g_mount_unmount (mount, 0, NULL, unmount_done_cb, NULL);
+  if (mount_force_unmount)
+    flags |= G_MOUNT_UNMOUNT_FORCE;
+  
+  g_mount_unmount (mount, flags, NULL, unmount_done_cb, NULL);
 
   outstanding_mounts++;
 }
