Whamcloud - gitweb
libext2fs: document EXT2_FLAG_64BITS in ext2fs_open2()
[tools/e2fsprogs.git] / lib / ext2fs / openfs.c
index a986beb..220d954 100644 (file)
@@ -23,6 +23,9 @@
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 
 #include "ext2_fs.h"
 
@@ -83,6 +86,9 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
  *     EXT2_FLAG_FORCE - Open the filesystem even if some of the
  *                             features aren't supported.
  *     EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
+ *     EXT2_FLAG_SKIP_MMP - Open without multi-mount protection check.
+ *     EXT2_FLAG_64BITS - Allow 64-bit bitfields (needed for large
+ *                             filesystems)
  */
 errcode_t ext2fs_open2(const char *name, const char *io_options,
                       int flags, int superblock,
@@ -352,8 +358,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                        goto cleanup;
 #ifdef WORDS_BIGENDIAN
                for (j=0; j < groups_per_block; j++) {
-                       /* The below happens to work... be careful. */
-                       gdp = ext2fs_group_desc(fs, fs->group_desc, j);
+                       gdp = ext2fs_group_desc(fs, fs->group_desc,
+                                               i * groups_per_block + j);
                        ext2fs_swap_group_desc2(fs, gdp);
                }
 #endif
@@ -374,12 +380,28 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                        ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
                        ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
                        ext2fs_bg_itable_unused_set(fs, group, 0);
+                       /* The checksum will be reset later, but fix it here
+                        * anyway to avoid printing a lot of spurious errors. */
+                       ext2fs_group_desc_csum_set(fs, group);
                }
-               ext2fs_mark_super_dirty(fs);
+               if (fs->flags & EXT2_FLAG_RW)
+                       ext2fs_mark_super_dirty(fs);
        }
 
        fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
        *ret_fs = fs;
+
+       if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
+           !(flags & EXT2_FLAG_SKIP_MMP) &&
+           (flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) {
+               retval = ext2fs_mmp_start(fs);
+               if (retval) {
+                       fs->flags |= EXT2_FLAG_SKIP_MMP; /* just do cleanup */
+                       ext2fs_mmp_stop(fs);
+                       goto cleanup;
+               }
+       }
+
        return 0;
 cleanup:
        if (flags & EXT2_FLAG_NOFREE_ON_ERROR)