#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <linux/random.h>
-#include <linux/version.h>
#include <asm/div64.h>
#include "compat.h"
#include "ctree.h"
u64 devid, u8 *uuid)
{
struct btrfs_device *dev;
- struct list_head *cur;
- list_for_each(cur, head) {
- dev = list_entry(cur, struct btrfs_device, dev_list);
+ list_for_each_entry(dev, head, dev_list) {
if (dev->devid == devid &&
(!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) {
return dev;
static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid)
{
- struct list_head *cur;
struct btrfs_fs_devices *fs_devices;
- list_for_each(cur, &fs_uuids) {
- fs_devices = list_entry(cur, struct btrfs_fs_devices, list);
+ list_for_each_entry(fs_devices, &fs_uuids, list) {
if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0)
return fs_devices;
}
* the list if the block device is congested. This way, multiple devices
* can make progress from a single worker thread.
*/
-static int noinline run_scheduled_bios(struct btrfs_device *device)
+static noinline int run_scheduled_bios(struct btrfs_device *device)
{
struct bio *pending;
struct backing_dev_info *bdi;
loop:
spin_lock(&device->io_lock);
+loop_lock:
/* take all the bios off the list at once and process them
* later on (without the lock held). But, remember the
* tail and other pointers so the bios can be properly reinserted
}
spin_unlock(&device->io_lock);
- while(pending) {
+ while (pending) {
cur = pending;
pending = pending->bi_next;
cur->bi_next = NULL;
* is now congested. Back off and let other work structs
* run instead
*/
- if (pending && bdi_write_congested(bdi) &&
+ if (pending && bdi_write_congested(bdi) && num_run > 16 &&
fs_info->fs_devices->open_devices > 1) {
struct bio *old_head;
else
device->pending_bio_tail = tail;
+ device->running_pending = 1;
+
spin_unlock(&device->io_lock);
btrfs_requeue_work(&device->work);
goto done;
}
if (again)
goto loop;
+
+ spin_lock(&device->io_lock);
+ if (device->pending_bios)
+ goto loop_lock;
+ spin_unlock(&device->io_lock);
done:
return 0;
}
int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices)
{
- struct list_head *tmp;
- struct list_head *cur;
- struct btrfs_device *device;
+ struct btrfs_device *device, *next;
mutex_lock(&uuid_mutex);
again:
- list_for_each_safe(cur, tmp, &fs_devices->devices) {
- device = list_entry(cur, struct btrfs_device, dev_list);
+ list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) {
if (device->in_fs_metadata)
continue;
static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
{
- struct list_head *cur;
struct btrfs_device *device;
if (--fs_devices->opened > 0)
return 0;
- list_for_each(cur, &fs_devices->devices) {
- device = list_entry(cur, struct btrfs_device, dev_list);
+ list_for_each_entry(device, &fs_devices->devices, dev_list) {
if (device->bdev) {
close_bdev_exclusive(device->bdev, device->mode);
fs_devices->open_devices--;
{
struct block_device *bdev;
struct list_head *head = &fs_devices->devices;
- struct list_head *cur;
struct btrfs_device *device;
struct block_device *latest_bdev = NULL;
struct buffer_head *bh;
int seeding = 1;
int ret = 0;
- list_for_each(cur, head) {
- device = list_entry(cur, struct btrfs_device, dev_list);
+ list_for_each_entry(device, head, dev_list) {
if (device->bdev)
continue;
if (!device->name)
bdev = open_bdev_exclusive(device->name, flags, holder);
if (IS_ERR(bdev)) {
- printk("open %s failed\n", device->name);
+ printk(KERN_INFO "open %s failed\n", device->name);
goto error;
}
set_blocksize(bdev, 4096);
devid = le64_to_cpu(disk_super->dev_item.devid);
transid = btrfs_super_generation(disk_super);
if (disk_super->label[0])
- printk("device label %s ", disk_super->label);
+ printk(KERN_INFO "device label %s ", disk_super->label);
else {
/* FIXME, make a readl uuid parser */
- printk("device fsid %llx-%llx ",
+ printk(KERN_INFO "device fsid %llx-%llx ",
*(unsigned long long *)disk_super->fsid,
*(unsigned long long *)(disk_super->fsid + 8));
}
- printk("devid %Lu transid %Lu %s\n", devid, transid, path);
+ printk(KERN_CONT "devid %llu transid %llu %s\n",
+ (unsigned long long)devid, (unsigned long long)transid, path);
ret = device_list_add(path, disk_super, devid, fs_devices_ret);
brelse(bh);
goto check_pending;
}
}
- if (btrfs_key_type(&key) != BTRFS_DEV_EXTENT_KEY) {
+ if (btrfs_key_type(&key) != BTRFS_DEV_EXTENT_KEY)
goto next;
- }
start_found = 1;
dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent);
if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) &&
root->fs_info->fs_devices->rw_devices <= 4) {
- printk("btrfs: unable to go below four devices on raid10\n");
+ printk(KERN_ERR "btrfs: unable to go below four devices "
+ "on raid10\n");
ret = -EINVAL;
goto out;
}
if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) &&
root->fs_info->fs_devices->rw_devices <= 2) {
- printk("btrfs: unable to go below two devices on raid1\n");
+ printk(KERN_ERR "btrfs: unable to go below two "
+ "devices on raid1\n");
ret = -EINVAL;
goto out;
}
if (strcmp(device_path, "missing") == 0) {
- struct list_head *cur;
struct list_head *devices;
struct btrfs_device *tmp;
device = NULL;
devices = &root->fs_info->fs_devices->devices;
- list_for_each(cur, devices) {
- tmp = list_entry(cur, struct btrfs_device, dev_list);
+ list_for_each_entry(tmp, devices, dev_list) {
if (tmp->in_fs_metadata && !tmp->bdev) {
device = tmp;
break;
bh = NULL;
disk_super = NULL;
if (!device) {
- printk("btrfs: no missing devices found to remove\n");
+ printk(KERN_ERR "btrfs: no missing devices found to "
+ "remove\n");
goto out;
}
} else {
}
if (device->writeable && root->fs_info->fs_devices->rw_devices == 1) {
- printk("btrfs: unable to remove the only writeable device\n");
+ printk(KERN_ERR "btrfs: unable to remove the only writeable "
+ "device\n");
ret = -EINVAL;
goto error_brelse;
}
struct btrfs_trans_handle *trans;
struct btrfs_device *device;
struct block_device *bdev;
- struct list_head *cur;
struct list_head *devices;
struct super_block *sb = root->fs_info->sb;
u64 total_bytes;
return -EINVAL;
bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder);
- if (!bdev) {
+ if (!bdev)
return -EIO;
- }
if (root->fs_info->fs_devices->seeding) {
seeding_dev = 1;
mutex_lock(&root->fs_info->volume_mutex);
devices = &root->fs_info->fs_devices->devices;
- list_for_each(cur, devices) {
- device = list_entry(cur, struct btrfs_device, dev_list);
+ list_for_each_entry(device, devices, dev_list) {
if (device->bdev == bdev) {
ret = -EEXIST;
goto error;
goto out;
}
-static int noinline btrfs_update_device(struct btrfs_trans_handle *trans,
- struct btrfs_device *device)
+static noinline int btrfs_update_device(struct btrfs_trans_handle *trans,
+ struct btrfs_device *device)
{
int ret;
struct btrfs_path *path;
int ret;
int i;
- printk("btrfs relocating chunk %llu\n",
+ printk(KERN_INFO "btrfs relocating chunk %llu\n",
(unsigned long long)chunk_offset);
root = root->fs_info->chunk_root;
extent_root = root->fs_info->extent_root;
int btrfs_balance(struct btrfs_root *dev_root)
{
int ret;
- struct list_head *cur;
struct list_head *devices = &dev_root->fs_info->fs_devices->devices;
struct btrfs_device *device;
u64 old_size;
dev_root = dev_root->fs_info->dev_root;
/* step one make some room on all the devices */
- list_for_each(cur, devices) {
- device = list_entry(cur, struct btrfs_device, dev_list);
+ list_for_each_entry(device, devices, dev_list) {
old_size = device->total_bytes;
size_to_free = div_factor(old_size, 1);
size_to_free = min(size_to_free, (u64)1 * 1024 * 1024);
key.offset = (u64)-1;
key.type = BTRFS_CHUNK_ITEM_KEY;
- while(1) {
+ while (1) {
ret = btrfs_search_slot(NULL, chunk_root, &key, path, 0, 0);
if (ret < 0)
goto error;
return 0;
}
-static u64 noinline chunk_bytes_by_type(u64 type, u64 calc_size,
+static noinline u64 chunk_bytes_by_type(u64 type, u64 calc_size,
int num_stripes, int sub_stripes)
{
if (type & (BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_DUP))
min_free += 1024 * 1024;
INIT_LIST_HEAD(&private_devs);
- while(index < num_stripes) {
+ while (index < num_stripes) {
device = list_entry(cur, struct btrfs_device, dev_alloc_list);
BUG_ON(!device->writeable);
if (device->total_bytes > device->bytes_used)
return 0;
}
-static int noinline init_first_rw_device(struct btrfs_trans_handle *trans,
+static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_device *device)
{
{
struct extent_map *em;
- while(1) {
+ while (1) {
spin_lock(&tree->map_tree.lock);
em = lookup_extent_mapping(&tree->map_tree, 0, (u64)-1);
if (em)
int max_errors = 0;
struct btrfs_multi_bio *multi = NULL;
- if (multi_ret && !(rw & (1 << BIO_RW))) {
+ if (multi_ret && !(rw & (1 << BIO_RW)))
stripes_allocated = 1;
- }
again:
if (multi_ret) {
multi = kzalloc(btrfs_multi_bio_size(stripes_allocated),
return 0;
if (!em) {
- printk("unable to find logical %Lu len %Lu\n", logical, *length);
+ printk(KERN_CRIT "unable to find logical %llu len %llu\n",
+ (unsigned long long)logical,
+ (unsigned long long)*length);
BUG();
}
device = map->stripes[stripe_index].dev;
if (device->bdev) {
bdi = blk_get_backing_dev_info(device->bdev);
- if (bdi->unplug_io_fn) {
+ if (bdi->unplug_io_fn)
bdi->unplug_io_fn(bdi, unplug_page);
- }
}
} else {
multi->stripes[i].physical =
* This will add one bio to the pending list for a device and make sure
* the work struct is scheduled.
*/
-static int noinline schedule_bio(struct btrfs_root *root,
+static noinline int schedule_bio(struct btrfs_root *root,
struct btrfs_device *device,
int rw, struct bio *bio)
{
total_devs = multi->num_stripes;
if (map_length < length) {
- printk("mapping failed logical %Lu bio len %Lu "
- "len %Lu\n", logical, length, map_length);
+ printk(KERN_CRIT "mapping failed logical %llu bio len %llu "
+ "len %llu\n", (unsigned long long)logical,
+ (unsigned long long)length,
+ (unsigned long long)map_length);
BUG();
}
multi->end_io = first_bio->bi_end_io;
multi->orig_bio = first_bio;
atomic_set(&multi->stripes_pending, multi->num_stripes);
- while(dev_nr < total_devs) {
+ while (dev_nr < total_devs) {
if (total_devs > 1) {
if (dev_nr < total_devs - 1) {
bio = bio_clone(first_bio, GFP_NOFS);
return -EIO;
if (!device) {
- printk("warning devid %Lu missing\n", devid);
+ printk(KERN_WARNING "warning devid %llu missing\n",
+ (unsigned long long)devid);
device = add_missing_dev(root, devid, dev_uuid);
if (!device)
return -ENOMEM;
if (device->writeable)
device->fs_devices->total_rw_bytes += device->total_bytes;
ret = 0;
-#if 0
- ret = btrfs_open_device(device);
- if (ret) {
- kfree(device);
- }
-#endif
return ret;
}
key.type = 0;
again:
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- while(1) {
+ while (1) {
leaf = path->nodes[0];
slot = path->slots[0];
if (slot >= btrfs_header_nritems(leaf)) {