Whamcloud - gitweb
e2fsck: optimize loop counter when fixing bitmap padding
[tools/e2fsprogs.git] / e2fsck / message.c
index 268620a..3f85916 100644 (file)
@@ -35,6 +35,7 @@
  *     %Id     <inode> -> i_dir_acl
  *     %Iu     <inode> -> i_uid
  *     %Ig     <inode> -> i_gid
+ *     %It     <inode type>
  *     %j      <ino2>                  inode number
  *     %m      <com_err error message>
  *     %N      <num>
  *     @o      orphaned
  *     @p      problem in
  *     @r      root inode
- *     @s      should be 
+ *     @s      should be
  *     @S      superblock
  *     @u      unattached
  *     @v      device
+ *     @x      extent
  *     @z      zero-length
  */
 
@@ -133,6 +135,7 @@ static const char *abbrevs[] = {
        N_("Ssuper@b"),
        N_("uunattached"),
        N_("vdevice"),
+       N_("xextent"),
        N_("zzero-length"),
        "@@",
        0
@@ -196,7 +199,7 @@ static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
                fputs(_(special_inode_name[ino]), stdout);
                return;
        }
-       
+
        retval = ext2fs_get_pathname(fs, dir, ino, &path);
        if (retval)
                fputs("???", stdout);
@@ -209,26 +212,26 @@ static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
 /*
  * This function handles the '@' expansion.  We allow recursive
  * expansion; an @ expression can contain further '@' and '%'
- * expressions. 
+ * expressions.
  */
 static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch,
                                          struct problem_context *pctx,
-                                         int *first)
+                                         int *first, int recurse)
 {
        const char **cpp, *str;
-       
+
        /* Search for the abbreviation */
        for (cpp = abbrevs; *cpp; cpp++) {
                if (ch == *cpp[0])
                        break;
        }
-       if (*cpp) {
+       if (*cpp && recurse < 10) {
                str = _(*cpp) + 1;
                if (*first && islower(*str)) {
                        *first = 0;
                        fputc(toupper(*str++), stdout);
                }
-               print_e2fsck_message(ctx, str, pctx, *first);
+               print_e2fsck_message(ctx, str, pctx, *first, recurse+1);
        } else
                printf("@%c", ch);
 }
@@ -236,18 +239,18 @@ static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch,
 /*
  * This function expands '%IX' expressions
  */
-static _INLINE_ void expand_inode_expression(char ch, 
+static _INLINE_ void expand_inode_expression(char ch,
                                             struct problem_context *ctx)
 {
        struct ext2_inode       *inode;
        struct ext2_inode_large *large_inode;
        const char *            time_str;
        time_t                  t;
-       int                     do_gmt = -1;
+       static int              do_gmt = -1;
 
        if (!ctx || !ctx->inode)
                goto no_inode;
-       
+
        inode = ctx->inode;
        large_inode = (struct ext2_inode_large *) inode;
 
@@ -263,8 +266,8 @@ static _INLINE_ void expand_inode_expression(char ch,
                        else
                                printf("%u", inode->i_size);
 #else
-                       printf("%llu", (inode->i_size | 
-                                       ((__u64) inode->i_size_high << 32)));
+                       printf("%llu", inode->i_size |
+                                      ((long long)inode->i_size_high << 32));
 #endif
                }
                break;
@@ -272,7 +275,12 @@ static _INLINE_ void expand_inode_expression(char ch,
                printf("%u", large_inode->i_extra_isize);
                break;
        case 'b':
-               printf("%u", inode->i_blocks);
+               if (inode->i_flags & EXT4_HUGE_FILE_FL)
+                       printf("%llu", inode->i_blocks +
+                              (((long long) inode->osd2.linux2.l_i_blocks_hi)
+                               << 32));
+               else
+                       printf("%u", inode->i_blocks);
                break;
        case 'l':
                printf("%d", inode->i_links_count);
@@ -281,15 +289,17 @@ static _INLINE_ void expand_inode_expression(char ch,
                printf("0%o", inode->i_mode);
                break;
        case 'M':
+#ifdef __dietlibc__
                /* The diet libc doesn't respect the TZ environemnt variable */
                if (do_gmt == -1) {
                        time_str = getenv("TZ");
                        if (!time_str)
                                time_str = "";
-                       do_gmt = !strcmp(time_str, "GMT");
+                       do_gmt = !strcmp(time_str, "GMT0");
                }
+#endif
                t = inode->i_mtime;
-               time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
+               time_str = asctime((do_gmt > 0) ? gmtime(&t) : localtime(&t));
                printf("%.24s", time_str);
                break;
        case 'F':
@@ -303,12 +313,29 @@ static _INLINE_ void expand_inode_expression(char ch,
                              inode->i_dir_acl : 0));
                break;
        case 'u':
-               printf("%d", (inode->i_uid |
-                             (inode->osd2.linux2.l_i_uid_high << 16)));
+               printf("%d", inode_uid(*inode));
                break;
        case 'g':
-               printf("%d", (inode->i_gid |
-                             (inode->osd2.linux2.l_i_gid_high << 16)));
+               printf("%d", inode_gid(*inode));
+               break;
+       case 't':
+               if (LINUX_S_ISREG(inode->i_mode))
+                       printf(_("regular file"));
+               else if (LINUX_S_ISDIR(inode->i_mode))
+                       printf(_("directory"));
+               else if (LINUX_S_ISCHR(inode->i_mode))
+                       printf(_("character device"));
+               else if (LINUX_S_ISBLK(inode->i_mode))
+                       printf(_("block device"));
+               else if (LINUX_S_ISFIFO(inode->i_mode))
+                       printf(_("named pipe"));
+               else if (LINUX_S_ISLNK(inode->i_mode))
+                       printf(_("symbolic link"));
+               else if (LINUX_S_ISSOCK(inode->i_mode))
+                       printf(_("socket"));
+               else
+                       printf(_("unknown file type with mode 0%o"),
+                              inode->i_mode);
                break;
        default:
        no_inode:
@@ -320,17 +347,18 @@ static _INLINE_ void expand_inode_expression(char ch,
 /*
  * This function expands '%dX' expressions
  */
-static _INLINE_ void expand_dirent_expression(char ch,
+static _INLINE_ void expand_dirent_expression(ext2_filsys fs, char ch,
                                              struct problem_context *ctx)
 {
        struct ext2_dir_entry   *dirent;
+       unsigned int rec_len;
        int     len;
-       
+
        if (!ctx || !ctx->dirent)
                goto no_dirent;
-       
+
        dirent = ctx->dirent;
-       
+
        switch (ch) {
        case 'i':
                printf("%u", dirent->inode);
@@ -339,12 +367,14 @@ static _INLINE_ void expand_dirent_expression(char ch,
                len = dirent->name_len & 0xFF;
                if (len > EXT2_NAME_LEN)
                        len = EXT2_NAME_LEN;
-               if (len > dirent->rec_len)
-                       len = dirent->rec_len;
+               if ((ext2fs_get_rec_len(fs, dirent, &rec_len) == 0) &&
+                   (len > rec_len))
+                       len = rec_len;
                safe_print(dirent->name, len);
                break;
        case 'r':
-               printf("%u", dirent->rec_len);
+               (void) ext2fs_get_rec_len(fs, dirent, &rec_len);
+               printf("%u", rec_len);
                break;
        case 'l':
                printf("%u", dirent->name_len & 0xFF);
@@ -364,23 +394,31 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
 {
        if (!ctx)
                goto no_context;
-       
+
        switch (ch) {
        case '%':
                fputc('%', stdout);
                break;
        case 'b':
-               printf("%u", ctx->blk);
+#ifdef EXT2_NO_64_TYPE
+               printf("%u", (unsigned long) ctx->blk);
+#else
+               printf("%llu", (unsigned long long) ctx->blk);
+#endif
                break;
        case 'B':
 #ifdef EXT2_NO_64_TYPE
                printf("%d", ctx->blkcount);
 #else
-               printf("%lld", ctx->blkcount);
+               printf("%lld", (long long)ctx->blkcount);
 #endif
                break;
        case 'c':
-               printf("%u", ctx->blk2);
+#ifdef EXT2_NO_64_TYPE
+               printf("%u", (unsigned long) ctx->blk2);
+#else
+               printf("%llu", (unsigned long long) ctx->blk2);
+#endif
                break;
        case 'd':
                printf("%u", ctx->dir);
@@ -401,7 +439,7 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
 #ifdef EXT2_NO_64_TYPE
                printf("%u", ctx->num);
 #else
-               printf("%llu", ctx->num);
+               printf("%llu", (long long)ctx->num);
 #endif
                break;
        case 'p':
@@ -427,7 +465,7 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
 #ifdef EXT2_NO_64_TYPE
                printf("0x%x", ctx->num);
 #else
-               printf("0x%llx", ctx->num);
+               printf("0x%llx", (long long)ctx->num);
 #endif
                break;
        default:
@@ -435,10 +473,11 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
                printf("%%%c", ch);
                break;
        }
-}      
+}
 
 void print_e2fsck_message(e2fsck_t ctx, const char *msg,
-                         struct problem_context *pctx, int first)
+                         struct problem_context *pctx, int first,
+                         int recurse)
 {
        ext2_filsys fs = ctx->fs;
        const char *    cp;
@@ -448,13 +487,13 @@ void print_e2fsck_message(e2fsck_t ctx, const char *msg,
        for (cp = msg; *cp; cp++) {
                if (cp[0] == '@') {
                        cp++;
-                       expand_at_expression(ctx, *cp, pctx, &first);
+                       expand_at_expression(ctx, *cp, pctx, &first, recurse);
                } else if (cp[0] == '%' && cp[1] == 'I') {
                        cp += 2;
                        expand_inode_expression(*cp, pctx);
                } else if (cp[0] == '%' && cp[1] == 'D') {
                        cp += 2;
-                       expand_dirent_expression(*cp, pctx);
+                       expand_dirent_expression(fs, *cp, pctx);
                } else if ((cp[0] == '%')) {
                        cp++;
                        expand_percent_expression(fs, *cp, pctx);