Skip to content

Commit

Permalink
Merge branch 'for-chris' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/arne/btrfs-unstable-arne into inode_numbers

Conflicts:
	fs/btrfs/Makefile
	fs/btrfs/ctree.h
	fs/btrfs/volumes.h

Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Chris Mason committed May 23, 2011
2 parents aa2dfb3 + 8628764 commit 7126733
Show file tree
Hide file tree
Showing 13 changed files with 1,649 additions and 13 deletions.
2 changes: 1 addition & 1 deletion fs/btrfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
extent_map.o sysfs.o struct-funcs.o xattr.o ordered-data.o \
extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \
export.o tree-log.o acl.o free-space-cache.o zlib.o lzo.o \
compression.o delayed-ref.o relocation.o delayed-inode.o
compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o
42 changes: 38 additions & 4 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/fs.h>
#include <linux/rwsem.h>
#include <linux/completion.h>
#include <linux/backing-dev.h>
#include <linux/wait.h>
Expand All @@ -33,6 +34,7 @@
#include "extent_io.h"
#include "extent_map.h"
#include "async-thread.h"
#include "ioctl.h"

struct btrfs_trans_handle;
struct btrfs_transaction;
Expand Down Expand Up @@ -193,7 +195,6 @@ struct btrfs_mapping_tree {
struct extent_map_tree map_tree;
};

#define BTRFS_UUID_SIZE 16
struct btrfs_dev_item {
/* the internal btrfs device id */
__le64 devid;
Expand Down Expand Up @@ -300,7 +301,6 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
sizeof(struct btrfs_stripe) * (num_stripes - 1);
}

#define BTRFS_FSID_SIZE 16
#define BTRFS_HEADER_FLAG_WRITTEN (1ULL << 0)
#define BTRFS_HEADER_FLAG_RELOC (1ULL << 1)

Expand Down Expand Up @@ -516,6 +516,12 @@ struct btrfs_extent_item_v0 {
/* use full backrefs for extent pointers in the block */
#define BTRFS_BLOCK_FLAG_FULL_BACKREF (1ULL << 8)

/*
* this flag is only used internally by scrub and may be changed at any time
* it is only declared here to avoid collisions
*/
#define BTRFS_EXTENT_FLAG_SUPER (1ULL << 48)

struct btrfs_tree_block_info {
struct btrfs_disk_key key;
u8 level;
Expand Down Expand Up @@ -1083,6 +1089,17 @@ struct btrfs_fs_info {

void *bdev_holder;

/* private scrub information */
struct mutex scrub_lock;
atomic_t scrubs_running;
atomic_t scrub_pause_req;
atomic_t scrubs_paused;
atomic_t scrub_cancel_req;
wait_queue_head_t scrub_pause_wait;
struct rw_semaphore scrub_super_lock;
int scrub_workers_refcnt;
struct btrfs_workers scrub_workers;

/* filesystem state */
u64 fs_state;

Expand Down Expand Up @@ -2422,8 +2439,11 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path,
u64 bytenr, int cow);
int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start,
u64 end, struct list_head *list);
int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_path *path,
u64 isize);
int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
struct list_head *list, int search_commit);
/* inode.c */

/* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */
Expand Down Expand Up @@ -2577,4 +2597,18 @@ void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans,
u64 *bytes_to_reserve);
void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
struct btrfs_pending_snapshot *pending);

/* scrub.c */
int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end,
struct btrfs_scrub_progress *progress, int readonly);
int btrfs_scrub_pause(struct btrfs_root *root);
int btrfs_scrub_pause_super(struct btrfs_root *root);
int btrfs_scrub_continue(struct btrfs_root *root);
int btrfs_scrub_continue_super(struct btrfs_root *root);
int btrfs_scrub_cancel(struct btrfs_root *root);
int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev);
int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid);
int btrfs_scrub_progress(struct btrfs_root *root, u64 devid,
struct btrfs_scrub_progress *progress);

#endif
12 changes: 12 additions & 0 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1654,6 +1654,17 @@ struct btrfs_root *open_ctree(struct super_block *sb,
}
btrfs_init_delayed_root(fs_info->delayed_root);

mutex_init(&fs_info->scrub_lock);
atomic_set(&fs_info->scrubs_running, 0);
atomic_set(&fs_info->scrub_pause_req, 0);
atomic_set(&fs_info->scrubs_paused, 0);
atomic_set(&fs_info->scrub_cancel_req, 0);
init_waitqueue_head(&fs_info->scrub_pause_wait);
init_rwsem(&fs_info->scrub_super_lock);
fs_info->scrub_workers_refcnt = 0;
btrfs_init_workers(&fs_info->scrub_workers, "scrub",
fs_info->thread_pool_size, &fs_info->generic_worker);

sb->s_blocksize = 4096;
sb->s_blocksize_bits = blksize_bits(4096);
sb->s_bdi = &fs_info->bdi;
Expand Down Expand Up @@ -2488,6 +2499,7 @@ int close_ctree(struct btrfs_root *root)
fs_info->closing = 1;
smp_mb();

btrfs_scrub_cancel(root);
btrfs_put_block_group_cache(fs_info);

/*
Expand Down
8 changes: 7 additions & 1 deletion fs/btrfs/file-item.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
}

int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
struct list_head *list)
struct list_head *list, int search_commit)
{
struct btrfs_key key;
struct btrfs_path *path;
Expand All @@ -284,6 +284,12 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
path = btrfs_alloc_path();
BUG_ON(!path);

if (search_commit) {
path->skip_locking = 1;
path->reada = 2;
path->search_commit_root = 1;
}

key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
key.offset = start;
key.type = BTRFS_EXTENT_CSUM_KEY;
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ static noinline int csum_exist_in_range(struct btrfs_root *root,
LIST_HEAD(list);

ret = btrfs_lookup_csums_range(root->fs_info->csum_root, bytenr,
bytenr + num_bytes - 1, &list);
bytenr + num_bytes - 1, &list, 0);
if (ret == 0 && list_empty(&list))
return 0;

Expand Down
131 changes: 131 additions & 0 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1809,6 +1809,75 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg)
return ret;
}

static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg)
{
struct btrfs_ioctl_fs_info_args fi_args;
struct btrfs_device *device;
struct btrfs_device *next;
struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;

fi_args.num_devices = fs_devices->num_devices;
fi_args.max_id = 0;
memcpy(&fi_args.fsid, root->fs_info->fsid, sizeof(fi_args.fsid));

mutex_lock(&fs_devices->device_list_mutex);
list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) {
if (device->devid > fi_args.max_id)
fi_args.max_id = device->devid;
}
mutex_unlock(&fs_devices->device_list_mutex);

if (copy_to_user(arg, &fi_args, sizeof(fi_args)))
return -EFAULT;

return 0;
}

static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg)
{
struct btrfs_ioctl_dev_info_args *di_args;
struct btrfs_device *dev;
struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
int ret = 0;
char *s_uuid = NULL;
char empty_uuid[BTRFS_UUID_SIZE] = {0};

if (!capable(CAP_SYS_ADMIN))
return -EPERM;

di_args = memdup_user(arg, sizeof(*di_args));
if (IS_ERR(di_args))
return PTR_ERR(di_args);

if (memcmp(empty_uuid, di_args->uuid, BTRFS_UUID_SIZE) != 0)
s_uuid = di_args->uuid;

mutex_lock(&fs_devices->device_list_mutex);
dev = btrfs_find_device(root, di_args->devid, s_uuid, NULL);
mutex_unlock(&fs_devices->device_list_mutex);

if (!dev) {
ret = -ENODEV;
goto out;
}

di_args->devid = dev->devid;
di_args->bytes_used = dev->bytes_used;
di_args->total_bytes = dev->total_bytes;
memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
strncpy(di_args->path, dev->name, sizeof(di_args->path));

out:
if (ret == 0 && copy_to_user(arg, di_args, sizeof(*di_args)))
ret = -EFAULT;

kfree(di_args);
return ret;
}

static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
u64 off, u64 olen, u64 destoff)
{
Expand Down Expand Up @@ -2471,6 +2540,58 @@ static noinline long btrfs_ioctl_wait_sync(struct file *file, void __user *argp)
return btrfs_wait_for_commit(root, transid);
}

static long btrfs_ioctl_scrub(struct btrfs_root *root, void __user *arg)
{
int ret;
struct btrfs_ioctl_scrub_args *sa;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;

sa = memdup_user(arg, sizeof(*sa));
if (IS_ERR(sa))
return PTR_ERR(sa);

ret = btrfs_scrub_dev(root, sa->devid, sa->start, sa->end,
&sa->progress, sa->flags & BTRFS_SCRUB_READONLY);

if (copy_to_user(arg, sa, sizeof(*sa)))
ret = -EFAULT;

kfree(sa);
return ret;
}

static long btrfs_ioctl_scrub_cancel(struct btrfs_root *root, void __user *arg)
{
if (!capable(CAP_SYS_ADMIN))
return -EPERM;

return btrfs_scrub_cancel(root);
}

static long btrfs_ioctl_scrub_progress(struct btrfs_root *root,
void __user *arg)
{
struct btrfs_ioctl_scrub_args *sa;
int ret;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;

sa = memdup_user(arg, sizeof(*sa));
if (IS_ERR(sa))
return PTR_ERR(sa);

ret = btrfs_scrub_progress(root, sa->devid, &sa->progress);

if (copy_to_user(arg, sa, sizeof(*sa)))
ret = -EFAULT;

kfree(sa);
return ret;
}

long btrfs_ioctl(struct file *file, unsigned int
cmd, unsigned long arg)
{
Expand Down Expand Up @@ -2510,6 +2631,10 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_add_dev(root, argp);
case BTRFS_IOC_RM_DEV:
return btrfs_ioctl_rm_dev(root, argp);
case BTRFS_IOC_FS_INFO:
return btrfs_ioctl_fs_info(root, argp);
case BTRFS_IOC_DEV_INFO:
return btrfs_ioctl_dev_info(root, argp);
case BTRFS_IOC_BALANCE:
return btrfs_balance(root->fs_info->dev_root);
case BTRFS_IOC_CLONE:
Expand All @@ -2533,6 +2658,12 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_start_sync(file, argp);
case BTRFS_IOC_WAIT_SYNC:
return btrfs_ioctl_wait_sync(file, argp);
case BTRFS_IOC_SCRUB:
return btrfs_ioctl_scrub(root, argp);
case BTRFS_IOC_SCRUB_CANCEL:
return btrfs_ioctl_scrub_cancel(root, argp);
case BTRFS_IOC_SCRUB_PROGRESS:
return btrfs_ioctl_scrub_progress(root, argp);
}

return -ENOTTY;
Expand Down
Loading

0 comments on commit 7126733

Please sign in to comment.