Reviewed-by: Sage Weil <[email protected]>

On Sat, 21 Sep 2013, Yan, Zheng wrote:

> From: "Yan, Zheng" <[email protected]>
> 
> If directory fragments change, fill_inode() inserts new frags into
> the fragtree, but it does not remove outdated frags from the fragtree.
> This patch fixes it.
> 
> Signed-off-by: Yan, Zheng <[email protected]>
> ---
>  fs/ceph/inode.c | 32 ++++++++++++++++++++++++++++----
>  1 file changed, 28 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
> index 8549a48..cf12ea6 100644
> --- a/fs/ceph/inode.c
> +++ b/fs/ceph/inode.c
> @@ -577,6 +577,8 @@ static int fill_inode(struct inode *inode,
>       int issued = 0, implemented;
>       struct timespec mtime, atime, ctime;
>       u32 nsplits;
> +     struct ceph_inode_frag *frag;
> +     struct rb_node *rb_node;
>       struct ceph_buffer *xattr_blob = NULL;
>       int err = 0;
>       int queue_trunc = 0;
> @@ -751,15 +753,37 @@ no_change:
>       /* FIXME: move me up, if/when version reflects fragtree changes */
>       nsplits = le32_to_cpu(info->fragtree.nsplits);
>       mutex_lock(&ci->i_fragtree_mutex);
> +     rb_node = rb_first(&ci->i_fragtree);
>       for (i = 0; i < nsplits; i++) {
>               u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
> -             struct ceph_inode_frag *frag = __get_or_create_frag(ci, id);
> -
> -             if (IS_ERR(frag))
> -                     continue;
> +             frag = NULL;
> +             while (rb_node) {
> +                     frag = rb_entry(rb_node, struct ceph_inode_frag, node);
> +                     if (ceph_frag_compare(frag->frag, id) >= 0) {
> +                             if (frag->frag != id)
> +                                     frag = NULL;
> +                             else
> +                                     rb_node = rb_next(rb_node);
> +                             break;
> +                     }
> +                     rb_node = rb_next(rb_node);
> +                     rb_erase(&frag->node, &ci->i_fragtree);
> +                     kfree(frag);
> +             }
> +             if (!frag) {
> +                     frag = __get_or_create_frag(ci, id);
> +                     if (IS_ERR(frag))
> +                             continue;
> +             }
>               frag->split_by = le32_to_cpu(info->fragtree.splits[i].by);
>               dout(" frag %x split by %d\n", frag->frag, frag->split_by);
>       }
> +     while (rb_node) {
> +             frag = rb_entry(rb_node, struct ceph_inode_frag, node);
> +             rb_node = rb_next(rb_node);
> +             rb_erase(&frag->node, &ci->i_fragtree);
> +             kfree(frag);
> +     }
>       mutex_unlock(&ci->i_fragtree_mutex);
>  
>       /* were we issued a capability? */
> -- 
> 1.8.1.4
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to