diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
index 1746bd8..9b77920 100644
--- a/daemon/gvfsbackend.c
+++ b/daemon/gvfsbackend.c
@@ -268,6 +268,11 @@ g_vfs_backend_get_daemon (GVfsBackend *backend)
   return backend->priv->daemon;
 }
 
+gboolean
+g_vfs_backend_is_busy (GVfsBackend *backend)
+{
+  return g_vfs_daemon_has_channel_sources (backend->priv->daemon);
+}
 
 void
 g_vfs_backend_set_display_name (GVfsBackend *backend,
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index c99d18b..6214767 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -399,6 +399,7 @@ 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);
+gboolean    g_vfs_backend_is_busy                        (GVfsBackend        *backend);
 
 void        g_vfs_backend_add_auto_info                  (GVfsBackend           *backend,
 							  GFileAttributeMatcher *matcher,
diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c
index f9f5276..fab6ee1 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,12 @@ g_vfs_daemon_re_register_job_sources (GVfsDaemon *daemon)
   g_mutex_unlock (daemon->lock);
 }
 
+gboolean
+g_vfs_daemon_has_channel_sources (GVfsDaemon *daemon)
+{
+  return (daemon->n_channel_sources > 0);
+}
+
 void
 g_vfs_daemon_add_job_source (GVfsDaemon *daemon,
 			     GVfsJobSource *job_source)
@@ -378,6 +389,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..96c009a 100644
--- a/daemon/gvfsdaemon.h
+++ b/daemon/gvfsdaemon.h
@@ -51,25 +51,26 @@ 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);
+gboolean    g_vfs_daemon_has_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..deeadd4 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);
@@ -106,6 +125,15 @@ try (GVfsJob *job)
   GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job);
   GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
 
+  if (!(op_job->flags & G_MOUNT_UNMOUNT_FORCE) &&
+      g_vfs_backend_is_busy (op_job->backend))
+    {
+      g_vfs_job_failed (G_VFS_JOB (job),
+			G_IO_ERROR, G_IO_ERROR_BUSY,
+			_("File system is busy"));
+      return TRUE;
+    }
+  
   if (class->try_unmount == NULL)
     {
       if (class->unmount == NULL)
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 0d5d592..9e134e8 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;
 
@@ -48,6 +49,7 @@ static 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},
+  { "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 }
@@ -237,6 +239,7 @@ static void
 unmount (GFile *file)
 {
   GMount *mount;
+  GMountUnmountFlags flags = 0;
   GError *error = NULL;
 
   if (file == NULL)
@@ -249,7 +252,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++;
 }
