Whamcloud - gitweb
ext2fs: check if Lustre filesystem is mounted
[tools/e2fsprogs.git] / lib / ext2fs / closefs.c
index 3c7c7dc..69cbdd8 100644 (file)
@@ -37,14 +37,13 @@ int ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group)
 {
        if (group == 0)
                return 1;
-       if (fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
+       if (ext2fs_has_feature_sparse_super2(fs->super)) {
                if (group == fs->super->s_backup_bgs[0] ||
                    group == fs->super->s_backup_bgs[1])
                        return 1;
                return 0;
        }
-       if ((group <= 1) || !(fs->super->s_feature_ro_compat &
-                             EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
+       if ((group <= 1) || !ext2fs_has_feature_sparse_super(fs->super))
                return 1;
        if (!(group & 1))
                return 0;
@@ -86,7 +85,7 @@ errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
        if (group_block == 0 && fs->blocksize == 1024)
                group_block = 1; /* Deal with 1024 blocksize && bigalloc */
 
-       if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
+       if (ext2fs_has_feature_meta_bg(fs->super))
                old_desc_blocks = fs->super->s_first_meta_bg;
        else
                old_desc_blocks =
@@ -101,7 +100,7 @@ errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
        meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
        meta_bg = group / meta_bg_size;
 
-       if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
+       if (!ext2fs_has_feature_meta_bg(fs->super) ||
            (meta_bg < fs->super->s_first_meta_bg)) {
                if (has_super) {
                        old_desc_blk = group_block + 1;
@@ -261,10 +260,8 @@ static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
        if (sgrp > ((1 << 16) - 1))
                sgrp = (1 << 16) - 1;
 
-       super_shadow->s_block_group_nr = sgrp;
-#ifdef WORDS_BIGENDIAN
-       ext2fs_swap_super(super_shadow);
-#endif
+       super_shadow->s_block_group_nr = ext2fs_cpu_to_le16(sgrp);
+
        retval = ext2fs_superblock_csum_set(fs, super_shadow);
        if (retval)
                return retval;
@@ -285,7 +282,7 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags)
        unsigned long   fs_state;
        __u32           feature_incompat;
        struct ext2_super_block *super_shadow = 0;
-       struct ext2_group_desc *group_shadow = 0;
+       struct opaque_ext2_group_desc *group_shadow = 0;
 #ifdef WORDS_BIGENDIAN
        struct ext2_group_desc *gdp;
        dgrp_t          j;
@@ -296,6 +293,11 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags)
 
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
+       if ((fs->flags & EXT2_FLAG_SUPER_ONLY) == 0 &&
+           !ext2fs_has_feature_journal_dev(fs->super) &&
+           fs->group_desc == NULL)
+               return EXT2_ET_NO_GDESC;
+
        fs_state = fs->super->s_state;
        feature_incompat = fs->super->s_feature_incompat;
 
@@ -317,44 +319,47 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags)
                        goto errout;
        }
 
-       /* Prepare the group descriptors for writing */
+       /*
+        * Set the state of the FS to be non-valid.  (The state has
+        * already been backed up earlier, and will be restored after
+        * we write out the backup superblocks.)
+        */
+       fs->super->s_state &= ~EXT2_VALID_FS;
+       ext2fs_clear_feature_journal_needs_recovery(fs->super);
+
+       /* Byte swap the superblock and the group descriptors if necessary */
 #ifdef WORDS_BIGENDIAN
        retval = EXT2_ET_NO_MEMORY;
        retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow);
        if (retval)
                goto errout;
-       retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize,
-                                 &group_shadow);
-       if (retval)
-               goto errout;
        memcpy(super_shadow, fs->super, sizeof(struct ext2_super_block));
-       memcpy(group_shadow, fs->group_desc, (size_t) fs->blocksize *
-              fs->desc_blocks);
+       ext2fs_swap_super(super_shadow);
+
+       if (((fs->flags & EXT2_FLAG_SUPER_ONLY) == 0) &&
+           !ext2fs_has_feature_journal_dev(fs->super)) {
+               retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize,
+                                         &group_shadow);
+               if (retval)
+                       goto errout;
+               memcpy(group_shadow, fs->group_desc, (size_t) fs->blocksize *
+                      fs->desc_blocks);
 
-       /* swap the group descriptors */
-       for (j = 0; j < fs->group_desc_count; j++) {
-               gdp = ext2fs_group_desc(fs, group_shadow, j);
-               ext2fs_swap_group_desc2(fs, gdp);
+               for (j = 0; j < fs->group_desc_count; j++) {
+                       gdp = ext2fs_group_desc(fs, group_shadow, j);
+                       ext2fs_swap_group_desc2(fs, gdp);
+               }
        }
 #else
        super_shadow = fs->super;
-       group_shadow = ext2fs_group_desc(fs, fs->group_desc, 0);
+       group_shadow = fs->group_desc;
 #endif
 
        /*
-        * Set the state of the FS to be non-valid.  (The state has
-        * already been backed up earlier, and will be restored after
-        * we write out the backup superblocks.)
-        */
-       fs->super->s_state &= ~EXT2_VALID_FS;
-       fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
-
-       /*
         * If this is an external journal device, don't write out the
         * block group descriptors or any of the backup superblocks
         */
-       if (fs->super->s_feature_incompat &
-           EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
+       if (ext2fs_has_feature_journal_dev(fs->super))
                goto write_primary_superblock_only;
 
        /*
@@ -362,7 +367,7 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags)
         * superblocks and group descriptors.
         */
        group_ptr = (char *) group_shadow;
-       if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) {
+       if (ext2fs_has_feature_meta_bg(fs->super)) {
                old_desc_blocks = fs->super->s_first_meta_bg;
                if (old_desc_blocks > fs->desc_blocks)
                        old_desc_blocks = fs->desc_blocks;
@@ -431,16 +436,22 @@ write_primary_superblock_only:
        if (retval)
                return retval;
 
-       if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC))
+       if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC)) {
                retval = io_channel_flush(fs->io);
+               if (retval)
+                       goto errout;
+       }
        retval = write_primary_superblock(fs, super_shadow);
        if (retval)
                goto errout;
 
        fs->flags &= ~EXT2_FLAG_DIRTY;
 
-       if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC))
+       if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC)) {
                retval = io_channel_flush(fs->io);
+               if (retval)
+                       goto errout;
+       }
 errout:
        fs->super->s_state = fs_state;
 #ifdef WORDS_BIGENDIAN