All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Dilger <adilger@sun.com>
To: Eric Sandeen <sandeen@redhat.com>
Cc: ext4 development <linux-ext4@vger.kernel.org>
Subject: Re: [PATCH 2/3] reinstate ext4_ext_walk_space()
Date: Fri, 11 Apr 2008 17:31:55 -0600	[thread overview]
Message-ID: <20080411233155.GU5693@webber.adilger.int> (raw)
In-Reply-To: <47EA6ED0.6050504@redhat.com>

On Mar 26, 2008  10:42 -0500, Eric Sandeen wrote:
> the ext4 fiemap call needs this helper function.
> 
> I need to dig for the original author to see what signed-off-by
> lines should be here.

This was originally written by Alex and was in the extents patches
but later removed.

> Index: linux-2.6.25-rc1/fs/ext4/extents.c
> ===================================================================
> --- linux-2.6.25-rc1.orig/fs/ext4/extents.c
> +++ linux-2.6.25-rc1/fs/ext4/extents.c
> @@ -1588,6 +1588,112 @@ cleanup:
>  	return err;
>  }
>  
> +int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
> +			ext4_lblk_t num, ext_prepare_callback func,
> +			void *cbdata)
> +{
> +	struct ext4_ext_path *path = NULL;
> +	struct ext4_ext_cache cbex;
> +	struct ext4_extent *ex;
> +	ext4_lblk_t next, start = 0, end = 0;
> +	ext4_lblk_t last = block + num;
> +	int depth, exists, err = 0;
> +
> +	BUG_ON(func == NULL);
> +	BUG_ON(inode == NULL);
> +
> +	while (block < last && block != EXT_MAX_BLOCK) {
> +		num = last - block;
> +		/* find extent for this block */
> +		path = ext4_ext_find_extent(inode, block, path);
> +		if (IS_ERR(path)) {
> +			err = PTR_ERR(path);
> +			path = NULL;
> +			break;
> +		}
> +
> +		depth = ext_depth(inode);
> +		BUG_ON(path[depth].p_hdr == NULL);
> +		ex = path[depth].p_ext;
> +		next = ext4_ext_next_allocated_block(path);
> +
> +		exists = 0;
> +		if (!ex) {
> +			/* there is no extent yet, so try to allocate
> +			 * all requested space */
> +			start = block;
> +			end = block + num;
> +		} else if (le32_to_cpu(ex->ee_block) > block) {
> +			/* need to allocate space before found extent */
> +			start = block;
> +			end = le32_to_cpu(ex->ee_block);
> +			if (block + num < end)
> +				end = block + num;
> +		} else if (block >= le32_to_cpu(ex->ee_block)
> +					+ ext4_ext_get_actual_len(ex)) {
> +			/* need to allocate space after found extent */
> +			start = block;
> +			end = block + num;
> +			if (end >= next)
> +				end = next;
> +		} else if (block >= le32_to_cpu(ex->ee_block)) {
> +			/*
> +			 * some part of requested space is covered
> + 			 * by found extent
> + 			 */
> +			start = block;
> +			end = le32_to_cpu(ex->ee_block)
> +				+ ext4_ext_get_actual_len(ex);
> +			if (block + num < end)
> +				end = block + num;
> +			exists = 1;
> +		} else {
> +			BUG();
> +		}
> +		BUG_ON(end <= start);
> +
> +		if (!exists) {
> +			cbex.ec_block = start;
> +			cbex.ec_len = end - start;
> +			cbex.ec_start = 0;
> +			cbex.ec_type = EXT4_EXT_CACHE_GAP;
> +		} else {
> +			cbex.ec_block = le32_to_cpu(ex->ee_block);
> +			cbex.ec_len = ext4_ext_get_actual_len(ex);
> +			cbex.ec_start = ext_pblock(ex);
> +			cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
> +		}
> +
> +		BUG_ON(cbex.ec_len == 0);
> +		err = func(inode, path, &cbex, cbdata);
> +		ext4_ext_drop_refs(path);
> +
> +		if (err < 0)
> +			break;
> +		if (err == EXT_REPEAT)
> +			continue;
> +		else if (err == EXT_BREAK) {
> +			err = 0;
> +			break;
> +		}
> +
> +		if (ext_depth(inode) != depth) {
> +			/* depth was changed. we have to realloc path */
> +			kfree(path);
> +			path = NULL;
> +		}
> +
> +		block = cbex.ec_block + cbex.ec_len;
> +	}
> +
> +	if (path) {
> +		ext4_ext_drop_refs(path);
> +		kfree(path);
> +	}
> +
> +	return err;
> +}
> +
>  static void
>  ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block,
>  			__u32 len, ext4_fsblk_t start, int type)
> Index: linux-2.6.25-rc1/include/linux/ext4_fs_extents.h
> ===================================================================
> --- linux-2.6.25-rc1.orig/include/linux/ext4_fs_extents.h
> +++ linux-2.6.25-rc1/include/linux/ext4_fs_extents.h
> @@ -124,6 +124,19 @@ struct ext4_ext_path {
>  #define EXT4_EXT_CACHE_GAP	1
>  #define EXT4_EXT_CACHE_EXTENT	2
>  
> +/*
> + * to be called by ext4_ext_walk_space()
> + * negative retcode - error
> + * positive retcode - signal for ext4_ext_walk_space(), see below
> + * callback must return valid extent (passed or newly created)
> + */
> +typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
> +					struct ext4_ext_cache *,
> +					void *);
> +
> +#define EXT_CONTINUE   0
> +#define EXT_BREAK      1
> +#define EXT_REPEAT     2
>  
>  #define EXT_MAX_BLOCK	0xffffffff
>  
> @@ -221,6 +234,7 @@ extern int ext4_ext_try_to_merge(struct 
>  				 struct ext4_extent *);
>  extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *);
>  extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *);
> +extern int ext4_ext_walk_space(struct inode *, ext4_lblk_t, ext4_lblk_t, ext_prepare_callback, void *);
>  extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
>  							struct ext4_ext_path *);
>  extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *,
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


  reply	other threads:[~2008-04-11 23:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-26 15:37 [PATCH 0/3] fiemap patches (RFC/testing) Eric Sandeen
2008-03-26 15:40 ` [PATCH 1/3] vfs-level fiemap interface Eric Sandeen
2008-03-26 15:42 ` [PATCH 2/3] reinstate ext4_ext_walk_space() Eric Sandeen
2008-04-11 23:31   ` Andreas Dilger [this message]
2008-03-26 15:44 ` [PATCH 3/3] ext4 fiemap implementation Eric Sandeen
2008-03-26 23:07 ` [PATCH 0/3] fiemap patches (RFC/testing) Mingming Cao
2008-04-11 23:29 ` Andreas Dilger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080411233155.GU5693@webber.adilger.int \
    --to=adilger@sun.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=sandeen@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.