Loading Documentation/filesystems/btrfs.txt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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: Loading fs/btrfs/Makefile +2 −1 Original line number Original line Diff line number Diff line Loading @@ -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 fs/btrfs/acl.c +7 −10 Original line number Original line Diff line number Diff line Loading @@ -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; } } Loading fs/btrfs/async-thread.c +57 −63 Original line number Original line Diff line number Diff line Loading @@ -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, Loading @@ -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; } } /* /* Loading Loading @@ -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; Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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); Loading @@ -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); } } /* /* Loading Loading @@ -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) { Loading @@ -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; } } } } Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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; } } fs/btrfs/async-thread.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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 Loading
Documentation/filesystems/btrfs.txt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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: Loading
fs/btrfs/Makefile +2 −1 Original line number Original line Diff line number Diff line Loading @@ -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
fs/btrfs/acl.c +7 −10 Original line number Original line Diff line number Diff line Loading @@ -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; } } Loading
fs/btrfs/async-thread.c +57 −63 Original line number Original line Diff line number Diff line Loading @@ -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, Loading @@ -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; } } /* /* Loading Loading @@ -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; Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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); Loading @@ -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); } } /* /* Loading Loading @@ -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) { Loading @@ -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; } } } } Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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; } }
fs/btrfs/async-thread.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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