From: Jan Kara <jack@suse.cz>
To: Zheng Liu <gnehzuil.liu@gmail.com>
Cc: linux-ext4@vger.kernel.org, Zheng Liu <wenqing.lz@taobao.com>,
Theodore Ts'o <tytso@mit.edu>, Jan kara <jack@suse.cz>
Subject: Re: [PATCH 09/10 v5] ext4: convert unwritten extents from extent status tree in end_io
Date: Tue, 12 Feb 2013 13:51:59 +0100 [thread overview]
Message-ID: <20130212125159.GD19583@quack.suse.cz> (raw)
In-Reply-To: <1360313046-9876-10-git-send-email-wenqing.lz@taobao.com>
On Fri 08-02-13 16:44:05, Zheng Liu wrote:
> From: Zheng Liu <wenqing.lz@taobao.com>
>
> This commit tries to convert unwritten extents from extent status tree
> in end_io callback functions and ext4_ext_direct_IO.
Why should we do this?
...
> @@ -801,3 +807,147 @@ static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei,
> tree->cache_es = NULL;
> return nr_shrunk;
> }
> +
> +int ext4_es_convert_unwritten_extents(struct inode *inode, loff_t offset,
> + size_t size)
> +{
> + struct ext4_es_tree *tree;
> + struct rb_node *node;
> + struct extent_status *es, orig_es, conv_es;
> + ext4_lblk_t end, len1, len2;
> + ext4_lblk_t lblk = 0, len = 0;
> + ext4_fsblk_t block;
> + unsigned long flags;
> + unsigned int blkbits;
> + int err = 0;
> +
> + trace_ext4_es_convert_unwritten_extents(inode, offset, size);
> + blkbits = inode->i_blkbits;
> + lblk = offset >> blkbits;
> + len = (EXT4_BLOCK_ALIGN(offset + size, blkbits) >> blkbits) - lblk;
> +
> + end = lblk + len - 1;
> + BUG_ON(end < lblk);
> +
> + tree = &EXT4_I(inode)->i_es_tree;
> +
> + write_lock_irqsave(&EXT4_I(inode)->i_es_lock, flags);
> + es = __es_tree_search(&tree->root, lblk);
> + if (!es)
> + goto out;
> + if (es->es_lblk > end)
> + goto out;
> +
> + tree->cache_es = NULL;
> +
> + orig_es.es_lblk = es->es_lblk;
> + orig_es.es_len = es->es_len;
> + orig_es.es_pblk = es->es_pblk;
> +
> + len1 = lblk > es->es_lblk ? lblk - es->es_lblk : 0;
> + len2 = ext4_es_end(es) > end ?
> + ext4_es_end(es) - end : 0;
> + if (len1 > 0)
> + es->es_len = len1;
> + if (len2 > 0) {
> + if (len1 > 0) {
> + struct extent_status newes;
> +
> + newes.es_lblk = end + 1;
> + newes.es_len = len2;
> + block = ext4_es_pblock(&orig_es) +
> + orig_es.es_len - len2;
> + ext4_es_store_pblock(&newes, block);
> + ext4_es_store_status(&newes, ext4_es_status(&orig_es));
> + err = __es_insert_extent(inode, &newes);
> + if (err) {
> + es->es_lblk = orig_es.es_lblk;
> + es->es_len = orig_es.es_len;
> + es->es_pblk = orig_es.es_pblk;
> + goto out;
> + }
> +
> + conv_es.es_lblk = orig_es.es_lblk + len1;
> + conv_es.es_len = orig_es.es_len - len1 - len2;
> + block = ext4_es_pblock(&orig_es) + len1;
> + ext4_es_store_pblock(&conv_es, block);
> + ext4_es_store_status(&conv_es, EXTENT_STATUS_WRITTEN);
> + err = __es_insert_extent(inode, &conv_es);
> + if (err) {
> + int err2 = __es_remove_extent(inode,
> + conv_es.es_lblk,
> + ext4_es_end(&newes));
> + if (err2)
> + goto out;
> + es->es_lblk = orig_es.es_lblk;
> + es->es_len = orig_es.es_len;
> + es->es_pblk = orig_es.es_pblk;
> + goto out;
> + }
> + } else {
> + es->es_lblk = end + 1;
> + es->es_len = len2;
> + block = ext4_es_pblock(&orig_es) +
> + orig_es.es_len - len2;
> + ext4_es_store_pblock(es, block);
> +
> + conv_es.es_lblk = orig_es.es_lblk;
> + conv_es.es_len = orig_es.es_len - len2;
> + ext4_es_store_pblock(&conv_es,
> + ext4_es_pblock(&orig_es));
> + ext4_es_store_status(&conv_es, EXTENT_STATUS_WRITTEN);
> + err = __es_insert_extent(inode, &conv_es);
> + if (err) {
> + es->es_lblk = orig_es.es_lblk;
> + es->es_len = orig_es.es_len;
> + es->es_pblk = orig_es.es_pblk;
> + }
> + }
> + goto out;
> + }
> +
> + if (len1 > 0) {
> + node = rb_next(&es->rb_node);
> + if (node)
> + es = rb_entry(node, struct extent_status, rb_node);
> + else
> + es = NULL;
> + }
> +
> + while (es && ext4_es_end(es) <= end) {
> + node = rb_next(&es->rb_node);
> + ext4_es_store_status(es, EXTENT_STATUS_WRITTEN);
> + if (!inode) {
> + es = NULL;
> + break;
> + }
> + es = rb_entry(node, struct extent_status, rb_node);
> + }
> +
> + if (es && es->es_lblk < end + 1) {
> + ext4_lblk_t orig_len = es->es_len;
> +
> + /*
> + * Here we first set conv_es just because of avoiding copy the
> + * value of es to a temporary variable.
> + */
> + len1 = ext4_es_end(es) - end;
> + conv_es.es_lblk = es->es_lblk;
> + conv_es.es_len = es->es_len - len1;
> + ext4_es_store_pblock(&conv_es, ext4_es_pblock(es));
> + ext4_es_store_status(&conv_es, EXTENT_STATUS_WRITTEN);
> +
> + es->es_lblk = end + 1;
> + es->es_len = len1;
> + block = ext4_es_pblock(es) + orig_len - len1;
> + ext4_es_store_pblock(es, block);
> +
> + err = __es_insert_extent(inode, &conv_es);
> + if (err)
> + goto out;
> + }
> +
> +out:
> + write_unlock_irqrestore(&EXT4_I(inode)->i_es_lock, flags);
> + return err;
> +}
Is this really needed? Why don't you just use ext4_es_insert_extent() to
insert new extent of proper type? Also the way you wrote it, we can return
(freshly written) data to the user, then reclaim the extent status from
memory and later return 0s because we read the original status from disk
(conversion hasn't still happened on disk). That would be certainly
confusing.
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
next prev parent reply other threads:[~2013-02-12 12:52 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-08 8:43 [PATCH 00/10 v5] ext4: extent status tree (step2) Zheng Liu
2013-02-08 8:43 ` [PATCH 01/10 v5] ext4: refine extent status tree Zheng Liu
2013-02-08 15:35 ` Jan Kara
2013-02-15 6:38 ` Zheng Liu
2013-02-08 8:43 ` [PATCH 02/10 v5] ext4: add physical block and status member into " Zheng Liu
2013-02-08 15:39 ` Jan Kara
2013-02-08 8:43 ` [PATCH 03/10 v5] ext4: let ext4_ext_map_blocks return EXT4_MAP_UNWRITTEN flag Zheng Liu
2013-02-08 15:41 ` Jan Kara
2013-02-08 8:44 ` [PATCH 04/10 v5] ext4: track all extent status in extent status tree Zheng Liu
2013-02-11 12:21 ` Jan Kara
2013-02-15 6:45 ` Zheng Liu
2013-02-13 3:28 ` Theodore Ts'o
2013-02-13 3:46 ` [PATCH 1/2] ext4: rename ext4_es_find_extent() to ext4_es_find_delayed_extent() Theodore Ts'o
2013-02-13 3:46 ` [PATCH 2/2] ext4: track all extent status in extent status tree Theodore Ts'o
2013-02-15 6:53 ` [PATCH 04/10 v5] " Zheng Liu
2013-02-17 16:26 ` Zheng Liu
2013-02-08 8:44 ` [PATCH 05/10 v5] ext4: lookup block mapping " Zheng Liu
2013-02-12 12:31 ` Jan Kara
2013-02-15 7:06 ` Zheng Liu
2013-02-15 16:47 ` Jan Kara
2013-02-15 17:25 ` Theodore Ts'o
2013-02-16 2:32 ` Zheng Liu
2013-02-16 16:18 ` Possible TODO projects for the map_blocks() code path (was: Re: [PATCH 05/10 v5] ext4: lookup block mapping in extent status tree) Theodore Ts'o
2013-02-17 3:15 ` Zheng Liu
2013-02-08 8:44 ` [PATCH 06/10 v5] ext4: remove single extent cache Zheng Liu
2013-02-08 8:44 ` [PATCH 07/10 v5] ext4: adjust some functions for reclaiming extents from extent status tree Zheng Liu
2013-02-08 8:44 ` [PATCH 08/10 v5] ext4: reclaim " Zheng Liu
2013-02-08 8:44 ` [PATCH 09/10 v5] ext4: convert unwritten extents from extent status tree in end_io Zheng Liu
2013-02-10 8:45 ` Zheng Liu
2013-02-11 1:52 ` Theodore Ts'o
2013-02-12 12:51 ` Jan Kara [this message]
2013-02-15 7:12 ` Zheng Liu
2013-02-08 8:44 ` [PATCH 10/10 v5] ext4: remove bogus wait for unwritten extents in ext4_ind_direct_IO Zheng Liu
2013-02-12 12:58 ` Jan Kara
2013-02-15 7:14 ` Zheng Liu
2013-02-10 1:38 ` [PATCH 00/10 v5] ext4: extent status tree (step2) Theodore Ts'o
2013-02-10 8:40 ` Zheng Liu
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=20130212125159.GD19583@quack.suse.cz \
--to=jack@suse.cz \
--cc=gnehzuil.liu@gmail.com \
--cc=linux-ext4@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=wenqing.lz@taobao.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).