Whamcloud - gitweb
Many files:
[tools/e2fsprogs.git] / e2fsck / pass1b.c
1 /*
2  * pass1b.c --- Pass #1b of e2fsck
3  *
4  * This file contains pass1B, pass1C, and pass1D of e2fsck.  They are
5  * only invoked if pass 1 discovered blocks which are in use by more
6  * than one inode.
7  * 
8  * Pass1B scans the data blocks of all the inodes again, generating a
9  * complete list of duplicate blocks and which inodes have claimed
10  * them.
11  *
12  * Pass1C does a tree-traversal of the filesystem, to determine the
13  * parent directories of these inodes.  This step is necessary so that
14  * e2fsck can print out the pathnames of affected inodes.
15  *
16  * Pass1D is a reconciliation pass.  For each inode with duplicate
17  * blocks, the user is prompted if s/he would like to clone the file
18  * (so that the file gets a fresh copy of the duplicated blocks) or
19  * simply to delete the file.
20  * 
21  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
22  *
23  * %Begin-Header%
24  * This file may be redistributed under the terms of the GNU Public
25  * License.
26  * %End-Header%
27  * 
28  */
29
30 #include <time.h>
31 #ifdef HAVE_ERRNO_H
32 #include <errno.h>
33 #endif
34
35 #include <et/com_err.h>
36 #include "e2fsck.h"
37
38 #include "problem.h"
39
40 /*
41  * This is structure is allocated for each time that a block is
42  * claimed by more than one file.  So if a particular block is claimed
43  * by 3 files, then three copies of this structure will be allocated,
44  * one for each conflict.
45  *
46  * The linked list structure is as follows:
47  *
48  * dup_blk -->  block #34  --> block #35  --> block #47
49  *              inode #12      inode #14      inode #17
50  *              num_bad = 3    num_bad = 2    num_bad = 2
51  *                |              |               |
52  *                V              V               V
53  *              block #34      block #35      block #47
54  *              inode #14      inode #15      inode #23
55  *                |
56  *                V
57  *              block #34
58  *              inode #15
59  *
60  * The num_bad field indicates how many inodes are sharing a
61  * particular block, and is only stored in the first element of the
62  * linked list for a particular block.  As the block conflicts are
63  * resolved, num_bad is decremented; when it reaches 1, then we no
64  * longer need to worry about that block.
65  */
66 struct dup_block {
67         blk_t           block;          /* Block number */
68         ino_t           ino;            /* Inode number */
69         int             num_bad;
70         /* Pointer to next dup record with different block */
71         struct dup_block *next_block;
72         /* Pointer to next dup record with different inode */
73         struct dup_block *next_inode;
74 };
75
76 /*
77  * This structure stores information about a particular inode which
78  * is sharing blocks with other inodes.  This information is collected
79  * to display to the user, so that the user knows what files he or she
80  * is dealing with, when trying to decide how to resolve the conflict
81  * of multiply-claimed blocks.
82  */
83 struct dup_inode {
84         ino_t                   ino, dir;
85         int                     num_dupblocks;
86         struct ext2_inode       inode;
87         struct dup_inode        *next;
88 };
89
90 static int process_pass1b_block(ext2_filsys fs, blk_t   *blocknr,
91                                 int     blockcnt, void  *priv_data);
92 static void delete_file(e2fsck_t ctx, struct dup_inode *dp,
93                         char *block_buf);
94 static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf);
95 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
96
97 static void pass1b(e2fsck_t ctx, char *block_buf);
98 static void pass1c(e2fsck_t ctx, char *block_buf);
99 static void pass1d(e2fsck_t ctx, char *block_buf);
100
101 static struct dup_block *dup_blk = 0;
102 static struct dup_inode *dup_ino = 0;
103 static int dup_inode_count = 0;
104
105 static ext2fs_inode_bitmap inode_dup_map;
106
107 /*
108  * Main procedure for handling duplicate blocks
109  */
110 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
111 {
112         ext2_filsys             fs = ctx->fs;
113         struct dup_block        *p, *q, *next_p, *next_q;
114         struct dup_inode        *r, *next_r;
115         struct problem_context  pctx;
116
117         clear_problem_context(&pctx);
118         
119         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
120                       _("multiply claimed inode map"), &inode_dup_map);
121         if (pctx.errcode) {
122                 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
123                 ctx->flags |= E2F_FLAG_ABORT;
124                 return;
125         }
126         
127         pass1b(ctx, block_buf);
128         pass1c(ctx, block_buf);
129         pass1d(ctx, block_buf);
130
131         /*
132          * Time to free all of the accumulated data structures that we
133          * don't need anymore.
134          */
135         ext2fs_free_inode_bitmap(inode_dup_map); inode_dup_map = 0;
136         ext2fs_free_block_bitmap(ctx->block_dup_map); ctx->block_dup_map = 0;
137         for (p = dup_blk; p; p = next_p) {
138                 next_p = p->next_block;
139                 for (q = p; q; q = next_q) {
140                         next_q = q->next_inode;
141                         ext2fs_free_mem((void **) &q);
142                 }
143         }
144         for (r = dup_ino; r; r = next_r) {
145                 next_r = r->next;
146                 ext2fs_free_mem((void **) &r);
147         }
148 }
149
150 /*
151  * Scan the inodes looking for inodes that contain duplicate blocks.
152  */
153 struct process_block_struct {
154         ino_t   ino;
155         int     dup_blocks;
156         e2fsck_t ctx;
157         struct problem_context *pctx;
158 };
159
160 static void pass1b(e2fsck_t ctx, char *block_buf)
161 {
162         ext2_filsys fs = ctx->fs;
163         ino_t   ino;
164         struct ext2_inode inode;
165         ext2_inode_scan scan;
166         errcode_t       retval;
167         struct process_block_struct pb;
168         struct dup_inode *dp;
169         struct problem_context pctx;
170
171         clear_problem_context(&pctx);
172         
173         fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
174         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
175                                               &scan);
176         if (pctx.errcode) {
177                 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
178                 ctx->flags |= E2F_FLAG_ABORT;
179                 return;
180         }
181         pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
182         if (pctx.errcode) {
183                 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
184                 ctx->flags |= E2F_FLAG_ABORT;
185                 return;
186         }
187         ctx->stashed_inode = &inode;
188         pb.ctx = ctx;
189         pb.pctx = &pctx;
190         while (ino) {
191                 pctx.ino = ctx->stashed_ino = ino;
192                 if ((ino != EXT2_BAD_INO) &&
193                     (!ext2fs_test_inode_bitmap(ctx->inode_used_map, ino) ||
194                      !ext2fs_inode_has_valid_blocks(&inode)))
195                         goto next;
196
197                 pb.ino = ino;
198                 pb.dup_blocks = 0;
199                 retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
200                                               process_pass1b_block, &pb);
201                 if (pb.dup_blocks) {
202                         end_problem_latch(ctx, PR_LATCH_DBLOCK);
203                         dp = (struct dup_inode *) e2fsck_allocate_memory(ctx,
204                                     sizeof(struct dup_inode),
205                                     "duplicate inode record");
206                         dp->ino = ino;
207                         dp->dir = 0;
208                         dp->inode = inode;
209                         dp->num_dupblocks = pb.dup_blocks;
210                         dp->next = dup_ino;
211                         dup_ino = dp;
212                         if (ino != EXT2_BAD_INO)
213                                 dup_inode_count++;
214                 }
215                 if (retval)
216                         com_err(ctx->program_name, retval,
217                             _("while calling ext2fs_block_iterate in pass1b"));
218                 
219         next:
220                 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
221                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
222                         goto next;
223                 if (pctx.errcode) {
224                         fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
225                         ctx->flags |= E2F_FLAG_ABORT;
226                         return;
227                 }
228         }
229         ext2fs_close_inode_scan(scan);
230         fs->get_blocks = 0;
231         fs->check_directory = 0;
232 }
233
234 int process_pass1b_block(ext2_filsys fs,
235                          blk_t  *block_nr,
236                          int blockcnt,
237                          void *priv_data)
238 {
239         struct process_block_struct *p;
240         struct dup_block *dp, *q, *r;
241         int i;
242         e2fsck_t ctx;
243
244         if (HOLE_BLKADDR(*block_nr))
245                 return 0;
246         p = (struct process_block_struct *) priv_data;
247         ctx = p->ctx;
248         
249         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
250                 /* OK, this is a duplicate block */
251                 if (p->ino != EXT2_BAD_INO) {
252                         p->pctx->blk = *block_nr;
253                         fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
254                 }
255                 p->dup_blocks++;
256                 ext2fs_mark_block_bitmap(ctx->block_dup_map, *block_nr);
257                 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
258                 dp = (struct dup_block *) e2fsck_allocate_memory(ctx,
259                                             sizeof(struct dup_block),
260                                             "duplicate block record");
261                 dp->block = *block_nr;
262                 dp->ino = p->ino;
263                 dp->num_bad = 0;
264                 q = dup_blk;
265                 while (q) {
266                         if (q->block == *block_nr)
267                                 break;
268                         q = q->next_block;
269                 }
270                 if (q) {
271                         dp->next_inode = q->next_inode;
272                         q->next_inode = dp;
273                 } else {
274                         dp->next_block = dup_blk;
275                         dup_blk = dp;
276                 }
277         }
278         /*
279          * Set the num_bad field
280          */
281         for (q = dup_blk; q; q = q->next_block) {
282                 i = 0;
283                 for (r = q; r; r = r->next_inode)
284                         i++;
285                 q->num_bad = i;
286         }
287         return 0;
288 }
289
290 /*
291  * Pass 1c: Scan directories for inodes with duplicate blocks.  This
292  * is used so that we can print pathnames when prompting the user for
293  * what to do.
294  */
295 struct search_dir_struct {
296         int             count;
297         ino_t           first_inode;
298         ino_t           max_inode;
299 };
300
301 static int search_dirent_proc(ino_t dir, int entry,
302                               struct ext2_dir_entry *dirent,
303                               int offset, int blocksize,
304                               char *buf, void *priv_data)
305 {
306         struct search_dir_struct *sd;
307         struct dup_inode        *p;
308
309         sd = (struct search_dir_struct *) priv_data;
310
311         if (dirent->inode > sd->max_inode)
312                 /* Should abort this inode, but not everything */
313                 return 0;       
314
315         if (!dirent->inode || (entry < DIRENT_OTHER_FILE) ||
316             !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
317                 return 0;
318
319         for (p = dup_ino; p; p = p->next) {
320                 if ((p->ino >= sd->first_inode) && 
321                     (p->ino == dirent->inode))
322                         break;
323         }
324
325         if (!p || p->dir)
326                 return 0;
327
328         p->dir = dir;
329         sd->count--;
330
331         return(sd->count ? 0 : DIRENT_ABORT);
332 }
333
334
335 static void pass1c(e2fsck_t ctx, char *block_buf)
336 {
337         ext2_filsys fs = ctx->fs;
338         struct dup_inode        *p;
339         int     inodes_left = dup_inode_count;
340         struct search_dir_struct sd;
341         struct problem_context pctx;
342
343         clear_problem_context(&pctx);
344
345         fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
346
347         /*
348          * First check to see if any of the inodes with dup blocks is
349          * a special inode.  (Note that the bad block inode isn't
350          * counted.)
351          */
352         for (p = dup_ino; p; p = p->next) {
353                 if ((p->ino < EXT2_FIRST_INODE(fs->super)) &&
354                     (p->ino != EXT2_BAD_INO))
355                         inodes_left--;
356         }
357
358         /*
359          * Search through all directories to translate inodes to names
360          * (by searching for the containing directory for that inode.)
361          */
362         sd.count = inodes_left;
363         sd.first_inode = EXT2_FIRST_INODE(fs->super);
364         sd.max_inode = fs->super->s_inodes_count;
365         ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
366                                   search_dirent_proc, &sd);
367 }       
368
369 static void pass1d(e2fsck_t ctx, char *block_buf)
370 {
371         ext2_filsys fs = ctx->fs;
372         struct dup_inode        *p, *s;
373         struct dup_block        *q, *r;
374         ino_t   *shared;
375         int     shared_len;
376         int     i;
377         int     file_ok;
378         int     meta_data = 0;
379         struct problem_context pctx;
380
381         clear_problem_context(&pctx);
382         
383         fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
384         e2fsck_read_bitmaps(ctx);
385
386         pctx.num = dup_inode_count;
387         fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
388         shared = (ino_t *) e2fsck_allocate_memory(ctx,
389                                 sizeof(ino_t) * dup_inode_count,
390                                 "Shared inode list");
391         for (p = dup_ino; p; p = p->next) {
392                 shared_len = 0;
393                 file_ok = 1;
394                 if (p->ino == EXT2_BAD_INO)
395                         continue;
396
397                 /*
398                  * Search through the duplicate records to see which
399                  * inodes share blocks with this one
400                  */
401                 for (q = dup_blk; q; q = q->next_block) {
402                         /*
403                          * See if this block is used by this inode.
404                          * If it isn't, continue.
405                          */
406                         for (r = q; r; r = r->next_inode)
407                                 if (r->ino == p->ino)
408                                         break;
409                         if (!r)
410                                 continue;
411                         if (q->num_bad > 1)
412                                 file_ok = 0;
413                         if (check_if_fs_block(ctx, q->block)) {
414                                 file_ok = 0;
415                                 meta_data = 1;
416                         }
417                         
418                         /*
419                          * Add all inodes used by this block to the
420                          * shared[] --- which is a unique list, so
421                          * if an inode is already in shared[], don't
422                          * add it again.
423                          */
424                         for (r = q; r; r = r->next_inode) {
425                                 if (r->ino == p->ino)
426                                         continue;
427                                 for (i = 0; i < shared_len; i++)
428                                         if (shared[i] == r->ino)
429                                                 break;
430                                 if (i == shared_len) {
431                                         shared[shared_len++] = r->ino;
432                                 }
433                         }
434                 }
435
436                 /*
437                  * Report the inode that we are working on
438                  */
439                 pctx.inode = &p->inode;
440                 pctx.ino = p->ino;
441                 pctx.dir = p->dir;
442                 pctx.blkcount = p->num_dupblocks;
443                 pctx.num = meta_data ? shared_len+1 : shared_len;
444                 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
445                 pctx.blkcount = 0;
446                 pctx.num = 0;
447                 
448                 if (meta_data)
449                         fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
450                 
451                 for (i = 0; i < shared_len; i++) {
452                         for (s = dup_ino; s; s = s->next)
453                                 if (s->ino == shared[i])
454                                         break;
455                         if (!s)
456                                 continue;
457                         /*
458                          * Report the inode that we are sharing with
459                          */
460                         pctx.inode = &s->inode;
461                         pctx.ino = s->ino;
462                         pctx.dir = s->dir;
463                         fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
464                 }
465                 if (file_ok) {
466                         fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
467                         continue;
468                 }
469                 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
470                         pctx.errcode = clone_file(ctx, p, block_buf);
471                         if (pctx.errcode)
472                                 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
473                         else
474                                 continue;
475                 }
476                 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
477                         delete_file(ctx, p, block_buf);
478                 else
479                         ext2fs_unmark_valid(fs);
480         }
481         ext2fs_free_mem((void **) &shared);
482 }
483
484 static int delete_file_block(ext2_filsys fs,
485                              blk_t      *block_nr,
486                              int blockcnt,
487                              void *priv_data)
488 {
489         struct process_block_struct *pb;
490         struct dup_block *p;
491         e2fsck_t ctx;
492
493         pb = (struct process_block_struct *) priv_data;
494         ctx = pb->ctx;
495
496         if (HOLE_BLKADDR(*block_nr))
497                 return 0;
498
499         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
500                 for (p = dup_blk; p; p = p->next_block)
501                         if (p->block == *block_nr)
502                                 break;
503                 if (p) {
504                         p->num_bad--;
505                         if (p->num_bad == 1)
506                                 ext2fs_unmark_block_bitmap(ctx->block_dup_map,
507                                                            *block_nr);
508                 } else
509                         com_err("delete_file_block", 0,
510                             _("internal error; can't find dup_blk for %d\n"),
511                                 *block_nr);
512         } else {
513                 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
514                 ext2fs_unmark_block_bitmap(fs->block_map, *block_nr);
515         }
516                 
517         return 0;
518 }
519                 
520 static void delete_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
521 {
522         ext2_filsys fs = ctx->fs;
523         errcode_t       retval;
524         struct process_block_struct pb;
525         struct ext2_inode       inode;
526
527         pb.ino = dp->ino;
528         pb.dup_blocks = dp->num_dupblocks;
529         pb.ctx = ctx;
530         
531         retval = ext2fs_block_iterate(fs, dp->ino, 0, block_buf,
532                                       delete_file_block, &pb);
533         if (retval)
534                 com_err("delete_file", retval,
535                         _("while calling ext2fs_block_iterate for inode %d"),
536                         dp->ino);
537         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, dp->ino);
538         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, dp->ino);
539         if (ctx->inode_bad_map)
540                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, dp->ino);
541         ext2fs_unmark_inode_bitmap(fs->inode_map, dp->ino);
542         ext2fs_mark_ib_dirty(fs);
543         ext2fs_mark_bb_dirty(fs);
544         e2fsck_read_inode(ctx, dp->ino, &inode, "delete_file");
545         inode.i_links_count = 0;
546         inode.i_dtime = time(0);
547         e2fsck_write_inode(ctx, dp->ino, &inode, "delete_file");
548 }
549
550 struct clone_struct {
551         errcode_t       errcode;
552         ino_t           dir;
553         char    *buf;
554         e2fsck_t ctx;
555 };
556
557 static int clone_file_block(ext2_filsys fs,
558                             blk_t       *block_nr,
559                             int blockcnt,
560                             void *priv_data)
561 {
562         struct dup_block *p;
563         blk_t   new_block;
564         errcode_t       retval;
565         struct clone_struct *cs = (struct clone_struct *) priv_data;
566         e2fsck_t ctx;
567
568         ctx = cs->ctx;
569         
570         if (HOLE_BLKADDR(*block_nr))
571                 return 0;
572
573         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
574                 for (p = dup_blk; p; p = p->next_block)
575                         if (p->block == *block_nr)
576                                 break;
577                 if (p) {
578                         retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
579                                                   &new_block);
580                         if (retval) {
581                                 cs->errcode = retval;
582                                 return BLOCK_ABORT;
583                         }
584                         if (cs->dir) {
585                                 retval = ext2fs_set_dir_block(fs->dblist,
586                                       cs->dir, new_block, blockcnt);
587                                 if (retval) {
588                                         cs->errcode = retval;
589                                         return BLOCK_ABORT;
590                                 }
591                         }
592                         retval = io_channel_read_blk(fs->io, *block_nr, 1,
593                                                      cs->buf);
594                         if (retval) {
595                                 cs->errcode = retval;
596                                 return BLOCK_ABORT;
597                         }
598                         retval = io_channel_write_blk(fs->io, new_block, 1,
599                                                       cs->buf);
600                         if (retval) {
601                                 cs->errcode = retval;
602                                 return BLOCK_ABORT;
603                         }
604                         p->num_bad--;
605                         if (p->num_bad == 1 &&
606                             !check_if_fs_block(ctx, *block_nr))
607                                 ext2fs_unmark_block_bitmap(ctx->block_dup_map,
608                                                            *block_nr);
609                         *block_nr = new_block;
610                         ext2fs_mark_block_bitmap(ctx->block_found_map,
611                                                  new_block);
612                         ext2fs_mark_block_bitmap(fs->block_map, new_block);
613                         return BLOCK_CHANGED;
614                 } else
615                         com_err("clone_file_block", 0,
616                             _("internal error; can't find dup_blk for %d\n"),
617                                 *block_nr);
618         }
619         return 0;
620 }
621                 
622 static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
623 {
624         ext2_filsys fs = ctx->fs;
625         errcode_t       retval;
626         struct clone_struct cs;
627
628         cs.errcode = 0;
629         cs.dir = 0;
630         cs.ctx = ctx;
631         retval = ext2fs_get_mem(fs->blocksize, (void **) &cs.buf);
632         if (retval)
633                 return retval;
634
635         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dp->ino))
636                 cs.dir = dp->ino;
637         
638         retval = ext2fs_block_iterate(fs, dp->ino, 0, block_buf,
639                                       clone_file_block, &cs);
640         ext2fs_mark_bb_dirty(fs);
641         ext2fs_free_mem((void **) &cs.buf);
642         if (retval) {
643                 com_err("clone_file", retval,
644                         _("while calling ext2fs_block_iterate for inode %d"),
645                         dp->ino);
646                 return retval;
647         }
648         if (cs.errcode) {
649                 com_err("clone_file", cs.errcode,
650                         _("returned from clone_file_block"));
651                 return retval;
652         }
653         return 0;
654 }
655
656 /*
657  * This routine returns 1 if a block overlaps with one of the superblocks,
658  * group descriptors, inode bitmaps, or block bitmaps.
659  */
660 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
661 {
662         ext2_filsys fs = ctx->fs;
663         blk_t   block;
664         int     i;
665         
666         block = fs->super->s_first_data_block;
667         for (i = 0; i < fs->group_desc_count; i++) {
668
669                 /* Check superblocks/block group descriptros */
670                 if (ext2fs_bg_has_super(fs, i)) {
671                         if (test_block >= block &&
672                             (test_block <= block + fs->desc_blocks))
673                                 return 1;
674                 }
675                 
676                 /* Check the inode table */
677                 if ((fs->group_desc[i].bg_inode_table) &&
678                     (test_block >= fs->group_desc[i].bg_inode_table) &&
679                     (test_block < (fs->group_desc[i].bg_inode_table +
680                                    fs->inode_blocks_per_group)))
681                         return 1;
682
683                 /* Check the bitmap blocks */
684                 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
685                     (test_block == fs->group_desc[i].bg_inode_bitmap))
686                         return 1;
687                 
688                 block += fs->super->s_blocks_per_group;
689         }
690         return 0;
691 }