ext2: Fix "ext2fs_mkdir .. No free space in directory".
[febootstrap.git] / helper / ext2.c
index a27fb47..2fc8036 100644 (file)
@@ -135,10 +135,20 @@ ext2_mkdir (ext2_ino_t dir_ino, const char *dirname, const char *basename,
   if (err != 0)
     error (EXIT_FAILURE, 0, "ext2fs_new_inode: %s", error_message (err));
 
+ try_again:
   err = ext2fs_mkdir (fs, dir_ino, ino, basename);
-  if (err != 0)
-    error (EXIT_FAILURE, 0, "ext2fs_mkdir: %s/%s: %s",
-           dirname, basename, error_message (err));
+  if (err != 0) {
+    /* See: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=217892 */
+    if (err == EXT2_ET_DIR_NO_SPACE) {
+      err = ext2fs_expand_dir (fs, dir_ino);
+      if (err)
+        error (EXIT_FAILURE, 0, "ext2fs_expand_dir: %s/%s: %s",
+               dirname, basename, error_message (err));
+      goto try_again;
+    } else
+      error (EXIT_FAILURE, 0, "ext2fs_mkdir: %s/%s: %s",
+             dirname, basename, error_message (err));
+  }
 
   /* Copy the final permissions, UID etc. to the inode. */
   struct ext2_inode inode;
@@ -304,9 +314,19 @@ ext2_clean_path (ext2_ino_t dir_ino,
       if (err != 0)
         error (EXIT_FAILURE, 0, "ext2fs_write_inode: %s", error_message (err));
 
-      if (ext2fs_inode_has_valid_blocks (&inode))
-        ext2fs_block_iterate (fs, ino, BLOCK_FLAG_READ_ONLY, NULL,
+      if (ext2fs_inode_has_valid_blocks (&inode)) {
+       int flags = 0;
+       /* From the docs: "BLOCK_FLAG_READ_ONLY is a promise by the
+        * caller that it will not modify returned block number."
+        * RHEL 5 does not have this flag, so just omit it if it is
+        * not defined.
+        */
+#ifdef BLOCK_FLAG_READ_ONLY
+       flags |= BLOCK_FLAG_READ_ONLY;
+#endif
+        ext2fs_block_iterate (fs, ino, flags, NULL,
                               release_block, NULL);
+      }
 
       ext2fs_inode_alloc_stats2 (fs, ino, -1, isdir);
     }