+Workaround Linux kernel last device block inaccessibility.
[captive.git] / src / libcaptive / sandbox / split.c
index f9da17a..d58c8ee 100644 (file)
@@ -37,6 +37,7 @@
 #include <errno.h>
 #include "../client/giochannel-blind.h"        /* for captive_giochannel_blind_new() */
 #include <signal.h>
+#include "../storage/relastblock.h"    /* for captive_storage_relastblock() */
 
 #ifdef HAVE_ORBIT_LINK
 void link_set_tmpdir(const char *dir);
@@ -652,19 +653,32 @@ int errint;
        g_assert(validate_CORBA_Environment(&captive_corba_ev));
 
        /* Init 'CaptiveIOChannel_object' */
-       if (!captive_vfs_parent_object->corba_parent_giochanel_blind_source)
+       if (!captive_vfs_parent_object->corba_parent_giochanel_blind_source) {
+GIOChannel *giochannel;
+
+               giochannel=CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.image_iochannel;
+               g_io_channel_ref(giochannel);
+
+               giochannel=captive_storage_relastblock(giochannel);
+
                switch (CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.rwmode) {
                        case CAPTIVE_OPTION_RWMODE_RO:
                        case CAPTIVE_OPTION_RWMODE_RW:
-                               captive_vfs_parent_object->corba_parent_giochanel_blind_source=CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.image_iochannel;
                                break;
-                       case CAPTIVE_OPTION_RWMODE_BLIND:
-                               captive_vfs_parent_object->corba_parent_giochanel_blind_source=(GIOChannel *)captive_giochannel_blind_new(
-                                               CAPTIVE_VFS_OBJECT(captive_vfs_parent_object)->options.image_iochannel, /* giochannel_orig */
+                       case CAPTIVE_OPTION_RWMODE_BLIND: {
+GIOChannel *giochannel_orig;
+
+                               giochannel_orig=giochannel;
+                               giochannel=(GIOChannel *)captive_giochannel_blind_new(
+                                               giochannel,     /* giochannel_orig */
                                                TRUE); /* writeable */
-                               break;
+                               g_io_channel_unref(giochannel_orig);    /* reffed by captive_giochannel_blind_new() */
+                               } break;
                        default: g_assert_not_reached();
                        }
+               captive_vfs_parent_object->corba_parent_giochanel_blind_source=giochannel;
+               }
+
        if (!captive_vfs_parent_object->corba_parent_giochanel_blind)
                captive_vfs_parent_object->corba_parent_giochanel_blind=(GIOChannel *)captive_giochannel_blind_new(
                                captive_vfs_parent_object->corba_parent_giochanel_blind_source,  /* giochannel_orig */