Re: [PATCH] Btrfs: fix our reservations for updating an inode when completing io V3

2011-11-11 Thread Chris Mason
On Fri, Nov 11, 2011 at 01:28:36PM +0100, David Sterba wrote:
> On Thu, Nov 10, 2011 at 05:57:07PM -0500, Josef Bacik wrote:
> > --- a/fs/btrfs/ctree.h
> > +++ b/fs/btrfs/ctree.h
> > @@ -2699,8 +2699,8 @@ struct extent_map *btrfs_get_extent(struct inode 
> > *inode, struct page *page,
> > size_t pg_offset, u64 start, u64 end,
> > int create);
> >  int btrfs_update_inode(struct btrfs_trans_handle *trans,
> > - struct btrfs_root *root,
> > - struct inode *inode);
> > +  struct btrfs_root *root, struct inode *inode,
> > +  int fallback);
> 
> Can you please add a helper __btrfs_update_inode which takes the
> argument, leave btrfs_update_inode as is and add
> btrfs_update_inode_fallback for the '1' case?
> 
> So you don't change every callsite of btrfs_update_inode and just those 4
> which need _fallback variant (the rest is 29, quite a lot).

I reworked this last night since I already have v2.  See my for-linus
branch.

-chris
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Btrfs: fix our reservations for updating an inode when completing io V3

2011-11-11 Thread David Sterba
On Thu, Nov 10, 2011 at 05:57:07PM -0500, Josef Bacik wrote:
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -2699,8 +2699,8 @@ struct extent_map *btrfs_get_extent(struct inode 
> *inode, struct page *page,
>   size_t pg_offset, u64 start, u64 end,
>   int create);
>  int btrfs_update_inode(struct btrfs_trans_handle *trans,
> -   struct btrfs_root *root,
> -   struct inode *inode);
> +struct btrfs_root *root, struct inode *inode,
> +int fallback);

Can you please add a helper __btrfs_update_inode which takes the
argument, leave btrfs_update_inode as is and add
btrfs_update_inode_fallback for the '1' case?

So you don't change every callsite of btrfs_update_inode and just those 4
which need _fallback variant (the rest is 29, quite a lot).


david
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Btrfs: fix our reservations for updating an inode when completing io V3

2011-11-10 Thread Josef Bacik
People have been reporting ENOSPC crashes in finish_ordered_io.  This is because
we try to steal from the delalloc block rsv to satisfy a reservation to update
the inode.  The problem with this is we don't explicitly save space for updating
the inode when doing delalloc.  This is kind of a problem and we've gotten away
with this because way back when we just stole from the delalloc reserve without
any questions, and this worked out fine because generally speaking the leaf had
been modified either by the mtime update when we did the original write or
because we just updated the leaf when we inserted the file extent item, only on
rare occasions had the leaf not actually been modified, and that was still ok
because we'd just use a block or two out of the over-reservation that is
delalloc.

Then came the delayed inode stuff.  This is amazing, except it wants a full
reservation for updating the inode since it may do it at some point down the
road after we've written the blocks and we have to recow everything again.  This
worked out because the delayed inode stuff just stole from the global reserve,
that is until recently when I changed that because it caused other problems.

So here we are, we're doing everything right and being screwed for it.  So take
an extra reservation for the inode at delalloc reservation time and carry it
through the life of the delalloc reservation.  If we need it we can steal it in
the delayed inode stuff.  If we have already stolen it try and do a normal
metadata reservation.  If that fails try to steal from the delalloc reservation.
If _that_ fails we'll get a WARN_ON() so I can start thinking of a better way to
solve this and in the meantime we'll steal from the global reserve.

If we fail all of this, then we'll fall back to just updating the inode instead
of delaying it, since we shouldn't use that much space as we've just modified
the tree by inserting the file extent item.

With this patch I ran xfstests 13 in a loop for a couple of hours and didn't see
any problems.  Thanks,

Signed-off-by: Josef Bacik 
---
V2->V3: lxo hit one of my "we should never hit this" BUG()'s with V2.  It is
possible we could have stolen all of our extra reservations, so add an option to
btrfs_update_inode to fall back to the direct update of the inode, so in the
endio case we can make sure we update the inode and don't get ENOSPC.

 fs/btrfs/btrfs_inode.h  |4 +--
 fs/btrfs/ctree.h|4 +-
 fs/btrfs/delayed-inode.c|   58 ++-
 fs/btrfs/extent-tree.c  |   24 +++---
 fs/btrfs/free-space-cache.c |4 +-
 fs/btrfs/inode-map.c|2 +-
 fs/btrfs/inode.c|   47 +++---
 fs/btrfs/ioctl.c|6 ++--
 fs/btrfs/transaction.c  |2 +-
 fs/btrfs/tree-log.c |8 +++---
 fs/btrfs/xattr.c|2 +-
 11 files changed, 118 insertions(+), 43 deletions(-)

diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 5a5d325..634608d 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -147,14 +147,12 @@ struct btrfs_inode {
 * the btrfs file release call will add this inode to the
 * ordered operations list so that we make sure to flush out any
 * new data the application may have written before commit.
-*
-* yes, its silly to have a single bitflag, but we might grow more
-* of these.
 */
unsigned ordered_data_close:1;
unsigned orphan_meta_reserved:1;
unsigned dummy_inode:1;
unsigned in_defrag:1;
+   unsigned delalloc_meta_reserved:1;
 
/*
 * always compress this one file
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b9ba59f..5e7eca6 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2699,8 +2699,8 @@ struct extent_map *btrfs_get_extent(struct inode *inode, 
struct page *page,
size_t pg_offset, u64 start, u64 end,
int create);
 int btrfs_update_inode(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct inode *inode);
+  struct btrfs_root *root, struct inode *inode,
+  int fallback);
 int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode);
 int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode);
 int btrfs_orphan_cleanup(struct btrfs_root *root);
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index bbe8496..d4fadb2 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -617,12 +617,14 @@ static void btrfs_delayed_item_release_metadata(struct 
btrfs_root *root,
 static int btrfs_delayed_inode_reserve_metadata(
struct btrfs_trans_handle *trans,
struct btrfs_root *root,
+