Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa3fc525 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (24 commits)
  Btrfs: don't use migrate page without CONFIG_MIGRATION
  Btrfs: deal with DIO bios that span more than one ordered extent
  Btrfs: setup blank root and fs_info for mount time
  Btrfs: fix fiemap
  Btrfs - fix race between btrfs_get_sb() and umount
  Btrfs: update inode ctime when using links
  Btrfs: make sure new inode size is ok in fallocate
  Btrfs: fix typo in fallocate to make it honor actual size
  Btrfs: avoid NULL pointer deref in try_release_extent_buffer
  Btrfs: make btrfs_add_nondir take parent inode as an argument
  Btrfs: hold i_mutex when calling btrfs_log_dentry_safe
  Btrfs: use dget_parent where we can UPDATED
  Btrfs: fix more ESTALE problems with NFS
  Btrfs: handle NFS lookups properly
  btrfs: make 1-bit signed fileds unsigned
  btrfs: Show device attr correctly for symlinks
  btrfs: Set file size correctly in file clone
  btrfs: Check if dest_offset is block-size aligned before cloning file
  Btrfs: handle the space_cache option properly
  btrfs: Fix early enospc because 'unused' calculated with wrong sign.
  ...
parents 555bdaef 5a92bc88
Loading
Loading
Loading
Loading
+1 −14
Original line number Original line Diff line number Diff line
@@ -91,23 +91,10 @@ static inline int compressed_bio_size(struct btrfs_root *root,
static struct bio *compressed_bio_alloc(struct block_device *bdev,
static struct bio *compressed_bio_alloc(struct block_device *bdev,
					u64 first_byte, gfp_t gfp_flags)
					u64 first_byte, gfp_t gfp_flags)
{
{
	struct bio *bio;
	int nr_vecs;
	int nr_vecs;


	nr_vecs = bio_get_nr_vecs(bdev);
	nr_vecs = bio_get_nr_vecs(bdev);
	bio = bio_alloc(gfp_flags, nr_vecs);
	return btrfs_bio_alloc(bdev, first_byte >> 9, nr_vecs, gfp_flags);

	if (bio == NULL && (current->flags & PF_MEMALLOC)) {
		while (!bio && (nr_vecs /= 2))
			bio = bio_alloc(gfp_flags, nr_vecs);
	}

	if (bio) {
		bio->bi_size = 0;
		bio->bi_bdev = bdev;
		bio->bi_sector = first_byte >> 9;
	}
	return bio;
}
}


static int check_compressed_csum(struct inode *inode,
static int check_compressed_csum(struct inode *inode,
+3 −3
Original line number Original line Diff line number Diff line
@@ -808,9 +808,9 @@ struct btrfs_block_group_cache {
	int extents_thresh;
	int extents_thresh;
	int free_extents;
	int free_extents;
	int total_bitmaps;
	int total_bitmaps;
	int ro:1;
	unsigned int ro:1;
	int dirty:1;
	unsigned int dirty:1;
	int iref:1;
	unsigned int iref:1;


	int disk_cache_state;
	int disk_cache_state;


+32 −6
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/freezer.h>
#include <linux/freezer.h>
#include <linux/crc32c.h>
#include <linux/crc32c.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/migrate.h>
#include "compat.h"
#include "compat.h"
#include "ctree.h"
#include "ctree.h"
#include "disk-io.h"
#include "disk-io.h"
@@ -355,6 +356,8 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
	ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE,
	ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE,
					     btrfs_header_generation(eb));
					     btrfs_header_generation(eb));
	BUG_ON(ret);
	BUG_ON(ret);
	WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN));

	found_start = btrfs_header_bytenr(eb);
	found_start = btrfs_header_bytenr(eb);
	if (found_start != start) {
	if (found_start != start) {
		WARN_ON(1);
		WARN_ON(1);
@@ -693,6 +696,29 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
				   __btree_submit_bio_done);
				   __btree_submit_bio_done);
}
}


static int btree_migratepage(struct address_space *mapping,
			struct page *newpage, struct page *page)
{
	/*
	 * we can't safely write a btree page from here,
	 * we haven't done the locking hook
	 */
	if (PageDirty(page))
		return -EAGAIN;
	/*
	 * Buffers may be managed in a filesystem specific way.
	 * We must have no buffers or drop them.
	 */
	if (page_has_private(page) &&
	    !try_to_release_page(page, GFP_KERNEL))
		return -EAGAIN;
#ifdef CONFIG_MIGRATION
	return migrate_page(mapping, newpage, page);
#else
	return -ENOSYS;
#endif
}

static int btree_writepage(struct page *page, struct writeback_control *wbc)
static int btree_writepage(struct page *page, struct writeback_control *wbc)
{
{
	struct extent_io_tree *tree;
	struct extent_io_tree *tree;
@@ -707,8 +733,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc)
	}
	}


	redirty_page_for_writepage(wbc, page);
	redirty_page_for_writepage(wbc, page);
	eb = btrfs_find_tree_block(root, page_offset(page),
	eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE);
				      PAGE_CACHE_SIZE);
	WARN_ON(!eb);
	WARN_ON(!eb);


	was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
	was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
@@ -799,6 +824,9 @@ static const struct address_space_operations btree_aops = {
	.releasepage	= btree_releasepage,
	.releasepage	= btree_releasepage,
	.invalidatepage = btree_invalidatepage,
	.invalidatepage = btree_invalidatepage,
	.sync_page	= block_sync_page,
	.sync_page	= block_sync_page,
#ifdef CONFIG_MIGRATION
	.migratepage	= btree_migratepage,
#endif
};
};


int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
@@ -1538,10 +1566,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
						 GFP_NOFS);
						 GFP_NOFS);
	struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
	struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
						 GFP_NOFS);
						 GFP_NOFS);
	struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root),
	struct btrfs_root *tree_root = btrfs_sb(sb);
					       GFP_NOFS);
	struct btrfs_fs_info *fs_info = tree_root->fs_info;
	struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info),
						GFP_NOFS);
	struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root),
	struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root),
						GFP_NOFS);
						GFP_NOFS);
	struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
	struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
+76 −0
Original line number Original line Diff line number Diff line
@@ -232,9 +232,85 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
	return ERR_PTR(ret);
	return ERR_PTR(ret);
}
}


static int btrfs_get_name(struct dentry *parent, char *name,
			  struct dentry *child)
{
	struct inode *inode = child->d_inode;
	struct inode *dir = parent->d_inode;
	struct btrfs_path *path;
	struct btrfs_root *root = BTRFS_I(dir)->root;
	struct btrfs_inode_ref *iref;
	struct btrfs_root_ref *rref;
	struct extent_buffer *leaf;
	unsigned long name_ptr;
	struct btrfs_key key;
	int name_len;
	int ret;

	if (!dir || !inode)
		return -EINVAL;

	if (!S_ISDIR(dir->i_mode))
		return -EINVAL;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->leave_spinning = 1;

	if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
		key.objectid = BTRFS_I(inode)->root->root_key.objectid;
		key.type = BTRFS_ROOT_BACKREF_KEY;
		key.offset = (u64)-1;
		root = root->fs_info->tree_root;
	} else {
		key.objectid = inode->i_ino;
		key.offset = dir->i_ino;
		key.type = BTRFS_INODE_REF_KEY;
	}

	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0) {
		btrfs_free_path(path);
		return ret;
	} else if (ret > 0) {
		if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
			path->slots[0]--;
		} else {
			btrfs_free_path(path);
			return -ENOENT;
		}
	}
	leaf = path->nodes[0];

	if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
	       rref = btrfs_item_ptr(leaf, path->slots[0],
				     struct btrfs_root_ref);
	       name_ptr = (unsigned long)(rref + 1);
	       name_len = btrfs_root_ref_name_len(leaf, rref);
	} else {
		iref = btrfs_item_ptr(leaf, path->slots[0],
				      struct btrfs_inode_ref);
		name_ptr = (unsigned long)(iref + 1);
		name_len = btrfs_inode_ref_name_len(leaf, iref);
	}

	read_extent_buffer(leaf, name, name_ptr, name_len);
	btrfs_free_path(path);

	/*
	 * have to add the null termination to make sure that reconnect_path
	 * gets the right len for strlen
	 */
	name[name_len] = '\0';

	return 0;
}

const struct export_operations btrfs_export_ops = {
const struct export_operations btrfs_export_ops = {
	.encode_fh	= btrfs_encode_fh,
	.encode_fh	= btrfs_encode_fh,
	.fh_to_dentry	= btrfs_fh_to_dentry,
	.fh_to_dentry	= btrfs_fh_to_dentry,
	.fh_to_parent	= btrfs_fh_to_parent,
	.fh_to_parent	= btrfs_fh_to_parent,
	.get_parent	= btrfs_get_parent,
	.get_parent	= btrfs_get_parent,
	.get_name	= btrfs_get_name,
};
};
+1 −1
Original line number Original line Diff line number Diff line
@@ -3412,7 +3412,7 @@ static int reserve_metadata_bytes(struct btrfs_trans_handle *trans,
	 * our reservation.
	 * our reservation.
	 */
	 */
	if (unused <= space_info->total_bytes) {
	if (unused <= space_info->total_bytes) {
		unused -= space_info->total_bytes;
		unused = space_info->total_bytes - unused;
		if (unused >= num_bytes) {
		if (unused >= num_bytes) {
			if (!reserved)
			if (!reserved)
				space_info->bytes_reserved += orig_bytes;
				space_info->bytes_reserved += orig_bytes;
Loading