1 /* vi: set sw=4 ts=4: */
3 * bmove.c --- Move blocks around to make way for a particular
4 * filesystem structure.
6 * Copyright (C) 1997 Theodore Ts'o. This file may be redistributed
7 * under the terms of the GNU Public License.
16 #include <sys/types.h>
22 struct process_block_struct
{
24 struct ext2_inode
* inode
;
25 ext2fs_block_bitmap reserve
;
26 ext2fs_block_bitmap alloc_map
;
33 static int process_block(ext2_filsys fs
, blk_t
*block_nr
,
34 e2_blkcnt_t blockcnt
, blk_t ref_block
,
35 int ref_offset
, void *priv_data
)
37 struct process_block_struct
*pb
;
42 pb
= (struct process_block_struct
*) priv_data
;
43 block
= orig
= *block_nr
;
47 * Let's see if this is one which we need to relocate
49 if (ext2fs_test_block_bitmap(pb
->reserve
, block
)) {
51 if (++block
>= fs
->super
->s_blocks_count
)
52 block
= fs
->super
->s_first_data_block
;
54 pb
->error
= EXT2_ET_BLOCK_ALLOC_FAIL
;
57 } while (ext2fs_test_block_bitmap(pb
->reserve
, block
) ||
58 ext2fs_test_block_bitmap(pb
->alloc_map
, block
));
60 retval
= io_channel_read_blk(fs
->io
, orig
, 1, pb
->buf
);
65 retval
= io_channel_write_blk(fs
->io
, block
, 1, pb
->buf
);
71 ext2fs_mark_block_bitmap(pb
->alloc_map
, block
);
73 if (pb
->flags
& EXT2_BMOVE_DEBUG
)
74 printf("ino=%ld, blockcnt=%lld, %d->%d\n", pb
->ino
,
75 blockcnt
, orig
, block
);
78 retval
= ext2fs_add_dir_block(fs
->dblist
, pb
->ino
,
79 block
, (int) blockcnt
);
88 errcode_t
ext2fs_move_blocks(ext2_filsys fs
,
89 ext2fs_block_bitmap reserve
,
90 ext2fs_block_bitmap alloc_map
,
94 struct ext2_inode inode
;
96 struct process_block_struct pb
;
100 retval
= ext2fs_open_inode_scan(fs
, 0, &scan
);
104 pb
.reserve
= reserve
;
106 pb
.alloc_map
= alloc_map
? alloc_map
: fs
->block_map
;
109 retval
= ext2fs_get_mem(fs
->blocksize
* 4, &block_buf
);
112 pb
.buf
= block_buf
+ fs
->blocksize
* 3;
115 * If GET_DBLIST is set in the flags field, then we should
116 * gather directory block information while we're doing the
119 if (flags
& EXT2_BMOVE_GET_DBLIST
) {
120 ext2fs_free_dblist(fs
->dblist
);
122 retval
= ext2fs_init_dblist(fs
, 0);
127 retval
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
132 if ((inode
.i_links_count
== 0) ||
133 !ext2fs_inode_has_valid_blocks(&inode
))
139 pb
.add_dir
= (LINUX_S_ISDIR(inode
.i_mode
) &&
140 flags
& EXT2_BMOVE_GET_DBLIST
);
142 retval
= ext2fs_block_iterate2(fs
, ino
, 0, block_buf
,
150 retval
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
151 if (retval
== EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
)