[Ocfs2-tools-devel] Add compress dirs option in fsck.ocfs2
Joel Becker
Joel.Becker at oracle.com
Tue Sep 1 13:29:04 PDT 2009
On Mon, Aug 31, 2009 at 06:47:00PM -0500, Goldwyn Rodrigues wrote:
> @@ -804,8 +807,29 @@ static unsigned pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe,
> dirent->name, (uint64_t)dirent->inode);
> o2fsck_icount_delta(dd->ost->ost_icount_refs, dirent->inode, 1);
> next:
> - offset += dirent->rec_len;
> + saved_reclen = dirent->rec_len;
> + if (dd->ost->ost_compress_dirs) {
> + if (prev && prev->inode) {
> + /*Bring previous rec_len to required space */
> + prev->rec_len = OCFS2_DIR_REC_LEN(prev->name_len);
> + write_off += prev->rec_len;
> + }
> + if (write_off < offset) {
> + verbosef("ino: %llu woff: %u off: %u\n",
> + dirent->inode, write_off, offset);
> + memmove(dd->dirblock_buf + write_off,
> + dd->dirblock_buf + offset,
> + OCFS2_DIR_REC_LEN(dirent->name_len));
> + dirent = (struct ocfs2_dir_entry *)(dd->dirblock_buf + write_off);
> + /* Cover space from our new location to
> + * the next dirent */
> + dirent->rec_len = saved_reclen + offset - write_off;
> +
> + ret_flags |= OCFS2_DIRENT_CHANGED;
> + }
> + }
> prev = dirent;
> + offset += saved_reclen;
> }
Two things. First, what about empty records? Imagine you've
just seen a dirent, set its rec_len to saved_reclen+offset-write_off.
You set prev=dirent. Then next pass is a deleted dirent, dirent->inode
= 0. You skip this block and set prev=dirent. Then you come to another
valid dirent. However, prev->inode is zero, and so you won't update the
first dirent's rec_len, nor will you update write_off correctly.
Second thing, when you reach the end of the block there is no
guarantee the last dirent->rec_len covers the entire block. It will if
it was the last dirent, but not if there were empty ones after it.
Joel
--
Life's Little Instruction Book #337
"Reread your favorite book."
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
More information about the Ocfs2-tools-devel
mailing list