Conflicts: fs/btrfs/inode.c
Unified · Split
| @@ -64,6 +64,8 @@ struct btrfs_worker_thread { · 63 unmodified lines | ||
| 64 | 64 | int idle; |
| 65 | 65 | }; |
| 66 | 66 | |
| 67 | +static int __btrfs_start_workers(struct btrfs_workers *workers); | |
| 68 | + | |
| 67 | 69 | /* |
| 68 | 70 | * btrfs_start_workers uses kthread_run, which can block waiting for memory |
| 69 | 71 | * for a very long time. It will actually throttle on page writeback, |
| @@ -88,27 +90,10 @@ static void start_new_worker_func(struct btrfs_work *work) · 18 unmodified lines | ||
| 88 | 90 | { |
| 89 | 91 | struct worker_start *start; |
| 90 | 92 | start = container_of(work, struct worker_start, work); |
| 91 | − btrfs_start_workers(start->queue, 1); | |
| 93 | + __btrfs_start_workers(start->queue); | |
| 92 | 94 | kfree(start); |
| 93 | 95 | } |
| 94 | 96 | |
| 95 | −static int start_new_worker(struct btrfs_workers *queue) | |
| 96 | −{ | |
| 97 | − struct worker_start *start; | |
| 98 | − int ret; | |
| 99 | − | |
| 100 | − start = kzalloc(sizeof(*start), GFP_NOFS); | |
| 101 | − if (!start) | |
| 102 | − return -ENOMEM; | |
| 103 | − | |
| 104 | − start->work.func = start_new_worker_func; | |
| 105 | − start->queue = queue; | |
| 106 | − ret = btrfs_queue_worker(queue->atomic_worker_start, &start->work); | |
| 107 | − if (ret) | |
| 108 | − kfree(start); | |
| 109 | − return ret; | |
| 110 | −} | |
| 111 | − | |
| 112 | 97 | /* |
| 113 | 98 | * helper function to move a thread onto the idle list after it |
| 114 | 99 | * has finished some requests. |
| @@ -153,12 +138,20 @@ static void check_busy_worker(struct btrfs_worker_thread *worker) · 38 unmodified lines | ||
| 153 | 138 | static void check_pending_worker_creates(struct btrfs_worker_thread *worker) |
| 154 | 139 | { |
| 155 | 140 | struct btrfs_workers *workers = worker->workers; |
| 141 | + struct worker_start *start; | |
| 156 | 142 | unsigned long flags; |
| 157 | 143 | |
| 158 | 144 | rmb(); |
| 159 | 145 | if (!workers->atomic_start_pending) |
| 160 | 146 | return; |
| 161 | 147 | |
| 148 | + start = kzalloc(sizeof(*start), GFP_NOFS); | |
| 149 | + if (!start) | |
| 150 | + return; | |
| 151 | + | |
| 152 | + start->work.func = start_new_worker_func; | |
| 153 | + start->queue = workers; | |
| 154 | + | |
| 162 | 155 | spin_lock_irqsave(&workers->lock, flags); |
| 163 | 156 | if (!workers->atomic_start_pending) |
| 164 | 157 | goto out; |
| @@ -170,10 +163,11 @@ static void check_pending_worker_creates(struct btrfs_worker_thread *worker) · 5 unmodified lines | ||
| 170 | 163 | |
| 171 | 164 | workers->num_workers_starting += 1; |
| 172 | 165 | spin_unlock_irqrestore(&workers->lock, flags); |
| 173 | − start_new_worker(workers); | |
| 166 | + btrfs_queue_worker(workers->atomic_worker_start, &start->work); | |
| 174 | 167 | return; |
| 175 | 168 | |
| 176 | 169 | out: |
| 170 | + kfree(start); | |
| 177 | 171 | spin_unlock_irqrestore(&workers->lock, flags); |
| 178 | 172 | } |
| 179 | 173 | |
| @@ -462,56 +456,55 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max, · 282 unmodified lines | ||
| 462 | 456 | * starts new worker threads. This does not enforce the max worker |
| 463 | 457 | * count in case you need to temporarily go past it. |
| 464 | 458 | */ |
| 465 | −static int __btrfs_start_workers(struct btrfs_workers *workers, | |
| 466 | − int num_workers) | |
| 459 | +static int __btrfs_start_workers(struct btrfs_workers *workers) | |
| 467 | 460 | { |
| 468 | 461 | struct btrfs_worker_thread *worker; |
| 469 | 462 | int ret = 0; |
| 470 | − int i; | |
| 471 | 463 | |
| 472 | − for (i = 0; i < num_workers; i++) { | |
| 473 | − worker = kzalloc(sizeof(*worker), GFP_NOFS); | |
| 474 | − if (!worker) { | |
| 475 | − ret = -ENOMEM; | |
| 476 | − goto fail; | |
| 477 | − } | |
| 464 | + worker = kzalloc(sizeof(*worker), GFP_NOFS); | |
| 465 | + if (!worker) { | |
| 466 | + ret = -ENOMEM; | |
| 467 | + goto fail; | |
| 468 | + } | |
| 478 | 469 | |
| 479 | − INIT_LIST_HEAD(&worker->pending); | |
| 480 | − INIT_LIST_HEAD(&worker->prio_pending); | |
| 481 | − INIT_LIST_HEAD(&worker->worker_list); | |
| 482 | − spin_lock_init(&worker->lock); | |
| 483 | − | |
| 484 | − atomic_set(&worker->num_pending, 0); | |
| 485 | − atomic_set(&worker->refs, 1); | |
| 486 | − worker->workers = workers; | |
| 487 | − worker->task = kthread_run(worker_loop, worker, | |
| 488 | − "btrfs-%s-%d", workers->name, | |
| 489 | − workers->num_workers + i); | |
| 490 | − if (IS_ERR(worker->task)) { | |
| 491 | − ret = PTR_ERR(worker->task); | |
| 492 | − kfree(worker); | |
| 493 | − goto fail; | |
| 494 | − } | |
| 495 | − spin_lock_irq(&workers->lock); | |
| 496 | − list_add_tail(&worker->worker_list, &workers->idle_list); | |
| 497 | − worker->idle = 1; | |
| 498 | − workers->num_workers++; | |
| 499 | − workers->num_workers_starting--; | |
| 500 | − WARN_ON(workers->num_workers_starting < 0); | |
| 501 | − spin_unlock_irq(&workers->lock); | |
| 470 | + INIT_LIST_HEAD(&worker->pending); | |
| 471 | + INIT_LIST_HEAD(&worker->prio_pending); | |
| 472 | + INIT_LIST_HEAD(&worker->worker_list); | |
| 473 | + spin_lock_init(&worker->lock); | |
| 474 | + | |
| 475 | + atomic_set(&worker->num_pending, 0); | |
| 476 | + atomic_set(&worker->refs, 1); | |
| 477 | + worker->workers = workers; | |
| 478 | + worker->task = kthread_run(worker_loop, worker, | |
| 479 | + "btrfs-%s-%d", workers->name, | |
| 480 | + workers->num_workers + 1); | |
| 481 | + if (IS_ERR(worker->task)) { | |
| 482 | + ret = PTR_ERR(worker->task); | |
| 483 | + kfree(worker); | |
| 484 | + goto fail; | |
| 502 | 485 | } |
| 486 | + spin_lock_irq(&workers->lock); | |
| 487 | + list_add_tail(&worker->worker_list, &workers->idle_list); | |
| 488 | + worker->idle = 1; | |
| 489 | + workers->num_workers++; | |
| 490 | + workers->num_workers_starting--; | |
| 491 | + WARN_ON(workers->num_workers_starting < 0); | |
| 492 | + spin_unlock_irq(&workers->lock); | |
| 493 | + | |
| 503 | 494 | return 0; |
| 504 | 495 | fail: |
| 505 | − btrfs_stop_workers(workers); | |
| 496 | + spin_lock_irq(&workers->lock); | |
| 497 | + workers->num_workers_starting--; | |
| 498 | + spin_unlock_irq(&workers->lock); | |
| 506 | 499 | return ret; |
| 507 | 500 | } |
| 508 | 501 | |
| 509 | −int btrfs_start_workers(struct btrfs_workers *workers, int num_workers) | |
| 502 | +int btrfs_start_workers(struct btrfs_workers *workers) | |
| 510 | 503 | { |
| 511 | 504 | spin_lock_irq(&workers->lock); |
| 512 | − workers->num_workers_starting += num_workers; | |
| 505 | + workers->num_workers_starting++; | |
| 513 | 506 | spin_unlock_irq(&workers->lock); |
| 514 | − return __btrfs_start_workers(workers, num_workers); | |
| 507 | + return __btrfs_start_workers(workers); | |
| 515 | 508 | } |
| 516 | 509 | |
| 517 | 510 | /* |
| @@ -568,6 +561,7 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers) · 50 unmodified lines | ||
| 568 | 561 | struct btrfs_worker_thread *worker; |
| 569 | 562 | unsigned long flags; |
| 570 | 563 | struct list_head *fallback; |
| 564 | + int ret; | |
| 571 | 565 | |
| 572 | 566 | again: |
| 573 | 567 | spin_lock_irqsave(&workers->lock, flags); |
| @@ -584,7 +578,9 @@ again: · 10 unmodified lines | ||
| 584 | 578 | workers->num_workers_starting++; |
| 585 | 579 | spin_unlock_irqrestore(&workers->lock, flags); |
| 586 | 580 | /* we're below the limit, start another worker */ |
| 587 | − __btrfs_start_workers(workers, 1); | |
| 581 | + ret = __btrfs_start_workers(workers); | |
| 582 | + if (ret) | |
| 583 | + goto fallback; | |
| 588 | 584 | goto again; |
| 589 | 585 | } |
| 590 | 586 | } |
| @@ -665,7 +661,7 @@ void btrfs_set_work_high_prio(struct btrfs_work *work) · 74 unmodified lines | ||
| 665 | 661 | /* |
| 666 | 662 | * places a struct btrfs_work into the pending queue of one of the kthreads |
| 667 | 663 | */ |
| 668 | −int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) | |
| 664 | +void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) | |
| 669 | 665 | { |
| 670 | 666 | struct btrfs_worker_thread *worker; |
| 671 | 667 | unsigned long flags; |
| @@ -673,7 +669,7 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) · 1 unmodified line | ||
| 673 | 669 | |
| 674 | 670 | /* don't requeue something already on a list */ |
| 675 | 671 | if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) |
| 676 | − goto out; | |
| 672 | + return; | |
| 677 | 673 | |
| 678 | 674 | worker = find_worker(workers); |
| 679 | 675 | if (workers->ordered) { |
| @@ -712,7 +708,4 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) · 32 unmodified lines | ||
| 712 | 708 | if (wake) |
| 713 | 709 | wake_up_process(worker->task); |
| 714 | 710 | spin_unlock_irqrestore(&worker->lock, flags); |
| 715 | − | |
| 716 | −out: | |
| 717 | − return 0; | |
| 718 | 711 | } |
| @@ -109,8 +109,8 @@ struct btrfs_workers { · 108 unmodified lines | ||
| 109 | 109 | char *name; |
| 110 | 110 | }; |
| 111 | 111 | |
| 112 | −int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work); | |
| 113 | −int btrfs_start_workers(struct btrfs_workers *workers, int num_workers); | |
| 112 | +void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work); | |
| 113 | +int btrfs_start_workers(struct btrfs_workers *workers); | |
| 114 | 114 | int btrfs_stop_workers(struct btrfs_workers *workers); |
| 115 | 115 | void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max, |
| 116 | 116 | struct btrfs_workers *async_starter); |
| @@ -2692,7 +2692,8 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); · 2691 unmodified lines | ||
| 2692 | 2692 | int btrfs_readpage(struct file *file, struct page *page); |
| 2693 | 2693 | void btrfs_evict_inode(struct inode *inode); |
| 2694 | 2694 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
| 2695 | −void btrfs_dirty_inode(struct inode *inode, int flags); | |
| 2695 | +int btrfs_dirty_inode(struct inode *inode); | |
| 2696 | +int btrfs_update_time(struct file *file); | |
| 2696 | 2697 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
| 2697 | 2698 | void btrfs_destroy_inode(struct inode *inode); |
| 2698 | 2699 | int btrfs_drop_inode(struct inode *inode); |
| @@ -2194,19 +2194,27 @@ struct btrfs_root *open_ctree(struct super_block *sb, · 2193 unmodified lines | ||
| 2194 | 2194 | fs_info->endio_meta_write_workers.idle_thresh = 2; |
| 2195 | 2195 | fs_info->readahead_workers.idle_thresh = 2; |
| 2196 | 2196 | |
| 2197 | − btrfs_start_workers(&fs_info->workers, 1); | |
| 2198 | − btrfs_start_workers(&fs_info->generic_worker, 1); | |
| 2199 | − btrfs_start_workers(&fs_info->submit_workers, 1); | |
| 2200 | − btrfs_start_workers(&fs_info->delalloc_workers, 1); | |
| 2201 | − btrfs_start_workers(&fs_info->fixup_workers, 1); | |
| 2202 | − btrfs_start_workers(&fs_info->endio_workers, 1); | |
| 2203 | − btrfs_start_workers(&fs_info->endio_meta_workers, 1); | |
| 2204 | − btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); | |
| 2205 | − btrfs_start_workers(&fs_info->endio_write_workers, 1); | |
| 2206 | − btrfs_start_workers(&fs_info->endio_freespace_worker, 1); | |
| 2207 | − btrfs_start_workers(&fs_info->delayed_workers, 1); | |
| 2208 | − btrfs_start_workers(&fs_info->caching_workers, 1); | |
| 2209 | − btrfs_start_workers(&fs_info->readahead_workers, 1); | |
| 2197 | + /* | |
| 2198 | + * btrfs_start_workers can really only fail because of ENOMEM so just | |
| 2199 | + * return -ENOMEM if any of these fail. | |
| 2200 | + */ | |
| 2201 | + ret = btrfs_start_workers(&fs_info->workers); | |
| 2202 | + ret |= btrfs_start_workers(&fs_info->generic_worker); | |
| 2203 | + ret |= btrfs_start_workers(&fs_info->submit_workers); | |
| 2204 | + ret |= btrfs_start_workers(&fs_info->delalloc_workers); | |
| 2205 | + ret |= btrfs_start_workers(&fs_info->fixup_workers); | |
| 2206 | + ret |= btrfs_start_workers(&fs_info->endio_workers); | |
| 2207 | + ret |= btrfs_start_workers(&fs_info->endio_meta_workers); | |
| 2208 | + ret |= btrfs_start_workers(&fs_info->endio_meta_write_workers); | |
| 2209 | + ret |= btrfs_start_workers(&fs_info->endio_write_workers); | |
| 2210 | + ret |= btrfs_start_workers(&fs_info->endio_freespace_worker); | |
| 2211 | + ret |= btrfs_start_workers(&fs_info->delayed_workers); | |
| 2212 | + ret |= btrfs_start_workers(&fs_info->caching_workers); | |
| 2213 | + ret |= btrfs_start_workers(&fs_info->readahead_workers); | |
| 2214 | + if (ret) { | |
| 2215 | + ret = -ENOMEM; | |
| 2216 | + goto fail_sb_buffer; | |
| 2217 | + } | |
| 2210 | 2218 | |
| 2211 | 2219 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); |
| 2212 | 2220 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, |
| @@ -2822,7 +2822,7 @@ out_free: · 2821 unmodified lines | ||
| 2822 | 2822 | btrfs_release_path(path); |
| 2823 | 2823 | out: |
| 2824 | 2824 | spin_lock(&block_group->lock); |
| 2825 | − if (!ret) | |
| 2825 | + if (!ret && dcs == BTRFS_DC_SETUP) | |
| 2826 | 2826 | block_group->cache_generation = trans->transid; |
| 2827 | 2827 | block_group->disk_cache_state = dcs; |
| 2828 | 2828 | spin_unlock(&block_group->lock); |
| @@ -4203,12 +4203,17 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) · 1374 unmodified lines | ||
| 4203 | 4203 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 4204 | 4204 | struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv; |
| 4205 | 4205 | u64 to_reserve = 0; |
| 4206 | + u64 csum_bytes; | |
| 4206 | 4207 | unsigned nr_extents = 0; |
| 4208 | + int extra_reserve = 0; | |
| 4207 | 4209 | int flush = 1; |
| 4208 | 4210 | int ret; |
| 4209 | 4211 | |
| 4212 | + /* Need to be holding the i_mutex here if we aren't free space cache */ | |
| 4210 | 4213 | if (btrfs_is_free_space_inode(root, inode)) |
| 4211 | 4214 | flush = 0; |
| 4215 | + else | |
| 4216 | + WARN_ON(!mutex_is_locked(&inode->i_mutex)); | |
| 4212 | 4217 | |
| 4213 | 4218 | if (flush && btrfs_transaction_in_commit(root->fs_info)) |
| 4214 | 4219 | schedule_timeout(1); |
| @@ -4219,11 +4224,9 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) · 4 unmodified lines | ||
| 4219 | 4224 | BTRFS_I(inode)->outstanding_extents++; |
| 4220 | 4225 | |
| 4221 | 4226 | if (BTRFS_I(inode)->outstanding_extents > |
| 4222 | − BTRFS_I(inode)->reserved_extents) { | |
| 4227 | + BTRFS_I(inode)->reserved_extents) | |
| 4223 | 4228 | nr_extents = BTRFS_I(inode)->outstanding_extents - |
| 4224 | 4229 | BTRFS_I(inode)->reserved_extents; |
| 4225 | − BTRFS_I(inode)->reserved_extents += nr_extents; | |
| 4226 | − } | |
| 4227 | 4230 | |
| 4228 | 4231 | /* |
| 4229 | 4232 | * Add an item to reserve for updating the inode when we complete the |
| @@ -4231,11 +4234,12 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) · 1 unmodified line | ||
| 4231 | 4234 | */ |
| 4232 | 4235 | if (!BTRFS_I(inode)->delalloc_meta_reserved) { |
| 4233 | 4236 | nr_extents++; |
| 4234 | − BTRFS_I(inode)->delalloc_meta_reserved = 1; | |
| 4237 | + extra_reserve = 1; | |
| 4235 | 4238 | } |
| 4236 | 4239 | |
| 4237 | 4240 | to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); |
| 4238 | 4241 | to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); |
| 4242 | + csum_bytes = BTRFS_I(inode)->csum_bytes; | |
| 4239 | 4243 | spin_unlock(&BTRFS_I(inode)->lock); |
| 4240 | 4244 | |
| 4241 | 4245 | ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush); |
| @@ -4245,22 +4249,35 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) · 3 unmodified lines | ||
| 4245 | 4249 | |
| 4246 | 4250 | spin_lock(&BTRFS_I(inode)->lock); |
| 4247 | 4251 | dropped = drop_outstanding_extent(inode); |
| 4248 | − to_free = calc_csum_metadata_size(inode, num_bytes, 0); | |
| 4249 | − spin_unlock(&BTRFS_I(inode)->lock); | |
| 4250 | − to_free += btrfs_calc_trans_metadata_size(root, dropped); | |
| 4251 | − | |
| 4252 | 4252 | /* |
| 4253 | − * Somebody could have come in and twiddled with the | |
| 4254 | − * reservation, so if we have to free more than we would have | |
| 4255 | − * reserved from this reservation go ahead and release those | |
| 4256 | − * bytes. | |
| 4253 | + * If the inodes csum_bytes is the same as the original | |
| 4254 | + * csum_bytes then we know we haven't raced with any free()ers | |
| 4255 | + * so we can just reduce our inodes csum bytes and carry on. | |
| 4256 | + * Otherwise we have to do the normal free thing to account for | |
| 4257 | + * the case that the free side didn't free up its reserve | |
| 4258 | + * because of this outstanding reservation. | |
| 4257 | 4259 | */ |
| 4258 | − to_free -= to_reserve; | |
| 4260 | + if (BTRFS_I(inode)->csum_bytes == csum_bytes) | |
| 4261 | + calc_csum_metadata_size(inode, num_bytes, 0); | |
| 4262 | + else | |
| 4263 | + to_free = calc_csum_metadata_size(inode, num_bytes, 0); | |
| 4264 | + spin_unlock(&BTRFS_I(inode)->lock); | |
| 4265 | + if (dropped) | |
| 4266 | + to_free += btrfs_calc_trans_metadata_size(root, dropped); | |
| 4267 | + | |
| 4259 | 4268 | if (to_free) |
| 4260 | 4269 | btrfs_block_rsv_release(root, block_rsv, to_free); |
| 4261 | 4270 | return ret; |
| 4262 | 4271 | } |
| 4263 | 4272 | |
| 4273 | + spin_lock(&BTRFS_I(inode)->lock); | |
| 4274 | + if (extra_reserve) { | |
| 4275 | + BTRFS_I(inode)->delalloc_meta_reserved = 1; | |
| 4276 | + nr_extents--; | |
| 4277 | + } | |
| 4278 | + BTRFS_I(inode)->reserved_extents += nr_extents; | |
| 4279 | + spin_unlock(&BTRFS_I(inode)->lock); | |
| 4280 | + | |
| 4264 | 4281 | block_rsv_add_bytes(block_rsv, to_reserve, 1); |
| 4265 | 4282 | |
| 4266 | 4283 | return 0; |
| @@ -1387,7 +1387,11 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, · 1386 unmodified lines | ||
| 1387 | 1387 | goto out; |
| 1388 | 1388 | } |
| 1389 | 1389 | |
| 1390 | − file_update_time(file); | |
| 1390 | + err = btrfs_update_time(file); | |
| 1391 | + if (err) { | |
| 1392 | + mutex_unlock(&inode->i_mutex); | |
| 1393 | + goto out; | |
| 1394 | + } | |
| 1391 | 1395 | BTRFS_I(inode)->sequence++; |
| 1392 | 1396 | |
| 1393 | 1397 | start_pos = round_down(pos, root->sectorsize); |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | #include <linux/falloc.h> |
| 39 | 39 | #include <linux/slab.h> |
| 40 | 40 | #include <linux/ratelimit.h> |
| 41 | +#include <linux/mount.h> | |
| 41 | 42 | #include "compat.h" |
| 42 | 43 | #include "ctree.h" |
| 43 | 44 | #include "disk-io.h" |
| @@ -2031,7 +2032,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) · 1987 unmodified lines | ||
| 2031 | 2032 | /* insert an orphan item to track this unlinked/truncated file */ |
| 2032 | 2033 | if (insert >= 1) { |
| 2033 | 2034 | ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode)); |
| 2034 | − BUG_ON(ret); | |
| 2035 | + BUG_ON(ret && ret != -EEXIST); | |
| 2035 | 2036 | } |
| 2036 | 2037 | |
| 2037 | 2038 | /* insert an orphan item to track subvolume contains orphan files */ |
| @@ -2223,7 +2224,14 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) · 185 unmodified lines | ||
| 2223 | 2224 | continue; |
| 2224 | 2225 | } |
| 2225 | 2226 | nr_truncate++; |
| 2227 | + /* | |
| 2228 | + * Need to hold the imutex for reservation purposes, not | |
| 2229 | + * a huge deal here but I have a WARN_ON in | |
| 2230 | + * btrfs_delalloc_reserve_space to catch offenders. | |
| 2231 | + */ | |
| 2232 | + mutex_lock(&inode->i_mutex); | |
| 2226 | 2233 | ret = btrfs_truncate(inode); |
| 2234 | + mutex_unlock(&inode->i_mutex); | |
| 2227 | 2235 | } else { |
| 2228 | 2236 | nr_unlink++; |
| 2229 | 2237 | } |
| @@ -3426,7 +3434,6 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize) · 1196 unmodified lines | ||
| 3426 | 3434 | i_size_write(inode, newsize); |
| 3427 | 3435 | btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); |
| 3428 | 3436 | ret = btrfs_update_inode(trans, root, inode); |
| 3429 | − | |
| 3430 | 3437 | btrfs_end_transaction_throttle(trans, root); |
| 3431 | 3438 | } else { |
| 3432 | 3439 | |
| @@ -3467,9 +3474,9 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) · 34 unmodified lines | ||
| 3467 | 3474 | |
| 3468 | 3475 | if (attr->ia_valid) { |
| 3469 | 3476 | setattr_copy(inode, attr); |
| 3470 | − mark_inode_dirty(inode); | |
| 3477 | + err = btrfs_dirty_inode(inode); | |
| 3471 | 3478 | |
| 3472 | − if (attr->ia_valid & ATTR_MODE) | |
| 3479 | + if (!err && attr->ia_valid & ATTR_MODE) | |
| 3473 | 3480 | err = btrfs_acl_chmod(inode); |
| 3474 | 3481 | } |
| 3475 | 3482 | |
| @@ -4245,42 +4252,80 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) · 769 unmodified lines | ||
| 4245 | 4252 | * FIXME, needs more benchmarking...there are no reasons other than performance |
| 4246 | 4253 | * to keep or drop this code. |
| 4247 | 4254 | */ |
| 4248 | −void btrfs_dirty_inode(struct inode *inode, int flags) | |
| 4255 | +int btrfs_dirty_inode(struct inode *inode) | |
| 4249 | 4256 | { |
| 4250 | 4257 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 4251 | 4258 | struct btrfs_trans_handle *trans; |
| 4252 | 4259 | int ret; |
| 4253 | 4260 | |
| 4254 | 4261 | if (BTRFS_I(inode)->dummy_inode) |
| 4255 | − return; | |
| 4262 | + return 0; | |
| 4256 | 4263 | |
| 4257 | 4264 | trans = btrfs_join_transaction(root); |
| 4258 | − BUG_ON(IS_ERR(trans)); | |
| 4265 | + if (IS_ERR(trans)) | |
| 4266 | + return PTR_ERR(trans); | |
| 4259 | 4267 | |
| 4260 | 4268 | ret = btrfs_update_inode(trans, root, inode); |
| 4261 | 4269 | if (ret && ret == -ENOSPC) { |
| 4262 | 4270 | /* whoops, lets try again with the full transaction */ |
| 4263 | 4271 | btrfs_end_transaction(trans, root); |
| 4264 | 4272 | trans = btrfs_start_transaction(root, 1); |
| 4265 | − if (IS_ERR(trans)) { | |
| 4266 | − printk_ratelimited(KERN_ERR "btrfs: fail to " | |
| 4267 | − "dirty inode %llu error %ld\n", | |
| 4268 | − (unsigned long long)btrfs_ino(inode), | |
| 4269 | − PTR_ERR(trans)); | |
| 4270 | − return; | |
| 4271 | − } | |
| 4273 | + if (IS_ERR(trans)) | |
| 4274 | + return PTR_ERR(trans); | |
| 4272 | 4275 | |
| 4273 | 4276 | ret = btrfs_update_inode(trans, root, inode); |
| 4274 | − if (ret) { | |
| 4275 | − printk_ratelimited(KERN_ERR "btrfs: fail to " | |
| 4276 | − "dirty inode %llu error %d\n", | |
| 4277 | − (unsigned long long)btrfs_ino(inode), | |
| 4278 | − ret); | |
| 4279 | − } | |
| 4280 | 4277 | } |
| 4281 | 4278 | btrfs_end_transaction(trans, root); |
| 4282 | 4279 | if (BTRFS_I(inode)->delayed_node) |
| 4283 | 4280 | btrfs_balance_delayed_items(root); |
| 4281 | + | |
| 4282 | + return ret; | |
| 4283 | +} | |
| 4284 | + | |
| 4285 | +/* | |
| 4286 | + * This is a copy of file_update_time. We need this so we can return error on | |
| 4287 | + * ENOSPC for updating the inode in the case of file write and mmap writes. | |
| 4288 | + */ | |
| 4289 | +int btrfs_update_time(struct file *file) | |
| 4290 | +{ | |
| 4291 | + struct inode *inode = file->f_path.dentry->d_inode; | |
| 4292 | + struct timespec now; | |
| 4293 | + int ret; | |
| 4294 | + enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0; | |
| 4295 | + | |
| 4296 | + /* First try to exhaust all avenues to not sync */ | |
| 4297 | + if (IS_NOCMTIME(inode)) | |
| 4298 | + return 0; | |
| 4299 | + | |
| 4300 | + now = current_fs_time(inode->i_sb); | |
| 4301 | + if (!timespec_equal(&inode->i_mtime, &now)) | |
| 4302 | + sync_it = S_MTIME; | |
| 4303 | + | |
| 4304 | + if (!timespec_equal(&inode->i_ctime, &now)) | |
| 4305 | + sync_it |= S_CTIME; | |
| 4306 | + | |
| 4307 | + if (IS_I_VERSION(inode)) | |
| 4308 | + sync_it |= S_VERSION; | |
| 4309 | + | |
| 4310 | + if (!sync_it) | |
| 4311 | + return 0; | |
| 4312 | + | |
| 4313 | + /* Finally allowed to write? Takes lock. */ | |
| 4314 | + if (mnt_want_write_file(file)) | |
| 4315 | + return 0; | |
| 4316 | + | |
| 4317 | + /* Only change inode inside the lock region */ | |
| 4318 | + if (sync_it & S_VERSION) | |
| 4319 | + inode_inc_iversion(inode); | |
| 4320 | + if (sync_it & S_CTIME) | |
| 4321 | + inode->i_ctime = now; | |
| 4322 | + if (sync_it & S_MTIME) | |
| 4323 | + inode->i_mtime = now; | |
| 4324 | + ret = btrfs_dirty_inode(inode); | |
| 4325 | + if (!ret) | |
| 4326 | + mark_inode_dirty_sync(inode); | |
| 4327 | + mnt_drop_write(file->f_path.mnt); | |
| 4328 | + return ret; | |
| 4284 | 4329 | } |
| 4285 | 4330 | |
| 4286 | 4331 | /* |
| @@ -6358,7 +6403,12 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) · 2071 unmodified lines | ||
| 6358 | 6403 | u64 page_start; |
| 6359 | 6404 | u64 page_end; |
| 6360 | 6405 | |
| 6406 | + /* Need this to keep space reservations serialized */ | |
| 6407 | + mutex_lock(&inode->i_mutex); | |
| 6361 | 6408 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
| 6409 | + mutex_unlock(&inode->i_mutex); | |
| 6410 | + if (!ret) | |
| 6411 | + ret = btrfs_update_time(vma->vm_file); | |
| 6362 | 6412 | if (ret) { |
| 6363 | 6413 | if (ret == -ENOMEM) |
| 6364 | 6414 | ret = VM_FAULT_OOM; |
| @@ -6570,8 +6620,9 @@ static int btrfs_truncate(struct inode *inode) · 205 unmodified lines | ||
| 6570 | 6620 | /* Just need the 1 for updating the inode */ |
| 6571 | 6621 | trans = btrfs_start_transaction(root, 1); |
| 6572 | 6622 | if (IS_ERR(trans)) { |
| 6573 | − err = PTR_ERR(trans); | |
| 6574 | − goto out; | |
| 6623 | + ret = err = PTR_ERR(trans); | |
| 6624 | + trans = NULL; | |
| 6625 | + break; | |
| 6575 | 6626 | } |
| 6576 | 6627 | } |
| 6577 | 6628 | |
| @@ -7415,6 +7466,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { · 837 unmodified lines | ||
| 7415 | 7466 | .follow_link = page_follow_link_light, |
| 7416 | 7467 | .put_link = page_put_link, |
| 7417 | 7468 | .getattr = btrfs_getattr, |
| 7469 | + .setattr = btrfs_setattr, | |
| 7418 | 7470 | .permission = btrfs_permission, |
| 7419 | 7471 | .setxattr = btrfs_setxattr, |
| 7420 | 7472 | .getxattr = btrfs_getxattr, |
| @@ -858,8 +858,10 @@ static int cluster_pages_for_defrag(struct inode *inode, · 857 unmodified lines | ||
| 858 | 858 | return 0; |
| 859 | 859 | file_end = (isize - 1) >> PAGE_CACHE_SHIFT; |
| 860 | 860 | |
| 861 | + mutex_lock(&inode->i_mutex); | |
| 861 | 862 | ret = btrfs_delalloc_reserve_space(inode, |
| 862 | 863 | num_pages << PAGE_CACHE_SHIFT); |
| 864 | + mutex_unlock(&inode->i_mutex); | |
| 863 | 865 | if (ret) |
| 864 | 866 | return ret; |
| 865 | 867 | again: |
| @@ -2947,7 +2947,9 @@ static int relocate_file_extent_cluster(struct inode *inode, · 2946 unmodified lines | ||
| 2947 | 2947 | index = (cluster->start - offset) >> PAGE_CACHE_SHIFT; |
| 2948 | 2948 | last_index = (cluster->end - offset) >> PAGE_CACHE_SHIFT; |
| 2949 | 2949 | while (index <= last_index) { |
| 2950 | + mutex_lock(&inode->i_mutex); | |
| 2950 | 2951 | ret = btrfs_delalloc_reserve_metadata(inode, PAGE_CACHE_SIZE); |
| 2952 | + mutex_unlock(&inode->i_mutex); | |
| 2951 | 2953 | if (ret) |
| 2952 | 2954 | goto out; |
| 2953 | 2955 | |
| @@ -1535,18 +1535,22 @@ static noinline_for_stack int scrub_supers(struct scrub_dev *sdev) · 1534 unmodified lines | ||
| 1535 | 1535 | static noinline_for_stack int scrub_workers_get(struct btrfs_root *root) |
| 1536 | 1536 | { |
| 1537 | 1537 | struct btrfs_fs_info *fs_info = root->fs_info; |
| 1538 | + int ret = 0; | |
| 1538 | 1539 | |
| 1539 | 1540 | mutex_lock(&fs_info->scrub_lock); |
| 1540 | 1541 | if (fs_info->scrub_workers_refcnt == 0) { |
| 1541 | 1542 | btrfs_init_workers(&fs_info->scrub_workers, "scrub", |
| 1542 | 1543 | fs_info->thread_pool_size, &fs_info->generic_worker); |
| 1543 | 1544 | fs_info->scrub_workers.idle_thresh = 4; |
| 1544 | − btrfs_start_workers(&fs_info->scrub_workers, 1); | |
| 1545 | + ret = btrfs_start_workers(&fs_info->scrub_workers); | |
| 1546 | + if (ret) | |
| 1547 | + goto out; | |
| 1545 | 1548 | } |
| 1546 | 1549 | ++fs_info->scrub_workers_refcnt; |
| 1550 | +out: | |
| 1547 | 1551 | mutex_unlock(&fs_info->scrub_lock); |
| 1548 | 1552 | |
| 1549 | − return 0; | |
| 1553 | + return ret; | |
| 1550 | 1554 | } |
| 1551 | 1555 | |
| 1552 | 1556 | static noinline_for_stack void scrub_workers_put(struct btrfs_root *root) |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <linux/slab.h> |
| 42 | 42 | #include <linux/cleancache.h> |
| 43 | 43 | #include <linux/mnt_namespace.h> |
| 44 | +#include <linux/ratelimit.h> | |
| 44 | 45 | #include "compat.h" |
| 45 | 46 | #include "delayed-inode.h" |
| 46 | 47 | #include "ctree.h" |
| @@ -1297,6 +1298,16 @@ static int btrfs_unfreeze(struct super_block *sb) · 1250 unmodified lines | ||
| 1297 | 1298 | return 0; |
| 1298 | 1299 | } |
| 1299 | 1300 | |
| 1301 | +static void btrfs_fs_dirty_inode(struct inode *inode, int flags) | |
| 1302 | +{ | |
| 1303 | + int ret; | |
| 1304 | + | |
| 1305 | + ret = btrfs_dirty_inode(inode); | |
| 1306 | + if (ret) | |
| 1307 | + printk_ratelimited(KERN_ERR "btrfs: fail to dirty inode %Lu " | |
| 1308 | + "error %d\n", btrfs_ino(inode), ret); | |
| 1309 | +} | |
| 1310 | + | |
| 1300 | 1311 | static const struct super_operations btrfs_super_ops = { |
| 1301 | 1312 | .drop_inode = btrfs_drop_inode, |
| 1302 | 1313 | .evict_inode = btrfs_evict_inode, |
| @@ -1304,7 +1315,7 @@ static const struct super_operations btrfs_super_ops = { · 1 unmodified line | ||
| 1304 | 1315 | .sync_fs = btrfs_sync_fs, |
| 1305 | 1316 | .show_options = btrfs_show_options, |
| 1306 | 1317 | .write_inode = btrfs_write_inode, |
| 1307 | − .dirty_inode = btrfs_dirty_inode, | |
| 1318 | + .dirty_inode = btrfs_fs_dirty_inode, | |
| 1308 | 1319 | .alloc_inode = btrfs_alloc_inode, |
| 1309 | 1320 | .destroy_inode = btrfs_destroy_inode, |
| 1310 | 1321 | .statfs = btrfs_statfs, |