tmp->h_commit_sec = cpu_to_be64(now.tv_sec);
        tmp->h_commit_nsec = cpu_to_be32(now.tv_nsec);
 
-       if (JBD2_HAS_COMPAT_FEATURE(journal,
-                                   JBD2_FEATURE_COMPAT_CHECKSUM)) {
+       if (jbd2_has_feature_checksum(journal)) {
                tmp->h_chksum_type      = JBD2_CRC32_CHKSUM;
                tmp->h_chksum_size      = JBD2_CRC32_CHKSUM_SIZE;
                tmp->h_chksum[0]        = cpu_to_be32(crc32_sum);
        bh->b_end_io = journal_end_buffer_io_sync;
 
        if (journal->j_flags & JBD2_BARRIER &&
-           !JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT))
+           !jbd2_has_feature_async_commit(journal))
                ret = submit_bh(WRITE_SYNC | WRITE_FLUSH_FUA, bh);
        else
                ret = submit_bh(WRITE_SYNC, bh);
                                   unsigned long long block)
 {
        tag->t_blocknr = cpu_to_be32(block & (u32)~0);
-       if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(j))
                tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
 }
 
                             bh->b_size);
        kunmap_atomic(addr);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3))
+       if (jbd2_has_feature_csum3(j))
                tag3->t_checksum = cpu_to_be32(csum32);
        else
                tag->t_checksum = cpu_to_be16(csum32);
                                /*
                                 * Compute checksum.
                                 */
-                               if (JBD2_HAS_COMPAT_FEATURE(journal,
-                                       JBD2_FEATURE_COMPAT_CHECKSUM)) {
+                               if (jbd2_has_feature_checksum(journal)) {
                                        crc32_sum =
                                            jbd2_checksum_data(crc32_sum, bh);
                                }
                blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);
 
        /* Done it all: now write the commit record asynchronously. */
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                     JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+       if (jbd2_has_feature_async_commit(journal)) {
                err = journal_submit_commit_record(journal, commit_transaction,
                                                 &cbh, crc32_sum);
                if (err)
        commit_transaction->t_state = T_COMMIT_JFLUSH;
        write_unlock(&journal->j_state_lock);
 
-       if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+       if (!jbd2_has_feature_async_commit(journal)) {
                err = journal_submit_commit_record(journal, commit_transaction,
                                                &cbh, crc32_sum);
                if (err)
        }
        if (cbh)
                err = journal_wait_on_commit_record(journal, cbh);
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                     JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) &&
+       if (jbd2_has_feature_async_commit(journal) &&
            journal->j_flags & JBD2_BARRIER) {
                blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL);
        }
 
                goto out;
        }
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2) &&
-           JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
+       if (jbd2_has_feature_csum2(journal) &&
+           jbd2_has_feature_csum3(journal)) {
                /* Can't have checksum v2 and v3 at the same time! */
                printk(KERN_ERR "JBD2: Can't enable checksumming v2 and v3 "
                       "at the same time!\n");
        }
 
        if (jbd2_journal_has_csum_v2or3_feature(journal) &&
-           JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) {
+           jbd2_has_feature_checksum(journal)) {
                /* Can't have checksum v1 and v2 on at the same time! */
                printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2/3 "
                       "at the same time!\n");
 {
        size_t sz;
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3))
+       if (jbd2_has_feature_csum3(journal))
                return sizeof(journal_block_tag3_t);
 
        sz = sizeof(journal_block_tag_t);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2))
+       if (jbd2_has_feature_csum2(journal))
                sz += sizeof(__u16);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                return sz;
        else
                return sz - sizeof(__u32);
 
                                                journal_block_tag_t *tag)
 {
        unsigned long long block = be32_to_cpu(tag->t_blocknr);
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
        return block;
 }
        csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq));
        csum32 = jbd2_chksum(j, csum32, buf, j->j_blocksize);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3))
+       if (jbd2_has_feature_csum3(j))
                return tag3->t_checksum == cpu_to_be32(csum32);
        else
                return tag->t_checksum == cpu_to_be16(csum32);
                         * just skip over the blocks it describes. */
                        if (pass != PASS_REPLAY) {
                                if (pass == PASS_SCAN &&
-                                   JBD2_HAS_COMPAT_FEATURE(journal,
-                                           JBD2_FEATURE_COMPAT_CHECKSUM) &&
+                                   jbd2_has_feature_checksum(journal) &&
                                    !info->end_transaction) {
                                        if (calc_chksums(journal, bh,
                                                        &next_log_block,
                         * much to do other than move on to the next sequence
                         * number. */
                        if (pass == PASS_SCAN &&
-                           JBD2_HAS_COMPAT_FEATURE(journal,
-                                   JBD2_FEATURE_COMPAT_CHECKSUM)) {
+                           jbd2_has_feature_checksum(journal)) {
                                int chksum_err, chksum_seen;
                                struct commit_header *cbh =
                                        (struct commit_header *)bh->b_data;
                                if (chksum_err) {
                                        info->end_transaction = next_commit_ID;
 
-                                       if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                          JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){
+                                       if (!jbd2_has_feature_async_commit(journal)) {
                                                journal->j_failed_commit =
                                                        next_commit_ID;
                                                brelse(bh);
                                                           bh->b_data)) {
                                info->end_transaction = next_commit_ID;
 
-                               if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                    JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+                               if (!jbd2_has_feature_async_commit(journal)) {
                                        journal->j_failed_commit =
                                                next_commit_ID;
                                        brelse(bh);
                return -EINVAL;
        max = rcount;
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                record_len = 8;
 
        while (offset + record_len <= max) {
 
        if (jbd2_journal_has_csum_v2or3(journal))
                csum_size = sizeof(struct jbd2_journal_revoke_tail);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                sz = 8;
        else
                sz = 4;
                *descriptorp = descriptor;
        }
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                * ((__be64 *)(&descriptor->b_data[offset])) =
                        cpu_to_be64(record->blocknr);
        else
 
 /* 0x0400 */
 } journal_superblock_t;
 
+/* Use the jbd2_{has,set,clear}_feature_* helpers; these will be removed */
 #define JBD2_HAS_COMPAT_FEATURE(j,mask)                                        \
        ((j)->j_format_version >= 2 &&                                  \
         ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
        ((j)->j_format_version >= 2 &&                                  \
         ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
 
-#define JBD2_FEATURE_COMPAT_CHECKSUM   0x00000001
+#define JBD2_FEATURE_COMPAT_CHECKSUM           0x00000001
 
 #define JBD2_FEATURE_INCOMPAT_REVOKE           0x00000001
 #define JBD2_FEATURE_INCOMPAT_64BIT            0x00000002
 #define JBD2_FEATURE_INCOMPAT_CSUM_V2          0x00000008
 #define JBD2_FEATURE_INCOMPAT_CSUM_V3          0x00000010
 
+/* See "journal feature predicate functions" below */
+
 /* Features known to this kernel version: */
 #define JBD2_KNOWN_COMPAT_FEATURES     JBD2_FEATURE_COMPAT_CHECKSUM
 #define JBD2_KNOWN_ROCOMPAT_FEATURES   0
        __u32 j_csum_seed;
 };
 
+/* journal feature predicate functions */
+#define JBD2_FEATURE_COMPAT_FUNCS(name, flagname) \
+static inline bool jbd2_has_feature_##name(journal_t *j) \
+{ \
+       return ((j)->j_format_version >= 2 && \
+               ((j)->j_superblock->s_feature_compat & \
+                cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname)) != 0); \
+} \
+static inline void jbd2_set_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_compat |= \
+               cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname); \
+} \
+static inline void jbd2_clear_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_compat &= \
+               ~cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname); \
+}
+
+#define JBD2_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
+static inline bool jbd2_has_feature_##name(journal_t *j) \
+{ \
+       return ((j)->j_format_version >= 2 && \
+               ((j)->j_superblock->s_feature_ro_compat & \
+                cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname)) != 0); \
+} \
+static inline void jbd2_set_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_ro_compat |= \
+               cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname); \
+} \
+static inline void jbd2_clear_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_ro_compat &= \
+               ~cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname); \
+}
+
+#define JBD2_FEATURE_INCOMPAT_FUNCS(name, flagname) \
+static inline bool jbd2_has_feature_##name(journal_t *j) \
+{ \
+       return ((j)->j_format_version >= 2 && \
+               ((j)->j_superblock->s_feature_incompat & \
+                cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname)) != 0); \
+} \
+static inline void jbd2_set_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_incompat |= \
+               cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname); \
+} \
+static inline void jbd2_clear_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_incompat &= \
+               ~cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname); \
+}
+
+JBD2_FEATURE_COMPAT_FUNCS(checksum,            CHECKSUM)
+
+JBD2_FEATURE_INCOMPAT_FUNCS(revoke,            REVOKE)
+JBD2_FEATURE_INCOMPAT_FUNCS(64bit,             64BIT)
+JBD2_FEATURE_INCOMPAT_FUNCS(async_commit,      ASYNC_COMMIT)
+JBD2_FEATURE_INCOMPAT_FUNCS(csum2,             CSUM_V2)
+JBD2_FEATURE_INCOMPAT_FUNCS(csum3,             CSUM_V3)
+
 /*
  * Journal flag definitions
  */
 
 static inline bool jbd2_journal_has_csum_v2or3_feature(journal_t *j)
 {
-       return JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2) ||
-              JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3);
+       return jbd2_has_feature_csum2(j) || jbd2_has_feature_csum3(j);
 }
 
 static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)