Commit d25223a0 authored by Li Zefan's avatar Li Zefan
Browse files

Merge branch 'for-linus' of...

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs into for-linus
parents 396e6e49 08c422c2
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -63,8 +63,8 @@ IRC network.
Userspace tools for creating and manipulating Btrfs file systems are
Userspace tools for creating and manipulating Btrfs file systems are
available from the git repository at the following location:
available from the git repository at the following location:


 http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs-unstable.git
 http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs.git
 git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs-unstable.git
 git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs.git


These include the following tools:
These include the following tools:


+2 −1
Original line number Original line Diff line number Diff line
@@ -7,6 +7,7 @@ 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_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 \
	   extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \
	   export.o tree-log.o free-space-cache.o zlib.o lzo.o \
	   export.o tree-log.o free-space-cache.o zlib.o lzo.o \
	   compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o
	   compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \
	   reada.o backref.o


btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
+7 −10
Original line number Original line Diff line number Diff line
@@ -59,22 +59,19 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
		if (!value)
		if (!value)
			return ERR_PTR(-ENOMEM);
			return ERR_PTR(-ENOMEM);
		size = __btrfs_getxattr(inode, name, value, size);
		size = __btrfs_getxattr(inode, name, value, size);
	}
	if (size > 0) {
	if (size > 0) {
		acl = posix_acl_from_xattr(value, size);
		acl = posix_acl_from_xattr(value, size);
			if (IS_ERR(acl)) {
				kfree(value);
				return acl;
			}
			set_cached_acl(inode, type, acl);
		}
		kfree(value);
	} else if (size == -ENOENT || size == -ENODATA || size == 0) {
	} else if (size == -ENOENT || size == -ENODATA || size == 0) {
		/* FIXME, who returns -ENOENT?  I think nobody */
		/* FIXME, who returns -ENOENT?  I think nobody */
		acl = NULL;
		acl = NULL;
		set_cached_acl(inode, type, acl);
	} else {
	} else {
		acl = ERR_PTR(-EIO);
		acl = ERR_PTR(-EIO);
	}
	}
	kfree(value);

	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);


	return acl;
	return acl;
}
}
+57 −63
Original line number Original line Diff line number Diff line
@@ -64,6 +64,8 @@ struct btrfs_worker_thread {
	int idle;
	int idle;
};
};


static int __btrfs_start_workers(struct btrfs_workers *workers);

/*
/*
 * btrfs_start_workers uses kthread_run, which can block waiting for memory
 * btrfs_start_workers uses kthread_run, which can block waiting for memory
 * for a very long time.  It will actually throttle on page writeback,
 * for a very long time.  It will actually throttle on page writeback,
@@ -88,25 +90,8 @@ static void start_new_worker_func(struct btrfs_work *work)
{
{
	struct worker_start *start;
	struct worker_start *start;
	start = container_of(work, struct worker_start, work);
	start = container_of(work, struct worker_start, work);
	btrfs_start_workers(start->queue, 1);
	__btrfs_start_workers(start->queue);
	kfree(start);
}

static int start_new_worker(struct btrfs_workers *queue)
{
	struct worker_start *start;
	int ret;

	start = kzalloc(sizeof(*start), GFP_NOFS);
	if (!start)
		return -ENOMEM;

	start->work.func = start_new_worker_func;
	start->queue = queue;
	ret = btrfs_queue_worker(queue->atomic_worker_start, &start->work);
	if (ret)
	kfree(start);
	kfree(start);
	return ret;
}
}


/*
/*
@@ -153,12 +138,20 @@ static void check_busy_worker(struct btrfs_worker_thread *worker)
static void check_pending_worker_creates(struct btrfs_worker_thread *worker)
static void check_pending_worker_creates(struct btrfs_worker_thread *worker)
{
{
	struct btrfs_workers *workers = worker->workers;
	struct btrfs_workers *workers = worker->workers;
	struct worker_start *start;
	unsigned long flags;
	unsigned long flags;


	rmb();
	rmb();
	if (!workers->atomic_start_pending)
	if (!workers->atomic_start_pending)
		return;
		return;


	start = kzalloc(sizeof(*start), GFP_NOFS);
	if (!start)
		return;

	start->work.func = start_new_worker_func;
	start->queue = workers;

	spin_lock_irqsave(&workers->lock, flags);
	spin_lock_irqsave(&workers->lock, flags);
	if (!workers->atomic_start_pending)
	if (!workers->atomic_start_pending)
		goto out;
		goto out;
@@ -170,10 +163,11 @@ static void check_pending_worker_creates(struct btrfs_worker_thread *worker)


	workers->num_workers_starting += 1;
	workers->num_workers_starting += 1;
	spin_unlock_irqrestore(&workers->lock, flags);
	spin_unlock_irqrestore(&workers->lock, flags);
	start_new_worker(workers);
	btrfs_queue_worker(workers->atomic_worker_start, &start->work);
	return;
	return;


out:
out:
	kfree(start);
	spin_unlock_irqrestore(&workers->lock, flags);
	spin_unlock_irqrestore(&workers->lock, flags);
}
}


@@ -331,7 +325,7 @@ static int worker_loop(void *arg)
			run_ordered_completions(worker->workers, work);
			run_ordered_completions(worker->workers, work);


			check_pending_worker_creates(worker);
			check_pending_worker_creates(worker);

			cond_resched();
		}
		}


		spin_lock_irq(&worker->lock);
		spin_lock_irq(&worker->lock);
@@ -462,14 +456,11 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
 * starts new worker threads.  This does not enforce the max worker
 * starts new worker threads.  This does not enforce the max worker
 * count in case you need to temporarily go past it.
 * count in case you need to temporarily go past it.
 */
 */
static int __btrfs_start_workers(struct btrfs_workers *workers,
static int __btrfs_start_workers(struct btrfs_workers *workers)
				 int num_workers)
{
{
	struct btrfs_worker_thread *worker;
	struct btrfs_worker_thread *worker;
	int ret = 0;
	int ret = 0;
	int i;


	for (i = 0; i < num_workers; i++) {
	worker = kzalloc(sizeof(*worker), GFP_NOFS);
	worker = kzalloc(sizeof(*worker), GFP_NOFS);
	if (!worker) {
	if (!worker) {
		ret = -ENOMEM;
		ret = -ENOMEM;
@@ -486,7 +477,7 @@ static int __btrfs_start_workers(struct btrfs_workers *workers,
	worker->workers = workers;
	worker->workers = workers;
	worker->task = kthread_run(worker_loop, worker,
	worker->task = kthread_run(worker_loop, worker,
				   "btrfs-%s-%d", workers->name,
				   "btrfs-%s-%d", workers->name,
					   workers->num_workers + i);
				   workers->num_workers + 1);
	if (IS_ERR(worker->task)) {
	if (IS_ERR(worker->task)) {
		ret = PTR_ERR(worker->task);
		ret = PTR_ERR(worker->task);
		kfree(worker);
		kfree(worker);
@@ -499,19 +490,21 @@ static int __btrfs_start_workers(struct btrfs_workers *workers,
	workers->num_workers_starting--;
	workers->num_workers_starting--;
	WARN_ON(workers->num_workers_starting < 0);
	WARN_ON(workers->num_workers_starting < 0);
	spin_unlock_irq(&workers->lock);
	spin_unlock_irq(&workers->lock);
	}

	return 0;
	return 0;
fail:
fail:
	btrfs_stop_workers(workers);
	spin_lock_irq(&workers->lock);
	workers->num_workers_starting--;
	spin_unlock_irq(&workers->lock);
	return ret;
	return ret;
}
}


int btrfs_start_workers(struct btrfs_workers *workers, int num_workers)
int btrfs_start_workers(struct btrfs_workers *workers)
{
{
	spin_lock_irq(&workers->lock);
	spin_lock_irq(&workers->lock);
	workers->num_workers_starting += num_workers;
	workers->num_workers_starting++;
	spin_unlock_irq(&workers->lock);
	spin_unlock_irq(&workers->lock);
	return __btrfs_start_workers(workers, num_workers);
	return __btrfs_start_workers(workers);
}
}


/*
/*
@@ -568,9 +561,10 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers)
	struct btrfs_worker_thread *worker;
	struct btrfs_worker_thread *worker;
	unsigned long flags;
	unsigned long flags;
	struct list_head *fallback;
	struct list_head *fallback;
	int ret;


again:
	spin_lock_irqsave(&workers->lock, flags);
	spin_lock_irqsave(&workers->lock, flags);
again:
	worker = next_worker(workers);
	worker = next_worker(workers);


	if (!worker) {
	if (!worker) {
@@ -584,7 +578,10 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers)
			workers->num_workers_starting++;
			workers->num_workers_starting++;
			spin_unlock_irqrestore(&workers->lock, flags);
			spin_unlock_irqrestore(&workers->lock, flags);
			/* we're below the limit, start another worker */
			/* we're below the limit, start another worker */
			__btrfs_start_workers(workers, 1);
			ret = __btrfs_start_workers(workers);
			spin_lock_irqsave(&workers->lock, flags);
			if (ret)
				goto fallback;
			goto again;
			goto again;
		}
		}
	}
	}
@@ -665,7 +662,7 @@ void btrfs_set_work_high_prio(struct btrfs_work *work)
/*
/*
 * places a struct btrfs_work into the pending queue of one of the kthreads
 * places a struct btrfs_work into the pending queue of one of the kthreads
 */
 */
int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
{
{
	struct btrfs_worker_thread *worker;
	struct btrfs_worker_thread *worker;
	unsigned long flags;
	unsigned long flags;
@@ -673,7 +670,7 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)


	/* don't requeue something already on a list */
	/* don't requeue something already on a list */
	if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
	if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
		goto out;
		return;


	worker = find_worker(workers);
	worker = find_worker(workers);
	if (workers->ordered) {
	if (workers->ordered) {
@@ -712,7 +709,4 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
	if (wake)
	if (wake)
		wake_up_process(worker->task);
		wake_up_process(worker->task);
	spin_unlock_irqrestore(&worker->lock, flags);
	spin_unlock_irqrestore(&worker->lock, flags);

out:
	return 0;
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -109,8 +109,8 @@ struct btrfs_workers {
	char *name;
	char *name;
};
};


int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work);
void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work);
int btrfs_start_workers(struct btrfs_workers *workers, int num_workers);
int btrfs_start_workers(struct btrfs_workers *workers);
int btrfs_stop_workers(struct btrfs_workers *workers);
int btrfs_stop_workers(struct btrfs_workers *workers);
void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
			struct btrfs_workers *async_starter);
			struct btrfs_workers *async_starter);
Loading