[Ocfs2-devel] [PATCH 3/3] Add inode stealing
for ocfs2_reserve_new_inode.V3
Sunil Mushran
Sunil.Mushran at oracle.com
Mon Mar 3 18:24:56 PST 2008
Tao Ma wrote:
> +static inline void ocfs2_set_inode_steal_slot(struct ocfs2_super *osb,
> + u16 slot)
> +{
> + spin_lock(&osb->osb_lock);
> + osb->s_inode_steal_slot = slot;
> + spin_unlock(&osb->osb_lock);
> +}
Shouldn't slot be s16 and not u16.
>
> +static int ocfs2_steal_inode_from_other_nodes(struct ocfs2_super *osb,
> + struct ocfs2_alloc_context *ac)
> +{
> + int status = -ENOSPC, i;
> + s16 slot = ocfs2_get_inode_steal_slot(osb);
> +
> + /*
> + * This is the first time we try to steal inodes, so begin
> + * with the node next to us first.
> + */
Change comment to:
/* Start to steal inodes from the first slot after ours. */
> + if (slot == OCFS2_INVALID_SLOT)
> + slot = osb->slot_num + 1;
> +
> + for (i = 0; i < osb->max_slots; i++, slot++) {
> + if (slot == osb->max_slots)
> + slot = 0;
> +
> + if (slot == osb->slot_num)
> + continue;
> +
> + status = ocfs2_reserve_suballoc_bits(osb, ac,
> + INODE_ALLOC_SYSTEM_INODE,
> + slot, NOT_ALLOC_NEW_GROUP);
> + if (status >= 0) {
> + ocfs2_set_inode_steal_slot(osb, slot);
> + break;
> + }
> +
> + ocfs2_free_ac_resource(ac);
> + }
> +
> + return status;
> +}
> +
if (slot == OCFS2_INVALID_SLOT)
slot = (osb->slot_num + 1 == osb->max_slots) ? 0 : osb->slot_num + 1;
while (slot != osb->slot_num) {
status = ocfs2_reserve_suballoc_bits(osb, ....);
...
ocfs2_free_ac_resource(ac);
slot = (slot + 1 == osb->max_slots) ? 0 : slot + 1;
}
Not that your code is incorrect. Other option is to not use "i"
and replace continue with a break.
> int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
> struct ocfs2_alloc_context **ac)
> {
> int status;
> + s16 slot = ocfs2_get_inode_steal_slot(osb);
> +#define OCFS2_INODE_STEAL_TIMES 10
> + static atomic_t inode_steal_times = ATOMIC_INIT(0);
Can you rename inode_steal_times to num_inodes_stolen. BTW, this
will be for all mounts which is not what we want. Why don't you
add this to ocfs2_super? s_num_inodes_stolen. In that case, protect
it using osb_lock.
>
> *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
> if (!(*ac)) {
> @@ -539,9 +584,43 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
>
> (*ac)->ac_group_search = ocfs2_block_group_search;
>
> + /*
> + * slot is set when we successfully steal inode from other nodes.
> + * It is reset in 3 places:
> + * 1. when we flush the turncate log
spelling... truncate
> + * 2. when we complete local alloc recovery.
> + * 3. when we successfully allocate from our own slot.
> + * After it is set, we will go on stealing inodes until we find the
> + * need to check our slots to see wether there is some space for us.
> + */
spelling... whether
> + if (slot != OCFS2_INVALID_SLOT &&
> + atomic_read(&inode_steal_times) < OCFS2_INODE_STEAL_TIMES)
> + goto inode_steal;
> +
> + atomic_set(&inode_steal_times, 0);
> status = ocfs2_reserve_suballoc_bits(osb, *ac,
> INODE_ALLOC_SYSTEM_INODE,
> osb->slot_num, ALLOC_NEW_GROUP);
> + if (status >= 0) {
> + status = 0;
> +
> + /*
> + * Some inodes must be freed by us, so try to allocate
> + * from our own next time.
> + */
> + if (slot != OCFS2_INVALID_SLOT)
> + ocfs2_init_inode_steal_slot(osb);
> + goto bail;
> + } else if (status < 0 && status != -ENOSPC) {
> + mlog_errno(status);
> + goto bail;
> + }
> +
> + ocfs2_free_ac_resource(*ac);
> +
> +inode_steal:
> + status = ocfs2_steal_inode_from_other_nodes(osb, *ac);
> + atomic_inc(&inode_steal_times);
> if (status < 0) {
> if (status != -ENOSPC)
> mlog_errno(status);
> diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
> index bec75af..c4e82c7 100644
> --- a/fs/ocfs2/super.c
> +++ b/fs/ocfs2/super.c
> @@ -1193,6 +1193,7 @@ static int ocfs2_mount_volume(struct super_block *sb)
> mlog_errno(status);
> goto leave;
> }
> + ocfs2_init_inode_steal_slot(osb);
>
> /* load all node-local system inodes */
> status = ocfs2_init_local_system_inodes(osb);
More information about the Ocfs2-devel
mailing list