Fix threadsafety of closing channels
Fix d-bus messages leaks Fix /dev symlink checks in gdu volume monitor
This commit is contained in:
parent
9486d00117
commit
38e3ea2e55
@ -1,124 +0,0 @@
|
||||
From 089ba0b1af08f8b7506bd867a415e197f4017ec0 Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Thu, 28 Oct 2010 16:25:12 +0000
|
||||
Subject: Use correct "usb:" address for GPhoto mounts with gudev
|
||||
|
||||
gphoto2 expects the usb:X,X addresses to use the dirname and device
|
||||
names from libusb, which are zero-padded. Given that it's what udev
|
||||
gives us, just don't transform it to an int before printing.
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=631562
|
||||
---
|
||||
diff --git a/monitor/gphoto2/ggphoto2volumemonitor.c b/monitor/gphoto2/ggphoto2volumemonitor.c
|
||||
index 9fefc5d..25affe3 100644
|
||||
--- a/monitor/gphoto2/ggphoto2volumemonitor.c
|
||||
+++ b/monitor/gphoto2/ggphoto2volumemonitor.c
|
||||
@@ -83,7 +83,7 @@ static void update_cameras (GGPhoto2VolumeMonitor *monitor,
|
||||
GList **removed_volumes);
|
||||
#endif
|
||||
|
||||
-static GList* get_stores_for_camera (int bus_num, int device_num);
|
||||
+static GList* get_stores_for_camera (const char *bus_num, const char *device_num);
|
||||
|
||||
G_DEFINE_TYPE (GGPhoto2VolumeMonitor, g_gphoto2_volume_monitor, G_TYPE_VOLUME_MONITOR)
|
||||
|
||||
@@ -195,9 +195,7 @@ gudev_add_camera (GGPhoto2VolumeMonitor *monitor, GUdevDevice *device, gboolean
|
||||
GGPhoto2Volume *volume;
|
||||
GList *store_heads, *l;
|
||||
guint num_store_heads;
|
||||
- const char *property;
|
||||
- int usb_bus_num;
|
||||
- int usb_device_num;
|
||||
+ const char *usb_bus_num, *usb_device_num;
|
||||
|
||||
/* For iPhones and iPod Touches, don't mount gphoto mounts,
|
||||
* we already have access through AFC */
|
||||
@@ -209,19 +207,17 @@ gudev_add_camera (GGPhoto2VolumeMonitor *monitor, GUdevDevice *device, gboolean
|
||||
}
|
||||
#endif /* HAVE_AFC */
|
||||
|
||||
- property = g_udev_device_get_property (device, "BUSNUM");
|
||||
- if (property == NULL) {
|
||||
+ usb_bus_num = g_udev_device_get_property (device, "BUSNUM");
|
||||
+ if (usb_bus_num == NULL) {
|
||||
g_warning("device %s has no BUSNUM property, ignoring", g_udev_device_get_device_file (device));
|
||||
return;
|
||||
}
|
||||
- usb_bus_num = atoi (property);
|
||||
|
||||
- property = g_udev_device_get_property (device, "DEVNUM");
|
||||
- if (property == NULL) {
|
||||
+ usb_device_num = g_udev_device_get_property (device, "DEVNUM");
|
||||
+ if (usb_device_num == NULL) {
|
||||
g_warning("device %s has no DEVNUM property, ignoring", g_udev_device_get_device_file (device));
|
||||
return;
|
||||
}
|
||||
- usb_device_num = atoi (property);
|
||||
|
||||
/* g_debug ("gudev_add_camera: camera device %s (bus: %i, device: %i)",
|
||||
g_udev_device_get_device_file (device),
|
||||
@@ -241,11 +237,11 @@ gudev_add_camera (GGPhoto2VolumeMonitor *monitor, GUdevDevice *device, gboolean
|
||||
*/
|
||||
if (num_store_heads == 1)
|
||||
{
|
||||
- uri = g_strdup_printf ("gphoto2://[usb:%03d,%03d]", usb_bus_num, usb_device_num);
|
||||
+ uri = g_strdup_printf ("gphoto2://[usb:%s,%s]", usb_bus_num, usb_device_num);
|
||||
}
|
||||
else
|
||||
{
|
||||
- uri = g_strdup_printf ("gphoto2://[usb:%03d,%03d]/%s", usb_bus_num, usb_device_num,
|
||||
+ uri = g_strdup_printf ("gphoto2://[usb:%s,%s]/%s", usb_bus_num, usb_device_num,
|
||||
store_path[0] == '/' ? store_path + 1 : store_path);
|
||||
}
|
||||
/* g_debug ("gudev_add_camera: ... adding URI for storage head: %s", uri); */
|
||||
@@ -608,7 +604,7 @@ update_all (GGPhoto2VolumeMonitor *monitor,
|
||||
#endif
|
||||
|
||||
static GList *
|
||||
-get_stores_for_camera (int bus_num, int device_num)
|
||||
+get_stores_for_camera (const char *bus_num, const char *device_num)
|
||||
{
|
||||
GList *l;
|
||||
CameraStorageInformation *storage_info;
|
||||
@@ -624,7 +620,7 @@ get_stores_for_camera (int bus_num, int device_num)
|
||||
camera = NULL;
|
||||
context = NULL;
|
||||
l = NULL;
|
||||
- port = g_strdup_printf ("usb:%d,%d", bus_num, device_num);
|
||||
+ port = g_strdup_printf ("usb:%s,%s", bus_num, device_num);
|
||||
|
||||
/* Connect to the camera */
|
||||
context = gp_context_new ();
|
||||
@@ -686,6 +682,21 @@ out:
|
||||
}
|
||||
|
||||
#ifndef HAVE_GUDEV
|
||||
+static GList *
|
||||
+get_stores_for_camera_int (int bus_num, int device_num)
|
||||
+{
|
||||
+ GList *ret;
|
||||
+ char *bus_num_str, *device_num_str;
|
||||
+
|
||||
+ bus_num_str = g_strdup_printf ("%d", bus_num);
|
||||
+ device_num_str = g_strdup_printf ("%d", device_num);
|
||||
+ ret = get_stores_for_camera (bus_num_str, device_num_str);
|
||||
+ g_free (bus_num_str);
|
||||
+ g_free (device_num_str);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
update_cameras (GGPhoto2VolumeMonitor *monitor,
|
||||
GList **added_volumes,
|
||||
@@ -781,7 +792,7 @@ update_cameras (GGPhoto2VolumeMonitor *monitor,
|
||||
# error "Need OS specific tweaks"
|
||||
#endif
|
||||
|
||||
- store_heads = get_stores_for_camera (usb_bus_num, usb_device_num);
|
||||
+ store_heads = get_stores_for_camera_int (usb_bus_num, usb_device_num);
|
||||
num_store_heads = g_list_length (store_heads);
|
||||
for (l = store_heads ; l != NULL; l = l->next)
|
||||
{
|
||||
--
|
||||
cgit v0.8.3.1
|
23
gvfs-1.8.1-gdu-volume-monitor-realpath.patch
Normal file
23
gvfs-1.8.1-gdu-volume-monitor-realpath.patch
Normal file
@ -0,0 +1,23 @@
|
||||
From 9bfe6ccdf1143c9f5409d17908f40c7544ceb119 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Larsson <alexl@redhat.com>
|
||||
Date: Fri, 15 Apr 2011 12:49:25 +0000
|
||||
Subject: gdu volume monitor: Fix check for symlinks in /dev, was reversed
|
||||
|
||||
Spotted by Emilio Pozuelo Monfort in
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=601497
|
||||
---
|
||||
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
|
||||
index 794d354..1066f4f 100644
|
||||
--- a/monitor/gdu/ggduvolumemonitor.c
|
||||
+++ b/monitor/gdu/ggduvolumemonitor.c
|
||||
@@ -1427,7 +1427,7 @@ update_fstab_volumes (GGduVolumeMonitor *monitor,
|
||||
GduDevice *device;
|
||||
|
||||
/* doesn't exist */
|
||||
- if (realpath (device_file, resolved_path) != NULL)
|
||||
+ if (realpath (device_file, resolved_path) == NULL)
|
||||
continue;
|
||||
|
||||
/* is handled by DKD */
|
||||
--
|
||||
cgit v0.9
|
183
gvfs-1.8.1-gvfschannel-safety.patch
Normal file
183
gvfs-1.8.1-gvfschannel-safety.patch
Normal file
@ -0,0 +1,183 @@
|
||||
From 0babec2c24287a8578be488dacb0428998aa5648 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Larsson <alexl@redhat.com>
|
||||
Date: Fri, 15 Apr 2011 10:14:46 +0000
|
||||
Subject: Fix threadsafety of closing channels
|
||||
|
||||
There is a race in g_vfs_job_close_read_finalize vs command_read_cb
|
||||
where if these run in different threads (the command_read_cb in the main
|
||||
thread and the close in another thread), such as in the smb case then
|
||||
we may free the channel early.
|
||||
|
||||
We fix this by having the command reading propely ref the channel and
|
||||
add a cancellable that allows us to cancel the command reading when the
|
||||
channel is closed.
|
||||
---
|
||||
diff --git a/daemon/gvfschannel.c b/daemon/gvfschannel.c
|
||||
index efe2376..f746f55 100644
|
||||
--- a/daemon/gvfschannel.c
|
||||
+++ b/daemon/gvfschannel.c
|
||||
@@ -61,6 +61,7 @@ typedef struct
|
||||
{
|
||||
GVfsChannel *channel;
|
||||
GInputStream *command_stream;
|
||||
+ GCancellable *cancellable;
|
||||
char buffer[G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE];
|
||||
int buffer_size;
|
||||
char *data;
|
||||
@@ -84,6 +85,7 @@ struct _GVfsChannelPrivate
|
||||
GVfsBackend *backend;
|
||||
gboolean connection_closed;
|
||||
GInputStream *command_stream;
|
||||
+ GCancellable *cancellable;
|
||||
GOutputStream *reply_stream;
|
||||
int remote_fd;
|
||||
GPid actual_consumer;
|
||||
@@ -94,8 +96,6 @@ struct _GVfsChannelPrivate
|
||||
|
||||
GList *queued_requests;
|
||||
|
||||
- RequestReader *request_reader;
|
||||
-
|
||||
char reply_buffer[G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SIZE];
|
||||
int reply_buffer_pos;
|
||||
|
||||
@@ -130,13 +130,13 @@ g_vfs_channel_finalize (GObject *object)
|
||||
g_object_unref (channel->priv->reply_stream);
|
||||
channel->priv->reply_stream = NULL;
|
||||
|
||||
- if (channel->priv->request_reader)
|
||||
- channel->priv->request_reader->channel = NULL;
|
||||
- channel->priv->request_reader = NULL;
|
||||
-
|
||||
if (channel->priv->command_stream)
|
||||
g_object_unref (channel->priv->command_stream);
|
||||
channel->priv->command_stream = NULL;
|
||||
+
|
||||
+ if (channel->priv->cancellable)
|
||||
+ g_object_unref (channel->priv->cancellable);
|
||||
+ channel->priv->cancellable = NULL;
|
||||
|
||||
if (channel->priv->remote_fd != -1)
|
||||
close (channel->priv->remote_fd);
|
||||
@@ -204,6 +204,7 @@ g_vfs_channel_init (GVfsChannel *channel)
|
||||
else
|
||||
{
|
||||
channel->priv->command_stream = g_unix_input_stream_new (socket_fds[0], TRUE);
|
||||
+ channel->priv->cancellable = g_cancellable_new ();
|
||||
channel->priv->reply_stream = g_unix_output_stream_new (socket_fds[0], FALSE);
|
||||
channel->priv->remote_fd = socket_fds[1];
|
||||
|
||||
@@ -284,6 +285,8 @@ static void
|
||||
request_reader_free (RequestReader *reader)
|
||||
{
|
||||
g_object_unref (reader->command_stream);
|
||||
+ g_object_unref (reader->cancellable);
|
||||
+ g_object_unref (reader->channel);
|
||||
g_free (reader->data);
|
||||
g_free (reader);
|
||||
}
|
||||
@@ -426,7 +429,7 @@ finish_request (RequestReader *reader)
|
||||
g_input_stream_read_async (reader->command_stream,
|
||||
reader->buffer + reader->buffer_size,
|
||||
G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE - reader->buffer_size,
|
||||
- 0, NULL,
|
||||
+ 0, reader->cancellable,
|
||||
command_read_cb,
|
||||
reader);
|
||||
}
|
||||
@@ -440,18 +443,10 @@ data_read_cb (GObject *source_object,
|
||||
GInputStream *stream = G_INPUT_STREAM (source_object);
|
||||
gssize count_read;
|
||||
|
||||
- if (reader->channel == NULL)
|
||||
- {
|
||||
- /* Channel was finalized */
|
||||
- request_reader_free (reader);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
count_read = g_input_stream_read_finish (stream, res, NULL);
|
||||
|
||||
if (count_read <= 0)
|
||||
{
|
||||
- reader->channel->priv->request_reader = NULL;
|
||||
g_vfs_channel_connection_closed (reader->channel);
|
||||
request_reader_free (reader);
|
||||
return;
|
||||
@@ -464,7 +459,7 @@ data_read_cb (GObject *source_object,
|
||||
g_input_stream_read_async (reader->command_stream,
|
||||
reader->data + reader->data_pos,
|
||||
reader->data_len - reader->data_pos,
|
||||
- 0, NULL,
|
||||
+ 0, reader->cancellable,
|
||||
data_read_cb, reader);
|
||||
return;
|
||||
}
|
||||
@@ -484,18 +479,10 @@ command_read_cb (GObject *source_object,
|
||||
guint32 data_len;
|
||||
gssize count_read;
|
||||
|
||||
- if (reader->channel == NULL)
|
||||
- {
|
||||
- /* Channel was finalized */
|
||||
- request_reader_free (reader);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
count_read = g_input_stream_read_finish (stream, res, NULL);
|
||||
|
||||
if (count_read <= 0)
|
||||
{
|
||||
- reader->channel->priv->request_reader = NULL;
|
||||
g_vfs_channel_connection_closed (reader->channel);
|
||||
request_reader_free (reader);
|
||||
return;
|
||||
@@ -508,7 +495,7 @@ command_read_cb (GObject *source_object,
|
||||
g_input_stream_read_async (reader->command_stream,
|
||||
reader->buffer + reader->buffer_size,
|
||||
G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE - reader->buffer_size,
|
||||
- 0, NULL,
|
||||
+ 0, reader->cancellable,
|
||||
command_read_cb, reader);
|
||||
return;
|
||||
}
|
||||
@@ -525,7 +512,7 @@ command_read_cb (GObject *source_object,
|
||||
g_input_stream_read_async (reader->command_stream,
|
||||
reader->data + reader->data_pos,
|
||||
reader->data_len - reader->data_pos,
|
||||
- 0, NULL,
|
||||
+ 0, reader->cancellable,
|
||||
data_read_cb, reader);
|
||||
return;
|
||||
}
|
||||
@@ -539,16 +526,15 @@ start_request_reader (GVfsChannel *channel)
|
||||
RequestReader *reader;
|
||||
|
||||
reader = g_new0 (RequestReader, 1);
|
||||
- reader->channel = channel;
|
||||
+ reader->channel = g_object_ref (channel);
|
||||
+ reader->cancellable = g_object_ref (channel->priv->cancellable);
|
||||
reader->command_stream = g_object_ref (channel->priv->command_stream);
|
||||
|
||||
g_input_stream_read_async (reader->command_stream,
|
||||
reader->buffer + reader->buffer_size,
|
||||
G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SIZE - reader->buffer_size,
|
||||
- 0, NULL,
|
||||
+ 0, reader->cancellable,
|
||||
command_read_cb, reader);
|
||||
-
|
||||
- channel->priv->request_reader = reader;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -615,6 +601,8 @@ send_reply_cb (GObject *source_object,
|
||||
if (G_VFS_IS_JOB_CLOSE_READ (job) ||
|
||||
G_VFS_IS_JOB_CLOSE_WRITE (job))
|
||||
{
|
||||
+ /* Cancel the reader */
|
||||
+ g_cancellable_cancel (channel->priv->cancellable);
|
||||
g_vfs_job_source_closed (G_VFS_JOB_SOURCE (channel));
|
||||
channel->priv->backend_handle = NULL;
|
||||
}
|
||||
--
|
||||
cgit v0.9
|
15
gvfs.spec
15
gvfs.spec
@ -1,7 +1,7 @@
|
||||
Summary: Backends for the gio framework in GLib
|
||||
Name: gvfs
|
||||
Version: 1.8.0
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
License: LGPLv2+
|
||||
Group: System Environment/Libraries
|
||||
URL: http://www.gtk.org
|
||||
@ -39,6 +39,11 @@ Patch0: gvfs-archive-integration.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=552856
|
||||
Patch15: gvfs-1.5.1-gphoto2-no-storageinfo-support.patch
|
||||
|
||||
# from upstream
|
||||
Patch16: gvfs-1.8.1-gvfschannel-safety.patch
|
||||
Patch17: gvfs-1.8.1-dbus-leak.patch
|
||||
Patch18: gvfs-1.8.1-gdu-volume-monitor-realpath.patch
|
||||
|
||||
Obsoletes: gnome-mount <= 0.8
|
||||
Obsoletes: gnome-mount-nautilus-properties <= 0.8
|
||||
|
||||
@ -136,6 +141,9 @@ including phones and music players to applications using gvfs.
|
||||
%setup -q
|
||||
%patch0 -p1 -b .archive-integration
|
||||
%patch15 -p1 -b .gphoto2-storageinfo
|
||||
%patch16 -p1 -b .channel-safety
|
||||
%patch17 -p1 -b .dbus-leak
|
||||
%patch18 -p1 -b .realpath
|
||||
|
||||
%build
|
||||
|
||||
@ -310,6 +318,11 @@ killall -USR1 gvfsd >&/dev/null || :
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Apr 18 2011 Tomas Bzatek <tbzatek@redhat.com> - 1.8.0-2
|
||||
- Fix threadsafety of closing channels
|
||||
- Fix d-bus messages leaks
|
||||
- Fix /dev symlink checks in gdu volume monitor
|
||||
|
||||
* Mon Apr 4 2011 Matthias Clasen <mclasen@redhat.com> - 1.8.0-1
|
||||
- Update to 1.8.0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user