Skip to content

Commit

Permalink
Merge branch 'integration-4.8' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/fdmanana/linux into for-linus-4.8
  • Loading branch information
masoncl committed Aug 5, 2016
2 parents 42049bf + e657149 commit 1083881
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 59 deletions.
27 changes: 0 additions & 27 deletions fs/btrfs/delayed-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,33 +862,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
return 0;
}

int btrfs_add_delayed_qgroup_reserve(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 ref_root, u64 bytenr, u64 num_bytes)
{
struct btrfs_delayed_ref_root *delayed_refs;
struct btrfs_delayed_ref_head *ref_head;
int ret = 0;

if (!fs_info->quota_enabled || !is_fstree(ref_root))
return 0;

delayed_refs = &trans->transaction->delayed_refs;

spin_lock(&delayed_refs->lock);
ref_head = find_ref_head(&delayed_refs->href_root, bytenr, 0);
if (!ref_head) {
ret = -ENOENT;
goto out;
}
WARN_ON(ref_head->qgroup_reserved || ref_head->qgroup_ref_root);
ref_head->qgroup_ref_root = ref_root;
ref_head->qgroup_reserved = num_bytes;
out:
spin_unlock(&delayed_refs->lock);
return ret;
}

int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes,
Expand Down
3 changes: 0 additions & 3 deletions fs/btrfs/delayed-ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
u64 parent, u64 ref_root,
u64 owner, u64 offset, u64 reserved, int action,
struct btrfs_delayed_extent_op *extent_op);
int btrfs_add_delayed_qgroup_reserve(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 ref_root, u64 bytenr, u64 num_bytes);
int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes,
Expand Down
8 changes: 8 additions & 0 deletions fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2033,6 +2033,14 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
*/
clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
&BTRFS_I(inode)->runtime_flags);
/*
* An ordered extent might have started before and completed
* already with io errors, in which case the inode was not
* updated and we end up here. So check the inode's mapping
* flags for any errors that might have happened while doing
* writeback of file data.
*/
ret = btrfs_inode_check_errors(inode);
inode_unlock(inode);
goto out;
}
Expand Down
46 changes: 36 additions & 10 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3436,10 +3436,10 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
found_key.offset = 0;
inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
ret = PTR_ERR_OR_ZERO(inode);
if (ret && ret != -ESTALE)
if (ret && ret != -ENOENT)
goto out;

if (ret == -ESTALE && root == root->fs_info->tree_root) {
if (ret == -ENOENT && root == root->fs_info->tree_root) {
struct btrfs_root *dead_root;
struct btrfs_fs_info *fs_info = root->fs_info;
int is_dead_root = 0;
Expand Down Expand Up @@ -3475,7 +3475,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
* Inode is already gone but the orphan item is still there,
* kill the orphan item.
*/
if (ret == -ESTALE) {
if (ret == -ENOENT) {
trans = btrfs_start_transaction(root, 1);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
Expand Down Expand Up @@ -3634,7 +3634,7 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf,
/*
* read an inode from the btree into the in-memory inode
*/
static void btrfs_read_locked_inode(struct inode *inode)
static int btrfs_read_locked_inode(struct inode *inode)
{
struct btrfs_path *path;
struct extent_buffer *leaf;
Expand All @@ -3653,14 +3653,19 @@ static void btrfs_read_locked_inode(struct inode *inode)
filled = true;

path = btrfs_alloc_path();
if (!path)
if (!path) {
ret = -ENOMEM;
goto make_bad;
}

memcpy(&location, &BTRFS_I(inode)->location, sizeof(location));

ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
if (ret)
if (ret) {
if (ret > 0)
ret = -ENOENT;
goto make_bad;
}

leaf = path->nodes[0];

Expand Down Expand Up @@ -3813,11 +3818,12 @@ static void btrfs_read_locked_inode(struct inode *inode)
}

btrfs_update_iflags(inode);
return;
return 0;

make_bad:
btrfs_free_path(path);
make_bad_inode(inode);
return ret;
}

/*
Expand Down Expand Up @@ -4205,6 +4211,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
int err = 0;
struct btrfs_root *root = BTRFS_I(dir)->root;
struct btrfs_trans_handle *trans;
u64 last_unlink_trans;

if (inode->i_size > BTRFS_EMPTY_DIR_SIZE)
return -ENOTEMPTY;
Expand All @@ -4227,11 +4234,27 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
if (err)
goto out;

last_unlink_trans = BTRFS_I(inode)->last_unlink_trans;

/* now the directory is empty */
err = btrfs_unlink_inode(trans, root, dir, d_inode(dentry),
dentry->d_name.name, dentry->d_name.len);
if (!err)
if (!err) {
btrfs_i_size_write(inode, 0);
/*
* Propagate the last_unlink_trans value of the deleted dir to
* its parent directory. This is to prevent an unrecoverable
* log tree in the case we do something like this:
* 1) create dir foo
* 2) create snapshot under dir foo
* 3) delete the snapshot
* 4) rmdir foo
* 5) mkdir foo
* 6) fsync foo or some file inside foo
*/
if (last_unlink_trans >= trans->transid)
BTRFS_I(dir)->last_unlink_trans = last_unlink_trans;
}
out:
btrfs_end_transaction(trans, root);
btrfs_btree_balance_dirty(root);
Expand Down Expand Up @@ -5607,7 +5630,9 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
return ERR_PTR(-ENOMEM);

if (inode->i_state & I_NEW) {
btrfs_read_locked_inode(inode);
int ret;

ret = btrfs_read_locked_inode(inode);
if (!is_bad_inode(inode)) {
inode_tree_add(inode);
unlock_new_inode(inode);
Expand All @@ -5616,7 +5641,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
} else {
unlock_new_inode(inode);
iput(inode);
inode = ERR_PTR(-ESTALE);
ASSERT(ret < 0);
inode = ERR_PTR(ret < 0 ? ret : -ESTALE);
}
}

Expand Down
Loading

0 comments on commit 1083881

Please sign in to comment.