[Ocfs2-tools-devel] [PATCH 2/4] defrag.ocfs2: Pass 1: Defrag individual files and directories
Goldwyn Rodrigues
rgoldwyn at gmail.com
Mon Jul 19 04:18:04 PDT 2010
Hi Joel,
On Sun, Jul 18, 2010 at 11:46 AM, Joel Becker <Joel.Becker at oracle.com> wrote:
> On Tue, May 11, 2010 at 11:02:34PM -0500, Goldwyn Rodrigues wrote:
>> Defragging file -
>> Allocate the maximum possible extent and copy the file into the
>> newly allocated extent. If the allocated extent is smaller than
>> the extent read from the file, write the collected data, and
>> re-use the file extent. At any point, if the number of extents
>> in the new inode increases than in the existing inode, abort.
>>
>> Defragging directory -
>> Allocate an extent, and copy dirents to the new extent, skipping
>> holes and empty dirents. For each dirent, the dirent length
>> is recalculated to optimize on space.
>>
>> TODO: Find the optimum extent size, perhaps by reading a
>> group_desc
>>
>> Signed-off-by: Goldwyn Rodrigues <rgoldwyn at suse.de>
>
> Can you break this up into three patches? The first adds
> defrag.c, which has a main function that parses options but doesn't
> actually do anything. The next patch adds file defrag, and the third
> does dir defrag.
Yes, sure. I will be travelling so won't be able to do this immediately.
> It's just that this is a lot of code to review in one email.
> It's easier if broken up, when there is a logical boundary to break it
> up. I'm going to review in multiple emails to take each piece of
> functionality one at a time.
>
>> diff --git a/defrag.ocfs2/defrag.c b/defrag.ocfs2/defrag.c
>> new file mode 100644
>> index 0000000..65c1a13
>> --- /dev/null
>> +++ b/defrag.ocfs2/defrag.c
>> @@ -0,0 +1,401 @@
>> +/* -*- mode: c; c-basic-offset: 8; -*-
>> + * vim: noexpandtab sw=8 ts=8 sts=0:
>> + *
>> + * defrag.c
>> + *
>> + * Copyright (C) 2010 Oracle. All rights reserved.
>
> Make sure you set the copyright to the company that employs you.
> Oracle can't claim ownership on code not written by an Oracle employee.
> Well, at least not without copyright assignment, and we don't really
> need to involve the lawyers, do we? ;-)
Yes, sure :)
>
>> +static errcode_t check_superblock(struct defrag_state *dst)
>> +{
>> + struct ocfs2_dinode *di = dst->dst_fs->fs_super;
>> + struct ocfs2_super_block *sb = OCFS2_RAW_SB(di);
>> + errcode_t ret = 0;
>> +
>> + if (sb->s_max_slots == 0) {
>> + printf("The superblock max_slots field is set to 0.\n");
>> + ret = OCFS2_ET_CORRUPT_SUPERBLOCK;
>> + }
>> + dst->fs_generation = di->i_fs_generation;
>> +
>> + return ret;
>> +}
>
> I don't get this. This should never happen, so why are you
> checking for it?
Hmm, I don't remember. Seems like this was left of what I copied from fsck.
>
>> +static int fs_clean(struct ocfs2_super_block *sb, char *filename)
>> +{
>> + time_t now = time(NULL);
>> + time_t next = sb->s_lastcheck + sb->s_checkinterval;
>> +
>> + if (sb->s_checkinterval > 0 && now >= next) {
>> + unsigned scaled_time;
>> + char *scaled_units;
>> +
>> + scale_time(now - sb->s_lastcheck, &scaled_time, &scaled_units);
>> + fprintf(stderr, "Filesystem has gone %u %s without"
>> + "being checked\n", scaled_time, scaled_units);
>> + return 0;
>> + }
>> +
>> + if (sb->s_mnt_count > 0) {
>> + fprintf(stderr, "Filesystem mounted for %u mounts "
>> + "without fsck. ", sb->s_mnt_count);
>> + return 0;
>> + }
>> +
>> + return 1;
>> +}
>
> And why are you detecting and printing the fsck counts?
Because I want to assume that the filesystem is perfect before we
perform defrag.fsck. However, now I feel that this number is not
incremented.
>
>> +static errcode_t recover_cluster_info(struct defrag_state *dst)
>> +{
>> + errcode_t ret = 0;
>> + struct o2cb_cluster_desc disk = {NULL, NULL}, running = {NULL, NULL};
>> +
>> + ret = o2cb_running_cluster_desc(&running);
>> + if (ret)
>> + goto bail;
>> +
>> + ret = ocfs2_fill_cluster_desc(dst->dst_fs, &disk);
>> + if (ret)
>> + goto bail;
>> +
>> + /*
>> + * If the disk matches the running cluster, there is nothing we
>> + * can fix.
>> + */
>> + if ((!running.c_stack && !disk.c_stack) ||
>> + (running.c_stack && running.c_cluster &&
>> + disk.c_stack && disk.c_cluster &&
>> + !strcmp(running.c_stack, disk.c_stack) &&
>> + !strcmp(running.c_cluster, disk.c_cluster)))
>> + goto bail;
>> +
>> +bail:
>> + o2cb_free_cluster_desc(&running);
>> + o2cb_free_cluster_desc(&disk);
>> +
>> + return ret;
>> +}
>
> I don't get this function either. It doesn't do anything.
> But...
>
>> + if (!dst->skip_o2cb && !ocfs2_mount_local(dst->dst_fs)) {
>> + ret = o2cb_init();
>> + if (ret) {
>> + com_err(whoami, ret, "while initializing the cluster");
>> + goto close;
>> + }
>> +
>> + block_signals(SIG_BLOCK);
>> + ret = ocfs2_initialize_dlm(dst->dst_fs, whoami);
>> + if (ret == O2CB_ET_INVALID_STACK_NAME) {
>> + block_signals(SIG_UNBLOCK);
>> + ret = recover_cluster_info(dst);
>
> No, no, no, no, no. If the cluster stack is invalid, you just
> error. They need to run 'tunfes.ocfs2 --update-cluster-stack' if they
> want to adjust the disk's stack information. defrag.ocfs2 shouldn't be
> touching this stuff.
Yes, I will clean this up as well.
Thanks.
--
Goldwyn
More information about the Ocfs2-tools-devel
mailing list