diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 1358 |
1 files changed, 1217 insertions, 141 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 645a17927a8f..a506a22b522a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/security.h> | 39 | #include <linux/security.h> |
40 | #include <linux/xattr.h> | 40 | #include <linux/xattr.h> |
41 | #include <linux/vmalloc.h> | 41 | #include <linux/vmalloc.h> |
42 | #include <linux/slab.h> | ||
42 | #include "compat.h" | 43 | #include "compat.h" |
43 | #include "ctree.h" | 44 | #include "ctree.h" |
44 | #include "disk-io.h" | 45 | #include "disk-io.h" |
@@ -146,6 +147,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
146 | unsigned int flags, oldflags; | 147 | unsigned int flags, oldflags; |
147 | int ret; | 148 | int ret; |
148 | 149 | ||
150 | if (btrfs_root_readonly(root)) | ||
151 | return -EROFS; | ||
152 | |||
149 | if (copy_from_user(&flags, arg, sizeof(flags))) | 153 | if (copy_from_user(&flags, arg, sizeof(flags))) |
150 | return -EFAULT; | 154 | return -EFAULT; |
151 | 155 | ||
@@ -223,7 +227,8 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg) | |||
223 | 227 | ||
224 | static noinline int create_subvol(struct btrfs_root *root, | 228 | static noinline int create_subvol(struct btrfs_root *root, |
225 | struct dentry *dentry, | 229 | struct dentry *dentry, |
226 | char *name, int namelen) | 230 | char *name, int namelen, |
231 | u64 *async_transid) | ||
227 | { | 232 | { |
228 | struct btrfs_trans_handle *trans; | 233 | struct btrfs_trans_handle *trans; |
229 | struct btrfs_key key; | 234 | struct btrfs_key key; |
@@ -231,30 +236,34 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
231 | struct btrfs_inode_item *inode_item; | 236 | struct btrfs_inode_item *inode_item; |
232 | struct extent_buffer *leaf; | 237 | struct extent_buffer *leaf; |
233 | struct btrfs_root *new_root; | 238 | struct btrfs_root *new_root; |
234 | struct inode *dir = dentry->d_parent->d_inode; | 239 | struct dentry *parent = dget_parent(dentry); |
240 | struct inode *dir; | ||
235 | int ret; | 241 | int ret; |
236 | int err; | 242 | int err; |
237 | u64 objectid; | 243 | u64 objectid; |
238 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; | 244 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; |
239 | u64 index = 0; | 245 | u64 index = 0; |
240 | 246 | ||
247 | ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root, | ||
248 | 0, &objectid); | ||
249 | if (ret) { | ||
250 | dput(parent); | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | dir = parent->d_inode; | ||
255 | |||
241 | /* | 256 | /* |
242 | * 1 - inode item | 257 | * 1 - inode item |
243 | * 2 - refs | 258 | * 2 - refs |
244 | * 1 - root item | 259 | * 1 - root item |
245 | * 2 - dir items | 260 | * 2 - dir items |
246 | */ | 261 | */ |
247 | ret = btrfs_reserve_metadata_space(root, 6); | 262 | trans = btrfs_start_transaction(root, 6); |
248 | if (ret) | 263 | if (IS_ERR(trans)) { |
249 | return ret; | 264 | dput(parent); |
250 | 265 | return PTR_ERR(trans); | |
251 | trans = btrfs_start_transaction(root, 1); | 266 | } |
252 | BUG_ON(!trans); | ||
253 | |||
254 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | ||
255 | 0, &objectid); | ||
256 | if (ret) | ||
257 | goto fail; | ||
258 | 267 | ||
259 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 268 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
260 | 0, objectid, NULL, 0, 0, 0); | 269 | 0, objectid, NULL, 0, 0, 0); |
@@ -341,18 +350,24 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
341 | 350 | ||
342 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); | 351 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); |
343 | fail: | 352 | fail: |
344 | err = btrfs_commit_transaction(trans, root); | 353 | dput(parent); |
354 | if (async_transid) { | ||
355 | *async_transid = trans->transid; | ||
356 | err = btrfs_commit_transaction_async(trans, root, 1); | ||
357 | } else { | ||
358 | err = btrfs_commit_transaction(trans, root); | ||
359 | } | ||
345 | if (err && !ret) | 360 | if (err && !ret) |
346 | ret = err; | 361 | ret = err; |
347 | |||
348 | btrfs_unreserve_metadata_space(root, 6); | ||
349 | return ret; | 362 | return ret; |
350 | } | 363 | } |
351 | 364 | ||
352 | static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | 365 | static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, |
353 | char *name, int namelen) | 366 | char *name, int namelen, u64 *async_transid, |
367 | bool readonly) | ||
354 | { | 368 | { |
355 | struct inode *inode; | 369 | struct inode *inode; |
370 | struct dentry *parent; | ||
356 | struct btrfs_pending_snapshot *pending_snapshot; | 371 | struct btrfs_pending_snapshot *pending_snapshot; |
357 | struct btrfs_trans_handle *trans; | 372 | struct btrfs_trans_handle *trans; |
358 | int ret; | 373 | int ret; |
@@ -360,42 +375,45 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
360 | if (!root->ref_cows) | 375 | if (!root->ref_cows) |
361 | return -EINVAL; | 376 | return -EINVAL; |
362 | 377 | ||
363 | /* | ||
364 | * 1 - inode item | ||
365 | * 2 - refs | ||
366 | * 1 - root item | ||
367 | * 2 - dir items | ||
368 | */ | ||
369 | ret = btrfs_reserve_metadata_space(root, 6); | ||
370 | if (ret) | ||
371 | goto fail; | ||
372 | |||
373 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); | 378 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); |
374 | if (!pending_snapshot) { | 379 | if (!pending_snapshot) |
375 | ret = -ENOMEM; | 380 | return -ENOMEM; |
376 | btrfs_unreserve_metadata_space(root, 6); | 381 | |
377 | goto fail; | 382 | btrfs_init_block_rsv(&pending_snapshot->block_rsv); |
378 | } | ||
379 | pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS); | ||
380 | if (!pending_snapshot->name) { | ||
381 | ret = -ENOMEM; | ||
382 | kfree(pending_snapshot); | ||
383 | btrfs_unreserve_metadata_space(root, 6); | ||
384 | goto fail; | ||
385 | } | ||
386 | memcpy(pending_snapshot->name, name, namelen); | ||
387 | pending_snapshot->name[namelen] = '\0'; | ||
388 | pending_snapshot->dentry = dentry; | 383 | pending_snapshot->dentry = dentry; |
389 | trans = btrfs_start_transaction(root, 1); | ||
390 | BUG_ON(!trans); | ||
391 | pending_snapshot->root = root; | 384 | pending_snapshot->root = root; |
385 | pending_snapshot->readonly = readonly; | ||
386 | |||
387 | trans = btrfs_start_transaction(root->fs_info->extent_root, 5); | ||
388 | if (IS_ERR(trans)) { | ||
389 | ret = PTR_ERR(trans); | ||
390 | goto fail; | ||
391 | } | ||
392 | |||
393 | ret = btrfs_snap_reserve_metadata(trans, pending_snapshot); | ||
394 | BUG_ON(ret); | ||
395 | |||
392 | list_add(&pending_snapshot->list, | 396 | list_add(&pending_snapshot->list, |
393 | &trans->transaction->pending_snapshots); | 397 | &trans->transaction->pending_snapshots); |
394 | ret = btrfs_commit_transaction(trans, root); | 398 | if (async_transid) { |
399 | *async_transid = trans->transid; | ||
400 | ret = btrfs_commit_transaction_async(trans, | ||
401 | root->fs_info->extent_root, 1); | ||
402 | } else { | ||
403 | ret = btrfs_commit_transaction(trans, | ||
404 | root->fs_info->extent_root); | ||
405 | } | ||
395 | BUG_ON(ret); | 406 | BUG_ON(ret); |
396 | btrfs_unreserve_metadata_space(root, 6); | ||
397 | 407 | ||
398 | inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); | 408 | ret = pending_snapshot->error; |
409 | if (ret) | ||
410 | goto fail; | ||
411 | |||
412 | btrfs_orphan_cleanup(pending_snapshot->snap); | ||
413 | |||
414 | parent = dget_parent(dentry); | ||
415 | inode = btrfs_lookup_dentry(parent->d_inode, dentry); | ||
416 | dput(parent); | ||
399 | if (IS_ERR(inode)) { | 417 | if (IS_ERR(inode)) { |
400 | ret = PTR_ERR(inode); | 418 | ret = PTR_ERR(inode); |
401 | goto fail; | 419 | goto fail; |
@@ -404,9 +422,80 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
404 | d_instantiate(dentry, inode); | 422 | d_instantiate(dentry, inode); |
405 | ret = 0; | 423 | ret = 0; |
406 | fail: | 424 | fail: |
425 | kfree(pending_snapshot); | ||
407 | return ret; | 426 | return ret; |
408 | } | 427 | } |
409 | 428 | ||
429 | /* copy of check_sticky in fs/namei.c() | ||
430 | * It's inline, so penalty for filesystems that don't use sticky bit is | ||
431 | * minimal. | ||
432 | */ | ||
433 | static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode) | ||
434 | { | ||
435 | uid_t fsuid = current_fsuid(); | ||
436 | |||
437 | if (!(dir->i_mode & S_ISVTX)) | ||
438 | return 0; | ||
439 | if (inode->i_uid == fsuid) | ||
440 | return 0; | ||
441 | if (dir->i_uid == fsuid) | ||
442 | return 0; | ||
443 | return !capable(CAP_FOWNER); | ||
444 | } | ||
445 | |||
446 | /* copy of may_delete in fs/namei.c() | ||
447 | * Check whether we can remove a link victim from directory dir, check | ||
448 | * whether the type of victim is right. | ||
449 | * 1. We can't do it if dir is read-only (done in permission()) | ||
450 | * 2. We should have write and exec permissions on dir | ||
451 | * 3. We can't remove anything from append-only dir | ||
452 | * 4. We can't do anything with immutable dir (done in permission()) | ||
453 | * 5. If the sticky bit on dir is set we should either | ||
454 | * a. be owner of dir, or | ||
455 | * b. be owner of victim, or | ||
456 | * c. have CAP_FOWNER capability | ||
457 | * 6. If the victim is append-only or immutable we can't do antyhing with | ||
458 | * links pointing to it. | ||
459 | * 7. If we were asked to remove a directory and victim isn't one - ENOTDIR. | ||
460 | * 8. If we were asked to remove a non-directory and victim isn't one - EISDIR. | ||
461 | * 9. We can't remove a root or mountpoint. | ||
462 | * 10. We don't allow removal of NFS sillyrenamed files; it's handled by | ||
463 | * nfs_async_unlink(). | ||
464 | */ | ||
465 | |||
466 | static int btrfs_may_delete(struct inode *dir,struct dentry *victim,int isdir) | ||
467 | { | ||
468 | int error; | ||
469 | |||
470 | if (!victim->d_inode) | ||
471 | return -ENOENT; | ||
472 | |||
473 | BUG_ON(victim->d_parent->d_inode != dir); | ||
474 | audit_inode_child(victim, dir); | ||
475 | |||
476 | error = inode_permission(dir, MAY_WRITE | MAY_EXEC); | ||
477 | if (error) | ||
478 | return error; | ||
479 | if (IS_APPEND(dir)) | ||
480 | return -EPERM; | ||
481 | if (btrfs_check_sticky(dir, victim->d_inode)|| | ||
482 | IS_APPEND(victim->d_inode)|| | ||
483 | IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode)) | ||
484 | return -EPERM; | ||
485 | if (isdir) { | ||
486 | if (!S_ISDIR(victim->d_inode->i_mode)) | ||
487 | return -ENOTDIR; | ||
488 | if (IS_ROOT(victim)) | ||
489 | return -EBUSY; | ||
490 | } else if (S_ISDIR(victim->d_inode->i_mode)) | ||
491 | return -EISDIR; | ||
492 | if (IS_DEADDIR(dir)) | ||
493 | return -ENOENT; | ||
494 | if (victim->d_flags & DCACHE_NFSFS_RENAMED) | ||
495 | return -EBUSY; | ||
496 | return 0; | ||
497 | } | ||
498 | |||
410 | /* copy of may_create in fs/namei.c() */ | 499 | /* copy of may_create in fs/namei.c() */ |
411 | static inline int btrfs_may_create(struct inode *dir, struct dentry *child) | 500 | static inline int btrfs_may_create(struct inode *dir, struct dentry *child) |
412 | { | 501 | { |
@@ -424,7 +513,8 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child) | |||
424 | */ | 513 | */ |
425 | static noinline int btrfs_mksubvol(struct path *parent, | 514 | static noinline int btrfs_mksubvol(struct path *parent, |
426 | char *name, int namelen, | 515 | char *name, int namelen, |
427 | struct btrfs_root *snap_src) | 516 | struct btrfs_root *snap_src, |
517 | u64 *async_transid, bool readonly) | ||
428 | { | 518 | { |
429 | struct inode *dir = parent->dentry->d_inode; | 519 | struct inode *dir = parent->dentry->d_inode; |
430 | struct dentry *dentry; | 520 | struct dentry *dentry; |
@@ -456,10 +546,10 @@ static noinline int btrfs_mksubvol(struct path *parent, | |||
456 | 546 | ||
457 | if (snap_src) { | 547 | if (snap_src) { |
458 | error = create_snapshot(snap_src, dentry, | 548 | error = create_snapshot(snap_src, dentry, |
459 | name, namelen); | 549 | name, namelen, async_transid, readonly); |
460 | } else { | 550 | } else { |
461 | error = create_subvol(BTRFS_I(dir)->root, dentry, | 551 | error = create_subvol(BTRFS_I(dir)->root, dentry, |
462 | name, namelen); | 552 | name, namelen, async_transid); |
463 | } | 553 | } |
464 | if (!error) | 554 | if (!error) |
465 | fsnotify_mkdir(dir, dentry); | 555 | fsnotify_mkdir(dir, dentry); |
@@ -474,49 +564,182 @@ out_unlock: | |||
474 | return error; | 564 | return error; |
475 | } | 565 | } |
476 | 566 | ||
477 | static int btrfs_defrag_file(struct file *file) | 567 | static int should_defrag_range(struct inode *inode, u64 start, u64 len, |
568 | int thresh, u64 *last_len, u64 *skip, | ||
569 | u64 *defrag_end) | ||
570 | { | ||
571 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | ||
572 | struct extent_map *em = NULL; | ||
573 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | ||
574 | int ret = 1; | ||
575 | |||
576 | |||
577 | if (thresh == 0) | ||
578 | thresh = 256 * 1024; | ||
579 | |||
580 | /* | ||
581 | * make sure that once we start defragging and extent, we keep on | ||
582 | * defragging it | ||
583 | */ | ||
584 | if (start < *defrag_end) | ||
585 | return 1; | ||
586 | |||
587 | *skip = 0; | ||
588 | |||
589 | /* | ||
590 | * hopefully we have this extent in the tree already, try without | ||
591 | * the full extent lock | ||
592 | */ | ||
593 | read_lock(&em_tree->lock); | ||
594 | em = lookup_extent_mapping(em_tree, start, len); | ||
595 | read_unlock(&em_tree->lock); | ||
596 | |||
597 | if (!em) { | ||
598 | /* get the big lock and read metadata off disk */ | ||
599 | lock_extent(io_tree, start, start + len - 1, GFP_NOFS); | ||
600 | em = btrfs_get_extent(inode, NULL, 0, start, len, 0); | ||
601 | unlock_extent(io_tree, start, start + len - 1, GFP_NOFS); | ||
602 | |||
603 | if (IS_ERR(em)) | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | /* this will cover holes, and inline extents */ | ||
608 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) | ||
609 | ret = 0; | ||
610 | |||
611 | /* | ||
612 | * we hit a real extent, if it is big don't bother defragging it again | ||
613 | */ | ||
614 | if ((*last_len == 0 || *last_len >= thresh) && em->len >= thresh) | ||
615 | ret = 0; | ||
616 | |||
617 | /* | ||
618 | * last_len ends up being a counter of how many bytes we've defragged. | ||
619 | * every time we choose not to defrag an extent, we reset *last_len | ||
620 | * so that the next tiny extent will force a defrag. | ||
621 | * | ||
622 | * The end result of this is that tiny extents before a single big | ||
623 | * extent will force at least part of that big extent to be defragged. | ||
624 | */ | ||
625 | if (ret) { | ||
626 | *last_len += len; | ||
627 | *defrag_end = extent_map_end(em); | ||
628 | } else { | ||
629 | *last_len = 0; | ||
630 | *skip = extent_map_end(em); | ||
631 | *defrag_end = 0; | ||
632 | } | ||
633 | |||
634 | free_extent_map(em); | ||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | static int btrfs_defrag_file(struct file *file, | ||
639 | struct btrfs_ioctl_defrag_range_args *range) | ||
478 | { | 640 | { |
479 | struct inode *inode = fdentry(file)->d_inode; | 641 | struct inode *inode = fdentry(file)->d_inode; |
480 | struct btrfs_root *root = BTRFS_I(inode)->root; | 642 | struct btrfs_root *root = BTRFS_I(inode)->root; |
481 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 643 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
482 | struct btrfs_ordered_extent *ordered; | 644 | struct btrfs_ordered_extent *ordered; |
483 | struct page *page; | 645 | struct page *page; |
646 | struct btrfs_super_block *disk_super; | ||
484 | unsigned long last_index; | 647 | unsigned long last_index; |
485 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; | 648 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; |
486 | unsigned long total_read = 0; | 649 | unsigned long total_read = 0; |
650 | u64 features; | ||
487 | u64 page_start; | 651 | u64 page_start; |
488 | u64 page_end; | 652 | u64 page_end; |
653 | u64 last_len = 0; | ||
654 | u64 skip = 0; | ||
655 | u64 defrag_end = 0; | ||
489 | unsigned long i; | 656 | unsigned long i; |
490 | int ret; | 657 | int ret; |
658 | int compress_type = BTRFS_COMPRESS_ZLIB; | ||
491 | 659 | ||
492 | ret = btrfs_check_data_free_space(root, inode, inode->i_size); | 660 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) { |
493 | if (ret) | 661 | if (range->compress_type > BTRFS_COMPRESS_TYPES) |
494 | return -ENOSPC; | 662 | return -EINVAL; |
663 | if (range->compress_type) | ||
664 | compress_type = range->compress_type; | ||
665 | } | ||
666 | |||
667 | if (inode->i_size == 0) | ||
668 | return 0; | ||
669 | |||
670 | if (range->start + range->len > range->start) { | ||
671 | last_index = min_t(u64, inode->i_size - 1, | ||
672 | range->start + range->len - 1) >> PAGE_CACHE_SHIFT; | ||
673 | } else { | ||
674 | last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT; | ||
675 | } | ||
676 | |||
677 | i = range->start >> PAGE_CACHE_SHIFT; | ||
678 | while (i <= last_index) { | ||
679 | if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT, | ||
680 | PAGE_CACHE_SIZE, | ||
681 | range->extent_thresh, | ||
682 | &last_len, &skip, | ||
683 | &defrag_end)) { | ||
684 | unsigned long next; | ||
685 | /* | ||
686 | * the should_defrag function tells us how much to skip | ||
687 | * bump our counter by the suggested amount | ||
688 | */ | ||
689 | next = (skip + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
690 | i = max(i + 1, next); | ||
691 | continue; | ||
692 | } | ||
495 | 693 | ||
496 | mutex_lock(&inode->i_mutex); | ||
497 | last_index = inode->i_size >> PAGE_CACHE_SHIFT; | ||
498 | for (i = 0; i <= last_index; i++) { | ||
499 | if (total_read % ra_pages == 0) { | 694 | if (total_read % ra_pages == 0) { |
500 | btrfs_force_ra(inode->i_mapping, &file->f_ra, file, i, | 695 | btrfs_force_ra(inode->i_mapping, &file->f_ra, file, i, |
501 | min(last_index, i + ra_pages - 1)); | 696 | min(last_index, i + ra_pages - 1)); |
502 | } | 697 | } |
503 | total_read++; | 698 | total_read++; |
699 | mutex_lock(&inode->i_mutex); | ||
700 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) | ||
701 | BTRFS_I(inode)->force_compress = compress_type; | ||
702 | |||
703 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | ||
704 | if (ret) | ||
705 | goto err_unlock; | ||
504 | again: | 706 | again: |
707 | if (inode->i_size == 0 || | ||
708 | i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) { | ||
709 | ret = 0; | ||
710 | goto err_reservations; | ||
711 | } | ||
712 | |||
505 | page = grab_cache_page(inode->i_mapping, i); | 713 | page = grab_cache_page(inode->i_mapping, i); |
506 | if (!page) | 714 | if (!page) { |
507 | goto out_unlock; | 715 | ret = -ENOMEM; |
716 | goto err_reservations; | ||
717 | } | ||
718 | |||
508 | if (!PageUptodate(page)) { | 719 | if (!PageUptodate(page)) { |
509 | btrfs_readpage(NULL, page); | 720 | btrfs_readpage(NULL, page); |
510 | lock_page(page); | 721 | lock_page(page); |
511 | if (!PageUptodate(page)) { | 722 | if (!PageUptodate(page)) { |
512 | unlock_page(page); | 723 | unlock_page(page); |
513 | page_cache_release(page); | 724 | page_cache_release(page); |
514 | goto out_unlock; | 725 | ret = -EIO; |
726 | goto err_reservations; | ||
515 | } | 727 | } |
516 | } | 728 | } |
517 | 729 | ||
730 | if (page->mapping != inode->i_mapping) { | ||
731 | unlock_page(page); | ||
732 | page_cache_release(page); | ||
733 | goto again; | ||
734 | } | ||
735 | |||
518 | wait_on_page_writeback(page); | 736 | wait_on_page_writeback(page); |
519 | 737 | ||
738 | if (PageDirty(page)) { | ||
739 | btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); | ||
740 | goto loop_unlock; | ||
741 | } | ||
742 | |||
520 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; | 743 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; |
521 | page_end = page_start + PAGE_CACHE_SIZE - 1; | 744 | page_end = page_start + PAGE_CACHE_SIZE - 1; |
522 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); | 745 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); |
@@ -537,18 +760,60 @@ again: | |||
537 | * page if it is dirtied again later | 760 | * page if it is dirtied again later |
538 | */ | 761 | */ |
539 | clear_page_dirty_for_io(page); | 762 | clear_page_dirty_for_io(page); |
763 | clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, | ||
764 | page_end, EXTENT_DIRTY | EXTENT_DELALLOC | | ||
765 | EXTENT_DO_ACCOUNTING, GFP_NOFS); | ||
540 | 766 | ||
541 | btrfs_set_extent_delalloc(inode, page_start, page_end); | 767 | btrfs_set_extent_delalloc(inode, page_start, page_end, NULL); |
768 | ClearPageChecked(page); | ||
542 | set_page_dirty(page); | 769 | set_page_dirty(page); |
543 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 770 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
771 | |||
772 | loop_unlock: | ||
544 | unlock_page(page); | 773 | unlock_page(page); |
545 | page_cache_release(page); | 774 | page_cache_release(page); |
775 | mutex_unlock(&inode->i_mutex); | ||
776 | |||
546 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1); | 777 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1); |
778 | i++; | ||
779 | } | ||
780 | |||
781 | if ((range->flags & BTRFS_DEFRAG_RANGE_START_IO)) | ||
782 | filemap_flush(inode->i_mapping); | ||
783 | |||
784 | if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { | ||
785 | /* the filemap_flush will queue IO into the worker threads, but | ||
786 | * we have to make sure the IO is actually started and that | ||
787 | * ordered extents get created before we return | ||
788 | */ | ||
789 | atomic_inc(&root->fs_info->async_submit_draining); | ||
790 | while (atomic_read(&root->fs_info->nr_async_submits) || | ||
791 | atomic_read(&root->fs_info->async_delalloc_pages)) { | ||
792 | wait_event(root->fs_info->async_submit_wait, | ||
793 | (atomic_read(&root->fs_info->nr_async_submits) == 0 && | ||
794 | atomic_read(&root->fs_info->async_delalloc_pages) == 0)); | ||
795 | } | ||
796 | atomic_dec(&root->fs_info->async_submit_draining); | ||
797 | |||
798 | mutex_lock(&inode->i_mutex); | ||
799 | BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_NONE; | ||
800 | mutex_unlock(&inode->i_mutex); | ||
801 | } | ||
802 | |||
803 | disk_super = &root->fs_info->super_copy; | ||
804 | features = btrfs_super_incompat_flags(disk_super); | ||
805 | if (range->compress_type == BTRFS_COMPRESS_LZO) { | ||
806 | features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; | ||
807 | btrfs_set_super_incompat_flags(disk_super, features); | ||
547 | } | 808 | } |
548 | 809 | ||
549 | out_unlock: | ||
550 | mutex_unlock(&inode->i_mutex); | ||
551 | return 0; | 810 | return 0; |
811 | |||
812 | err_reservations: | ||
813 | btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); | ||
814 | err_unlock: | ||
815 | mutex_unlock(&inode->i_mutex); | ||
816 | return ret; | ||
552 | } | 817 | } |
553 | 818 | ||
554 | static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | 819 | static noinline int btrfs_ioctl_resize(struct btrfs_root *root, |
@@ -563,7 +828,6 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | |||
563 | char *sizestr; | 828 | char *sizestr; |
564 | char *devstr = NULL; | 829 | char *devstr = NULL; |
565 | int ret = 0; | 830 | int ret = 0; |
566 | int namelen; | ||
567 | int mod = 0; | 831 | int mod = 0; |
568 | 832 | ||
569 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 833 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
@@ -577,7 +841,6 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | |||
577 | return PTR_ERR(vol_args); | 841 | return PTR_ERR(vol_args); |
578 | 842 | ||
579 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 843 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
580 | namelen = strlen(vol_args->name); | ||
581 | 844 | ||
582 | mutex_lock(&root->fs_info->volume_mutex); | 845 | mutex_lock(&root->fs_info->volume_mutex); |
583 | sizestr = vol_args->name; | 846 | sizestr = vol_args->name; |
@@ -608,7 +871,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | |||
608 | mod = 1; | 871 | mod = 1; |
609 | sizestr++; | 872 | sizestr++; |
610 | } | 873 | } |
611 | new_size = btrfs_parse_size(sizestr); | 874 | new_size = memparse(sizestr, NULL); |
612 | if (new_size == 0) { | 875 | if (new_size == 0) { |
613 | ret = -EINVAL; | 876 | ret = -EINVAL; |
614 | goto out_unlock; | 877 | goto out_unlock; |
@@ -643,7 +906,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | |||
643 | device->name, (unsigned long long)new_size); | 906 | device->name, (unsigned long long)new_size); |
644 | 907 | ||
645 | if (new_size > old_size) { | 908 | if (new_size > old_size) { |
646 | trans = btrfs_start_transaction(root, 1); | 909 | trans = btrfs_start_transaction(root, 0); |
647 | ret = btrfs_grow_device(trans, device, new_size); | 910 | ret = btrfs_grow_device(trans, device, new_size); |
648 | btrfs_commit_transaction(trans, root); | 911 | btrfs_commit_transaction(trans, root); |
649 | } else { | 912 | } else { |
@@ -656,11 +919,14 @@ out_unlock: | |||
656 | return ret; | 919 | return ret; |
657 | } | 920 | } |
658 | 921 | ||
659 | static noinline int btrfs_ioctl_snap_create(struct file *file, | 922 | static noinline int btrfs_ioctl_snap_create_transid(struct file *file, |
660 | void __user *arg, int subvol) | 923 | char *name, |
924 | unsigned long fd, | ||
925 | int subvol, | ||
926 | u64 *transid, | ||
927 | bool readonly) | ||
661 | { | 928 | { |
662 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 929 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; |
663 | struct btrfs_ioctl_vol_args *vol_args; | ||
664 | struct file *src_file; | 930 | struct file *src_file; |
665 | int namelen; | 931 | int namelen; |
666 | int ret = 0; | 932 | int ret = 0; |
@@ -668,23 +934,18 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
668 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 934 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
669 | return -EROFS; | 935 | return -EROFS; |
670 | 936 | ||
671 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 937 | namelen = strlen(name); |
672 | if (IS_ERR(vol_args)) | 938 | if (strchr(name, '/')) { |
673 | return PTR_ERR(vol_args); | ||
674 | |||
675 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | ||
676 | namelen = strlen(vol_args->name); | ||
677 | if (strchr(vol_args->name, '/')) { | ||
678 | ret = -EINVAL; | 939 | ret = -EINVAL; |
679 | goto out; | 940 | goto out; |
680 | } | 941 | } |
681 | 942 | ||
682 | if (subvol) { | 943 | if (subvol) { |
683 | ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen, | 944 | ret = btrfs_mksubvol(&file->f_path, name, namelen, |
684 | NULL); | 945 | NULL, transid, readonly); |
685 | } else { | 946 | } else { |
686 | struct inode *src_inode; | 947 | struct inode *src_inode; |
687 | src_file = fget(vol_args->fd); | 948 | src_file = fget(fd); |
688 | if (!src_file) { | 949 | if (!src_file) { |
689 | ret = -EINVAL; | 950 | ret = -EINVAL; |
690 | goto out; | 951 | goto out; |
@@ -698,15 +959,152 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
698 | fput(src_file); | 959 | fput(src_file); |
699 | goto out; | 960 | goto out; |
700 | } | 961 | } |
701 | ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen, | 962 | ret = btrfs_mksubvol(&file->f_path, name, namelen, |
702 | BTRFS_I(src_inode)->root); | 963 | BTRFS_I(src_inode)->root, |
964 | transid, readonly); | ||
703 | fput(src_file); | 965 | fput(src_file); |
704 | } | 966 | } |
705 | out: | 967 | out: |
968 | return ret; | ||
969 | } | ||
970 | |||
971 | static noinline int btrfs_ioctl_snap_create(struct file *file, | ||
972 | void __user *arg, int subvol) | ||
973 | { | ||
974 | struct btrfs_ioctl_vol_args *vol_args; | ||
975 | int ret; | ||
976 | |||
977 | vol_args = memdup_user(arg, sizeof(*vol_args)); | ||
978 | if (IS_ERR(vol_args)) | ||
979 | return PTR_ERR(vol_args); | ||
980 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | ||
981 | |||
982 | ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, | ||
983 | vol_args->fd, subvol, | ||
984 | NULL, false); | ||
985 | |||
706 | kfree(vol_args); | 986 | kfree(vol_args); |
707 | return ret; | 987 | return ret; |
708 | } | 988 | } |
709 | 989 | ||
990 | static noinline int btrfs_ioctl_snap_create_v2(struct file *file, | ||
991 | void __user *arg, int subvol) | ||
992 | { | ||
993 | struct btrfs_ioctl_vol_args_v2 *vol_args; | ||
994 | int ret; | ||
995 | u64 transid = 0; | ||
996 | u64 *ptr = NULL; | ||
997 | bool readonly = false; | ||
998 | |||
999 | vol_args = memdup_user(arg, sizeof(*vol_args)); | ||
1000 | if (IS_ERR(vol_args)) | ||
1001 | return PTR_ERR(vol_args); | ||
1002 | vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; | ||
1003 | |||
1004 | if (vol_args->flags & | ||
1005 | ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY)) { | ||
1006 | ret = -EOPNOTSUPP; | ||
1007 | goto out; | ||
1008 | } | ||
1009 | |||
1010 | if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC) | ||
1011 | ptr = &transid; | ||
1012 | if (vol_args->flags & BTRFS_SUBVOL_RDONLY) | ||
1013 | readonly = true; | ||
1014 | |||
1015 | ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, | ||
1016 | vol_args->fd, subvol, | ||
1017 | ptr, readonly); | ||
1018 | |||
1019 | if (ret == 0 && ptr && | ||
1020 | copy_to_user(arg + | ||
1021 | offsetof(struct btrfs_ioctl_vol_args_v2, | ||
1022 | transid), ptr, sizeof(*ptr))) | ||
1023 | ret = -EFAULT; | ||
1024 | out: | ||
1025 | kfree(vol_args); | ||
1026 | return ret; | ||
1027 | } | ||
1028 | |||
1029 | static noinline int btrfs_ioctl_subvol_getflags(struct file *file, | ||
1030 | void __user *arg) | ||
1031 | { | ||
1032 | struct inode *inode = fdentry(file)->d_inode; | ||
1033 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
1034 | int ret = 0; | ||
1035 | u64 flags = 0; | ||
1036 | |||
1037 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) | ||
1038 | return -EINVAL; | ||
1039 | |||
1040 | down_read(&root->fs_info->subvol_sem); | ||
1041 | if (btrfs_root_readonly(root)) | ||
1042 | flags |= BTRFS_SUBVOL_RDONLY; | ||
1043 | up_read(&root->fs_info->subvol_sem); | ||
1044 | |||
1045 | if (copy_to_user(arg, &flags, sizeof(flags))) | ||
1046 | ret = -EFAULT; | ||
1047 | |||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | static noinline int btrfs_ioctl_subvol_setflags(struct file *file, | ||
1052 | void __user *arg) | ||
1053 | { | ||
1054 | struct inode *inode = fdentry(file)->d_inode; | ||
1055 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
1056 | struct btrfs_trans_handle *trans; | ||
1057 | u64 root_flags; | ||
1058 | u64 flags; | ||
1059 | int ret = 0; | ||
1060 | |||
1061 | if (root->fs_info->sb->s_flags & MS_RDONLY) | ||
1062 | return -EROFS; | ||
1063 | |||
1064 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) | ||
1065 | return -EINVAL; | ||
1066 | |||
1067 | if (copy_from_user(&flags, arg, sizeof(flags))) | ||
1068 | return -EFAULT; | ||
1069 | |||
1070 | if (flags & ~BTRFS_SUBVOL_CREATE_ASYNC) | ||
1071 | return -EINVAL; | ||
1072 | |||
1073 | if (flags & ~BTRFS_SUBVOL_RDONLY) | ||
1074 | return -EOPNOTSUPP; | ||
1075 | |||
1076 | down_write(&root->fs_info->subvol_sem); | ||
1077 | |||
1078 | /* nothing to do */ | ||
1079 | if (!!(flags & BTRFS_SUBVOL_RDONLY) == btrfs_root_readonly(root)) | ||
1080 | goto out; | ||
1081 | |||
1082 | root_flags = btrfs_root_flags(&root->root_item); | ||
1083 | if (flags & BTRFS_SUBVOL_RDONLY) | ||
1084 | btrfs_set_root_flags(&root->root_item, | ||
1085 | root_flags | BTRFS_ROOT_SUBVOL_RDONLY); | ||
1086 | else | ||
1087 | btrfs_set_root_flags(&root->root_item, | ||
1088 | root_flags & ~BTRFS_ROOT_SUBVOL_RDONLY); | ||
1089 | |||
1090 | trans = btrfs_start_transaction(root, 1); | ||
1091 | if (IS_ERR(trans)) { | ||
1092 | ret = PTR_ERR(trans); | ||
1093 | goto out_reset; | ||
1094 | } | ||
1095 | |||
1096 | ret = btrfs_update_root(trans, root, | ||
1097 | &root->root_key, &root->root_item); | ||
1098 | |||
1099 | btrfs_commit_transaction(trans, root); | ||
1100 | out_reset: | ||
1101 | if (ret) | ||
1102 | btrfs_set_root_flags(&root->root_item, root_flags); | ||
1103 | out: | ||
1104 | up_write(&root->fs_info->subvol_sem); | ||
1105 | return ret; | ||
1106 | } | ||
1107 | |||
710 | /* | 1108 | /* |
711 | * helper to check if the subvolume references other subvolumes | 1109 | * helper to check if the subvolume references other subvolumes |
712 | */ | 1110 | */ |
@@ -743,6 +1141,322 @@ out: | |||
743 | return ret; | 1141 | return ret; |
744 | } | 1142 | } |
745 | 1143 | ||
1144 | static noinline int key_in_sk(struct btrfs_key *key, | ||
1145 | struct btrfs_ioctl_search_key *sk) | ||
1146 | { | ||
1147 | struct btrfs_key test; | ||
1148 | int ret; | ||
1149 | |||
1150 | test.objectid = sk->min_objectid; | ||
1151 | test.type = sk->min_type; | ||
1152 | test.offset = sk->min_offset; | ||
1153 | |||
1154 | ret = btrfs_comp_cpu_keys(key, &test); | ||
1155 | if (ret < 0) | ||
1156 | return 0; | ||
1157 | |||
1158 | test.objectid = sk->max_objectid; | ||
1159 | test.type = sk->max_type; | ||
1160 | test.offset = sk->max_offset; | ||
1161 | |||
1162 | ret = btrfs_comp_cpu_keys(key, &test); | ||
1163 | if (ret > 0) | ||
1164 | return 0; | ||
1165 | return 1; | ||
1166 | } | ||
1167 | |||
1168 | static noinline int copy_to_sk(struct btrfs_root *root, | ||
1169 | struct btrfs_path *path, | ||
1170 | struct btrfs_key *key, | ||
1171 | struct btrfs_ioctl_search_key *sk, | ||
1172 | char *buf, | ||
1173 | unsigned long *sk_offset, | ||
1174 | int *num_found) | ||
1175 | { | ||
1176 | u64 found_transid; | ||
1177 | struct extent_buffer *leaf; | ||
1178 | struct btrfs_ioctl_search_header sh; | ||
1179 | unsigned long item_off; | ||
1180 | unsigned long item_len; | ||
1181 | int nritems; | ||
1182 | int i; | ||
1183 | int slot; | ||
1184 | int found = 0; | ||
1185 | int ret = 0; | ||
1186 | |||
1187 | leaf = path->nodes[0]; | ||
1188 | slot = path->slots[0]; | ||
1189 | nritems = btrfs_header_nritems(leaf); | ||
1190 | |||
1191 | if (btrfs_header_generation(leaf) > sk->max_transid) { | ||
1192 | i = nritems; | ||
1193 | goto advance_key; | ||
1194 | } | ||
1195 | found_transid = btrfs_header_generation(leaf); | ||
1196 | |||
1197 | for (i = slot; i < nritems; i++) { | ||
1198 | item_off = btrfs_item_ptr_offset(leaf, i); | ||
1199 | item_len = btrfs_item_size_nr(leaf, i); | ||
1200 | |||
1201 | if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE) | ||
1202 | item_len = 0; | ||
1203 | |||
1204 | if (sizeof(sh) + item_len + *sk_offset > | ||
1205 | BTRFS_SEARCH_ARGS_BUFSIZE) { | ||
1206 | ret = 1; | ||
1207 | goto overflow; | ||
1208 | } | ||
1209 | |||
1210 | btrfs_item_key_to_cpu(leaf, key, i); | ||
1211 | if (!key_in_sk(key, sk)) | ||
1212 | continue; | ||
1213 | |||
1214 | sh.objectid = key->objectid; | ||
1215 | sh.offset = key->offset; | ||
1216 | sh.type = key->type; | ||
1217 | sh.len = item_len; | ||
1218 | sh.transid = found_transid; | ||
1219 | |||
1220 | /* copy search result header */ | ||
1221 | memcpy(buf + *sk_offset, &sh, sizeof(sh)); | ||
1222 | *sk_offset += sizeof(sh); | ||
1223 | |||
1224 | if (item_len) { | ||
1225 | char *p = buf + *sk_offset; | ||
1226 | /* copy the item */ | ||
1227 | read_extent_buffer(leaf, p, | ||
1228 | item_off, item_len); | ||
1229 | *sk_offset += item_len; | ||
1230 | } | ||
1231 | found++; | ||
1232 | |||
1233 | if (*num_found >= sk->nr_items) | ||
1234 | break; | ||
1235 | } | ||
1236 | advance_key: | ||
1237 | ret = 0; | ||
1238 | if (key->offset < (u64)-1 && key->offset < sk->max_offset) | ||
1239 | key->offset++; | ||
1240 | else if (key->type < (u8)-1 && key->type < sk->max_type) { | ||
1241 | key->offset = 0; | ||
1242 | key->type++; | ||
1243 | } else if (key->objectid < (u64)-1 && key->objectid < sk->max_objectid) { | ||
1244 | key->offset = 0; | ||
1245 | key->type = 0; | ||
1246 | key->objectid++; | ||
1247 | } else | ||
1248 | ret = 1; | ||
1249 | overflow: | ||
1250 | *num_found += found; | ||
1251 | return ret; | ||
1252 | } | ||
1253 | |||
1254 | static noinline int search_ioctl(struct inode *inode, | ||
1255 | struct btrfs_ioctl_search_args *args) | ||
1256 | { | ||
1257 | struct btrfs_root *root; | ||
1258 | struct btrfs_key key; | ||
1259 | struct btrfs_key max_key; | ||
1260 | struct btrfs_path *path; | ||
1261 | struct btrfs_ioctl_search_key *sk = &args->key; | ||
1262 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; | ||
1263 | int ret; | ||
1264 | int num_found = 0; | ||
1265 | unsigned long sk_offset = 0; | ||
1266 | |||
1267 | path = btrfs_alloc_path(); | ||
1268 | if (!path) | ||
1269 | return -ENOMEM; | ||
1270 | |||
1271 | if (sk->tree_id == 0) { | ||
1272 | /* search the root of the inode that was passed */ | ||
1273 | root = BTRFS_I(inode)->root; | ||
1274 | } else { | ||
1275 | key.objectid = sk->tree_id; | ||
1276 | key.type = BTRFS_ROOT_ITEM_KEY; | ||
1277 | key.offset = (u64)-1; | ||
1278 | root = btrfs_read_fs_root_no_name(info, &key); | ||
1279 | if (IS_ERR(root)) { | ||
1280 | printk(KERN_ERR "could not find root %llu\n", | ||
1281 | sk->tree_id); | ||
1282 | btrfs_free_path(path); | ||
1283 | return -ENOENT; | ||
1284 | } | ||
1285 | } | ||
1286 | |||
1287 | key.objectid = sk->min_objectid; | ||
1288 | key.type = sk->min_type; | ||
1289 | key.offset = sk->min_offset; | ||
1290 | |||
1291 | max_key.objectid = sk->max_objectid; | ||
1292 | max_key.type = sk->max_type; | ||
1293 | max_key.offset = sk->max_offset; | ||
1294 | |||
1295 | path->keep_locks = 1; | ||
1296 | |||
1297 | while(1) { | ||
1298 | ret = btrfs_search_forward(root, &key, &max_key, path, 0, | ||
1299 | sk->min_transid); | ||
1300 | if (ret != 0) { | ||
1301 | if (ret > 0) | ||
1302 | ret = 0; | ||
1303 | goto err; | ||
1304 | } | ||
1305 | ret = copy_to_sk(root, path, &key, sk, args->buf, | ||
1306 | &sk_offset, &num_found); | ||
1307 | btrfs_release_path(root, path); | ||
1308 | if (ret || num_found >= sk->nr_items) | ||
1309 | break; | ||
1310 | |||
1311 | } | ||
1312 | ret = 0; | ||
1313 | err: | ||
1314 | sk->nr_items = num_found; | ||
1315 | btrfs_free_path(path); | ||
1316 | return ret; | ||
1317 | } | ||
1318 | |||
1319 | static noinline int btrfs_ioctl_tree_search(struct file *file, | ||
1320 | void __user *argp) | ||
1321 | { | ||
1322 | struct btrfs_ioctl_search_args *args; | ||
1323 | struct inode *inode; | ||
1324 | int ret; | ||
1325 | |||
1326 | if (!capable(CAP_SYS_ADMIN)) | ||
1327 | return -EPERM; | ||
1328 | |||
1329 | args = memdup_user(argp, sizeof(*args)); | ||
1330 | if (IS_ERR(args)) | ||
1331 | return PTR_ERR(args); | ||
1332 | |||
1333 | inode = fdentry(file)->d_inode; | ||
1334 | ret = search_ioctl(inode, args); | ||
1335 | if (ret == 0 && copy_to_user(argp, args, sizeof(*args))) | ||
1336 | ret = -EFAULT; | ||
1337 | kfree(args); | ||
1338 | return ret; | ||
1339 | } | ||
1340 | |||
1341 | /* | ||
1342 | * Search INODE_REFs to identify path name of 'dirid' directory | ||
1343 | * in a 'tree_id' tree. and sets path name to 'name'. | ||
1344 | */ | ||
1345 | static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | ||
1346 | u64 tree_id, u64 dirid, char *name) | ||
1347 | { | ||
1348 | struct btrfs_root *root; | ||
1349 | struct btrfs_key key; | ||
1350 | char *ptr; | ||
1351 | int ret = -1; | ||
1352 | int slot; | ||
1353 | int len; | ||
1354 | int total_len = 0; | ||
1355 | struct btrfs_inode_ref *iref; | ||
1356 | struct extent_buffer *l; | ||
1357 | struct btrfs_path *path; | ||
1358 | |||
1359 | if (dirid == BTRFS_FIRST_FREE_OBJECTID) { | ||
1360 | name[0]='\0'; | ||
1361 | return 0; | ||
1362 | } | ||
1363 | |||
1364 | path = btrfs_alloc_path(); | ||
1365 | if (!path) | ||
1366 | return -ENOMEM; | ||
1367 | |||
1368 | ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX]; | ||
1369 | |||
1370 | key.objectid = tree_id; | ||
1371 | key.type = BTRFS_ROOT_ITEM_KEY; | ||
1372 | key.offset = (u64)-1; | ||
1373 | root = btrfs_read_fs_root_no_name(info, &key); | ||
1374 | if (IS_ERR(root)) { | ||
1375 | printk(KERN_ERR "could not find root %llu\n", tree_id); | ||
1376 | ret = -ENOENT; | ||
1377 | goto out; | ||
1378 | } | ||
1379 | |||
1380 | key.objectid = dirid; | ||
1381 | key.type = BTRFS_INODE_REF_KEY; | ||
1382 | key.offset = (u64)-1; | ||
1383 | |||
1384 | while(1) { | ||
1385 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
1386 | if (ret < 0) | ||
1387 | goto out; | ||
1388 | |||
1389 | l = path->nodes[0]; | ||
1390 | slot = path->slots[0]; | ||
1391 | if (ret > 0 && slot > 0) | ||
1392 | slot--; | ||
1393 | btrfs_item_key_to_cpu(l, &key, slot); | ||
1394 | |||
1395 | if (ret > 0 && (key.objectid != dirid || | ||
1396 | key.type != BTRFS_INODE_REF_KEY)) { | ||
1397 | ret = -ENOENT; | ||
1398 | goto out; | ||
1399 | } | ||
1400 | |||
1401 | iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref); | ||
1402 | len = btrfs_inode_ref_name_len(l, iref); | ||
1403 | ptr -= len + 1; | ||
1404 | total_len += len + 1; | ||
1405 | if (ptr < name) | ||
1406 | goto out; | ||
1407 | |||
1408 | *(ptr + len) = '/'; | ||
1409 | read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len); | ||
1410 | |||
1411 | if (key.offset == BTRFS_FIRST_FREE_OBJECTID) | ||
1412 | break; | ||
1413 | |||
1414 | btrfs_release_path(root, path); | ||
1415 | key.objectid = key.offset; | ||
1416 | key.offset = (u64)-1; | ||
1417 | dirid = key.objectid; | ||
1418 | |||
1419 | } | ||
1420 | if (ptr < name) | ||
1421 | goto out; | ||
1422 | memcpy(name, ptr, total_len); | ||
1423 | name[total_len]='\0'; | ||
1424 | ret = 0; | ||
1425 | out: | ||
1426 | btrfs_free_path(path); | ||
1427 | return ret; | ||
1428 | } | ||
1429 | |||
1430 | static noinline int btrfs_ioctl_ino_lookup(struct file *file, | ||
1431 | void __user *argp) | ||
1432 | { | ||
1433 | struct btrfs_ioctl_ino_lookup_args *args; | ||
1434 | struct inode *inode; | ||
1435 | int ret; | ||
1436 | |||
1437 | if (!capable(CAP_SYS_ADMIN)) | ||
1438 | return -EPERM; | ||
1439 | |||
1440 | args = memdup_user(argp, sizeof(*args)); | ||
1441 | if (IS_ERR(args)) | ||
1442 | return PTR_ERR(args); | ||
1443 | |||
1444 | inode = fdentry(file)->d_inode; | ||
1445 | |||
1446 | if (args->treeid == 0) | ||
1447 | args->treeid = BTRFS_I(inode)->root->root_key.objectid; | ||
1448 | |||
1449 | ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info, | ||
1450 | args->treeid, args->objectid, | ||
1451 | args->name); | ||
1452 | |||
1453 | if (ret == 0 && copy_to_user(argp, args, sizeof(*args))) | ||
1454 | ret = -EFAULT; | ||
1455 | |||
1456 | kfree(args); | ||
1457 | return ret; | ||
1458 | } | ||
1459 | |||
746 | static noinline int btrfs_ioctl_snap_destroy(struct file *file, | 1460 | static noinline int btrfs_ioctl_snap_destroy(struct file *file, |
747 | void __user *arg) | 1461 | void __user *arg) |
748 | { | 1462 | { |
@@ -758,9 +1472,6 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
758 | int ret; | 1472 | int ret; |
759 | int err = 0; | 1473 | int err = 0; |
760 | 1474 | ||
761 | if (!capable(CAP_SYS_ADMIN)) | ||
762 | return -EPERM; | ||
763 | |||
764 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 1475 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
765 | if (IS_ERR(vol_args)) | 1476 | if (IS_ERR(vol_args)) |
766 | return PTR_ERR(vol_args); | 1477 | return PTR_ERR(vol_args); |
@@ -790,13 +1501,51 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
790 | } | 1501 | } |
791 | 1502 | ||
792 | inode = dentry->d_inode; | 1503 | inode = dentry->d_inode; |
1504 | dest = BTRFS_I(inode)->root; | ||
1505 | if (!capable(CAP_SYS_ADMIN)){ | ||
1506 | /* | ||
1507 | * Regular user. Only allow this with a special mount | ||
1508 | * option, when the user has write+exec access to the | ||
1509 | * subvol root, and when rmdir(2) would have been | ||
1510 | * allowed. | ||
1511 | * | ||
1512 | * Note that this is _not_ check that the subvol is | ||
1513 | * empty or doesn't contain data that we wouldn't | ||
1514 | * otherwise be able to delete. | ||
1515 | * | ||
1516 | * Users who want to delete empty subvols should try | ||
1517 | * rmdir(2). | ||
1518 | */ | ||
1519 | err = -EPERM; | ||
1520 | if (!btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | ||
1521 | goto out_dput; | ||
1522 | |||
1523 | /* | ||
1524 | * Do not allow deletion if the parent dir is the same | ||
1525 | * as the dir to be deleted. That means the ioctl | ||
1526 | * must be called on the dentry referencing the root | ||
1527 | * of the subvol, not a random directory contained | ||
1528 | * within it. | ||
1529 | */ | ||
1530 | err = -EINVAL; | ||
1531 | if (root == dest) | ||
1532 | goto out_dput; | ||
1533 | |||
1534 | err = inode_permission(inode, MAY_WRITE | MAY_EXEC); | ||
1535 | if (err) | ||
1536 | goto out_dput; | ||
1537 | |||
1538 | /* check if subvolume may be deleted by a non-root user */ | ||
1539 | err = btrfs_may_delete(dir, dentry, 1); | ||
1540 | if (err) | ||
1541 | goto out_dput; | ||
1542 | } | ||
1543 | |||
793 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { | 1544 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { |
794 | err = -EINVAL; | 1545 | err = -EINVAL; |
795 | goto out_dput; | 1546 | goto out_dput; |
796 | } | 1547 | } |
797 | 1548 | ||
798 | dest = BTRFS_I(inode)->root; | ||
799 | |||
800 | mutex_lock(&inode->i_mutex); | 1549 | mutex_lock(&inode->i_mutex); |
801 | err = d_invalidate(dentry); | 1550 | err = d_invalidate(dentry); |
802 | if (err) | 1551 | if (err) |
@@ -808,7 +1557,13 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
808 | if (err) | 1557 | if (err) |
809 | goto out_up_write; | 1558 | goto out_up_write; |
810 | 1559 | ||
811 | trans = btrfs_start_transaction(root, 1); | 1560 | trans = btrfs_start_transaction(root, 0); |
1561 | if (IS_ERR(trans)) { | ||
1562 | err = PTR_ERR(trans); | ||
1563 | goto out_up_write; | ||
1564 | } | ||
1565 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
1566 | |||
812 | ret = btrfs_unlink_subvol(trans, root, dir, | 1567 | ret = btrfs_unlink_subvol(trans, root, dir, |
813 | dest->root_key.objectid, | 1568 | dest->root_key.objectid, |
814 | dentry->d_name.name, | 1569 | dentry->d_name.name, |
@@ -822,12 +1577,14 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
822 | dest->root_item.drop_level = 0; | 1577 | dest->root_item.drop_level = 0; |
823 | btrfs_set_root_refs(&dest->root_item, 0); | 1578 | btrfs_set_root_refs(&dest->root_item, 0); |
824 | 1579 | ||
825 | ret = btrfs_insert_orphan_item(trans, | 1580 | if (!xchg(&dest->orphan_item_inserted, 1)) { |
826 | root->fs_info->tree_root, | 1581 | ret = btrfs_insert_orphan_item(trans, |
827 | dest->root_key.objectid); | 1582 | root->fs_info->tree_root, |
828 | BUG_ON(ret); | 1583 | dest->root_key.objectid); |
1584 | BUG_ON(ret); | ||
1585 | } | ||
829 | 1586 | ||
830 | ret = btrfs_commit_transaction(trans, root); | 1587 | ret = btrfs_end_transaction(trans, root); |
831 | BUG_ON(ret); | 1588 | BUG_ON(ret); |
832 | inode->i_flags |= S_DEAD; | 1589 | inode->i_flags |= S_DEAD; |
833 | out_up_write: | 1590 | out_up_write: |
@@ -849,12 +1606,16 @@ out: | |||
849 | return err; | 1606 | return err; |
850 | } | 1607 | } |
851 | 1608 | ||
852 | static int btrfs_ioctl_defrag(struct file *file) | 1609 | static int btrfs_ioctl_defrag(struct file *file, void __user *argp) |
853 | { | 1610 | { |
854 | struct inode *inode = fdentry(file)->d_inode; | 1611 | struct inode *inode = fdentry(file)->d_inode; |
855 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1612 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1613 | struct btrfs_ioctl_defrag_range_args *range; | ||
856 | int ret; | 1614 | int ret; |
857 | 1615 | ||
1616 | if (btrfs_root_readonly(root)) | ||
1617 | return -EROFS; | ||
1618 | |||
858 | ret = mnt_want_write(file->f_path.mnt); | 1619 | ret = mnt_want_write(file->f_path.mnt); |
859 | if (ret) | 1620 | if (ret) |
860 | return ret; | 1621 | return ret; |
@@ -865,16 +1626,44 @@ static int btrfs_ioctl_defrag(struct file *file) | |||
865 | ret = -EPERM; | 1626 | ret = -EPERM; |
866 | goto out; | 1627 | goto out; |
867 | } | 1628 | } |
868 | btrfs_defrag_root(root, 0); | 1629 | ret = btrfs_defrag_root(root, 0); |
869 | btrfs_defrag_root(root->fs_info->extent_root, 0); | 1630 | if (ret) |
1631 | goto out; | ||
1632 | ret = btrfs_defrag_root(root->fs_info->extent_root, 0); | ||
870 | break; | 1633 | break; |
871 | case S_IFREG: | 1634 | case S_IFREG: |
872 | if (!(file->f_mode & FMODE_WRITE)) { | 1635 | if (!(file->f_mode & FMODE_WRITE)) { |
873 | ret = -EINVAL; | 1636 | ret = -EINVAL; |
874 | goto out; | 1637 | goto out; |
875 | } | 1638 | } |
876 | btrfs_defrag_file(file); | 1639 | |
1640 | range = kzalloc(sizeof(*range), GFP_KERNEL); | ||
1641 | if (!range) { | ||
1642 | ret = -ENOMEM; | ||
1643 | goto out; | ||
1644 | } | ||
1645 | |||
1646 | if (argp) { | ||
1647 | if (copy_from_user(range, argp, | ||
1648 | sizeof(*range))) { | ||
1649 | ret = -EFAULT; | ||
1650 | kfree(range); | ||
1651 | goto out; | ||
1652 | } | ||
1653 | /* compression requires us to start the IO */ | ||
1654 | if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { | ||
1655 | range->flags |= BTRFS_DEFRAG_RANGE_START_IO; | ||
1656 | range->extent_thresh = (u32)-1; | ||
1657 | } | ||
1658 | } else { | ||
1659 | /* the rest are all set to zero by kzalloc */ | ||
1660 | range->len = (u64)-1; | ||
1661 | } | ||
1662 | ret = btrfs_defrag_file(file, range); | ||
1663 | kfree(range); | ||
877 | break; | 1664 | break; |
1665 | default: | ||
1666 | ret = -EINVAL; | ||
878 | } | 1667 | } |
879 | out: | 1668 | out: |
880 | mnt_drop_write(file->f_path.mnt); | 1669 | mnt_drop_write(file->f_path.mnt); |
@@ -952,9 +1741,12 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
952 | */ | 1741 | */ |
953 | 1742 | ||
954 | /* the destination must be opened for writing */ | 1743 | /* the destination must be opened for writing */ |
955 | if (!(file->f_mode & FMODE_WRITE)) | 1744 | if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) |
956 | return -EINVAL; | 1745 | return -EINVAL; |
957 | 1746 | ||
1747 | if (btrfs_root_readonly(root)) | ||
1748 | return -EROFS; | ||
1749 | |||
958 | ret = mnt_want_write(file->f_path.mnt); | 1750 | ret = mnt_want_write(file->f_path.mnt); |
959 | if (ret) | 1751 | if (ret) |
960 | return ret; | 1752 | return ret; |
@@ -964,12 +1756,17 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
964 | ret = -EBADF; | 1756 | ret = -EBADF; |
965 | goto out_drop_write; | 1757 | goto out_drop_write; |
966 | } | 1758 | } |
1759 | |||
967 | src = src_file->f_dentry->d_inode; | 1760 | src = src_file->f_dentry->d_inode; |
968 | 1761 | ||
969 | ret = -EINVAL; | 1762 | ret = -EINVAL; |
970 | if (src == inode) | 1763 | if (src == inode) |
971 | goto out_fput; | 1764 | goto out_fput; |
972 | 1765 | ||
1766 | /* the src must be open for reading */ | ||
1767 | if (!(src_file->f_mode & FMODE_READ)) | ||
1768 | goto out_fput; | ||
1769 | |||
973 | ret = -EISDIR; | 1770 | ret = -EISDIR; |
974 | if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) | 1771 | if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) |
975 | goto out_fput; | 1772 | goto out_fput; |
@@ -991,27 +1788,26 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
991 | path->reada = 2; | 1788 | path->reada = 2; |
992 | 1789 | ||
993 | if (inode < src) { | 1790 | if (inode < src) { |
994 | mutex_lock(&inode->i_mutex); | 1791 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); |
995 | mutex_lock(&src->i_mutex); | 1792 | mutex_lock_nested(&src->i_mutex, I_MUTEX_CHILD); |
996 | } else { | 1793 | } else { |
997 | mutex_lock(&src->i_mutex); | 1794 | mutex_lock_nested(&src->i_mutex, I_MUTEX_PARENT); |
998 | mutex_lock(&inode->i_mutex); | 1795 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); |
999 | } | 1796 | } |
1000 | 1797 | ||
1001 | /* determine range to clone */ | 1798 | /* determine range to clone */ |
1002 | ret = -EINVAL; | 1799 | ret = -EINVAL; |
1003 | if (off >= src->i_size || off + len > src->i_size) | 1800 | if (off + len > src->i_size || off + len < off) |
1004 | goto out_unlock; | 1801 | goto out_unlock; |
1005 | if (len == 0) | 1802 | if (len == 0) |
1006 | olen = len = src->i_size - off; | 1803 | olen = len = src->i_size - off; |
1007 | /* if we extend to eof, continue to block boundary */ | 1804 | /* if we extend to eof, continue to block boundary */ |
1008 | if (off + len == src->i_size) | 1805 | if (off + len == src->i_size) |
1009 | len = ((src->i_size + bs-1) & ~(bs-1)) | 1806 | len = ALIGN(src->i_size, bs) - off; |
1010 | - off; | ||
1011 | 1807 | ||
1012 | /* verify the end result is block aligned */ | 1808 | /* verify the end result is block aligned */ |
1013 | if ((off & (bs-1)) || | 1809 | if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) || |
1014 | ((off + len) & (bs-1))) | 1810 | !IS_ALIGNED(destoff, bs)) |
1015 | goto out_unlock; | 1811 | goto out_unlock; |
1016 | 1812 | ||
1017 | /* do any pending delalloc/csum calc on src, one way or | 1813 | /* do any pending delalloc/csum calc on src, one way or |
@@ -1019,21 +1815,17 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1019 | while (1) { | 1815 | while (1) { |
1020 | struct btrfs_ordered_extent *ordered; | 1816 | struct btrfs_ordered_extent *ordered; |
1021 | lock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); | 1817 | lock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); |
1022 | ordered = btrfs_lookup_first_ordered_extent(inode, off+len); | 1818 | ordered = btrfs_lookup_first_ordered_extent(src, off+len); |
1023 | if (BTRFS_I(src)->delalloc_bytes == 0 && !ordered) | 1819 | if (!ordered && |
1820 | !test_range_bit(&BTRFS_I(src)->io_tree, off, off+len, | ||
1821 | EXTENT_DELALLOC, 0, NULL)) | ||
1024 | break; | 1822 | break; |
1025 | unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); | 1823 | unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); |
1026 | if (ordered) | 1824 | if (ordered) |
1027 | btrfs_put_ordered_extent(ordered); | 1825 | btrfs_put_ordered_extent(ordered); |
1028 | btrfs_wait_ordered_range(src, off, off+len); | 1826 | btrfs_wait_ordered_range(src, off, len); |
1029 | } | 1827 | } |
1030 | 1828 | ||
1031 | trans = btrfs_start_transaction(root, 1); | ||
1032 | BUG_ON(!trans); | ||
1033 | |||
1034 | /* punch hole in destination first */ | ||
1035 | btrfs_drop_extents(trans, inode, off, off + len, &hint_byte, 1); | ||
1036 | |||
1037 | /* clone data */ | 1829 | /* clone data */ |
1038 | key.objectid = src->i_ino; | 1830 | key.objectid = src->i_ino; |
1039 | key.type = BTRFS_EXTENT_DATA_KEY; | 1831 | key.type = BTRFS_EXTENT_DATA_KEY; |
@@ -1044,7 +1836,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1044 | * note the key will change type as we walk through the | 1836 | * note the key will change type as we walk through the |
1045 | * tree. | 1837 | * tree. |
1046 | */ | 1838 | */ |
1047 | ret = btrfs_search_slot(trans, root, &key, path, 0, 0); | 1839 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
1048 | if (ret < 0) | 1840 | if (ret < 0) |
1049 | goto out; | 1841 | goto out; |
1050 | 1842 | ||
@@ -1073,6 +1865,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1073 | u64 disko = 0, diskl = 0; | 1865 | u64 disko = 0, diskl = 0; |
1074 | u64 datao = 0, datal = 0; | 1866 | u64 datao = 0, datal = 0; |
1075 | u8 comp; | 1867 | u8 comp; |
1868 | u64 endoff; | ||
1076 | 1869 | ||
1077 | size = btrfs_item_size_nr(leaf, slot); | 1870 | size = btrfs_item_size_nr(leaf, slot); |
1078 | read_extent_buffer(leaf, buf, | 1871 | read_extent_buffer(leaf, buf, |
@@ -1099,7 +1892,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1099 | } | 1892 | } |
1100 | btrfs_release_path(root, path); | 1893 | btrfs_release_path(root, path); |
1101 | 1894 | ||
1102 | if (key.offset + datal < off || | 1895 | if (key.offset + datal <= off || |
1103 | key.offset >= off+len) | 1896 | key.offset >= off+len) |
1104 | goto next; | 1897 | goto next; |
1105 | 1898 | ||
@@ -1107,12 +1900,31 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1107 | new_key.objectid = inode->i_ino; | 1900 | new_key.objectid = inode->i_ino; |
1108 | new_key.offset = key.offset + destoff - off; | 1901 | new_key.offset = key.offset + destoff - off; |
1109 | 1902 | ||
1903 | trans = btrfs_start_transaction(root, 1); | ||
1904 | if (IS_ERR(trans)) { | ||
1905 | ret = PTR_ERR(trans); | ||
1906 | goto out; | ||
1907 | } | ||
1908 | |||
1110 | if (type == BTRFS_FILE_EXTENT_REG || | 1909 | if (type == BTRFS_FILE_EXTENT_REG || |
1111 | type == BTRFS_FILE_EXTENT_PREALLOC) { | 1910 | type == BTRFS_FILE_EXTENT_PREALLOC) { |
1911 | if (off > key.offset) { | ||
1912 | datao += off - key.offset; | ||
1913 | datal -= off - key.offset; | ||
1914 | } | ||
1915 | |||
1916 | if (key.offset + datal > off + len) | ||
1917 | datal = off + len - key.offset; | ||
1918 | |||
1919 | ret = btrfs_drop_extents(trans, inode, | ||
1920 | new_key.offset, | ||
1921 | new_key.offset + datal, | ||
1922 | &hint_byte, 1); | ||
1923 | BUG_ON(ret); | ||
1924 | |||
1112 | ret = btrfs_insert_empty_item(trans, root, path, | 1925 | ret = btrfs_insert_empty_item(trans, root, path, |
1113 | &new_key, size); | 1926 | &new_key, size); |
1114 | if (ret) | 1927 | BUG_ON(ret); |
1115 | goto out; | ||
1116 | 1928 | ||
1117 | leaf = path->nodes[0]; | 1929 | leaf = path->nodes[0]; |
1118 | slot = path->slots[0]; | 1930 | slot = path->slots[0]; |
@@ -1123,14 +1935,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1123 | extent = btrfs_item_ptr(leaf, slot, | 1935 | extent = btrfs_item_ptr(leaf, slot, |
1124 | struct btrfs_file_extent_item); | 1936 | struct btrfs_file_extent_item); |
1125 | 1937 | ||
1126 | if (off > key.offset) { | ||
1127 | datao += off - key.offset; | ||
1128 | datal -= off - key.offset; | ||
1129 | } | ||
1130 | |||
1131 | if (key.offset + datal > off + len) | ||
1132 | datal = off + len - key.offset; | ||
1133 | |||
1134 | /* disko == 0 means it's a hole */ | 1938 | /* disko == 0 means it's a hole */ |
1135 | if (!disko) | 1939 | if (!disko) |
1136 | datao = 0; | 1940 | datao = 0; |
@@ -1161,14 +1965,21 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1161 | 1965 | ||
1162 | if (comp && (skip || trim)) { | 1966 | if (comp && (skip || trim)) { |
1163 | ret = -EINVAL; | 1967 | ret = -EINVAL; |
1968 | btrfs_end_transaction(trans, root); | ||
1164 | goto out; | 1969 | goto out; |
1165 | } | 1970 | } |
1166 | size -= skip + trim; | 1971 | size -= skip + trim; |
1167 | datal -= skip + trim; | 1972 | datal -= skip + trim; |
1973 | |||
1974 | ret = btrfs_drop_extents(trans, inode, | ||
1975 | new_key.offset, | ||
1976 | new_key.offset + datal, | ||
1977 | &hint_byte, 1); | ||
1978 | BUG_ON(ret); | ||
1979 | |||
1168 | ret = btrfs_insert_empty_item(trans, root, path, | 1980 | ret = btrfs_insert_empty_item(trans, root, path, |
1169 | &new_key, size); | 1981 | &new_key, size); |
1170 | if (ret) | 1982 | BUG_ON(ret); |
1171 | goto out; | ||
1172 | 1983 | ||
1173 | if (skip) { | 1984 | if (skip) { |
1174 | u32 start = | 1985 | u32 start = |
@@ -1186,8 +1997,26 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1186 | } | 1997 | } |
1187 | 1998 | ||
1188 | btrfs_mark_buffer_dirty(leaf); | 1999 | btrfs_mark_buffer_dirty(leaf); |
1189 | } | 2000 | btrfs_release_path(root, path); |
1190 | 2001 | ||
2002 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
2003 | |||
2004 | /* | ||
2005 | * we round up to the block size at eof when | ||
2006 | * determining which extents to clone above, | ||
2007 | * but shouldn't round up the file size | ||
2008 | */ | ||
2009 | endoff = new_key.offset + datal; | ||
2010 | if (endoff > destoff+olen) | ||
2011 | endoff = destoff+olen; | ||
2012 | if (endoff > inode->i_size) | ||
2013 | btrfs_i_size_write(inode, endoff); | ||
2014 | |||
2015 | BTRFS_I(inode)->flags = BTRFS_I(src)->flags; | ||
2016 | ret = btrfs_update_inode(trans, root, inode); | ||
2017 | BUG_ON(ret); | ||
2018 | btrfs_end_transaction(trans, root); | ||
2019 | } | ||
1191 | next: | 2020 | next: |
1192 | btrfs_release_path(root, path); | 2021 | btrfs_release_path(root, path); |
1193 | key.offset++; | 2022 | key.offset++; |
@@ -1195,17 +2024,7 @@ next: | |||
1195 | ret = 0; | 2024 | ret = 0; |
1196 | out: | 2025 | out: |
1197 | btrfs_release_path(root, path); | 2026 | btrfs_release_path(root, path); |
1198 | if (ret == 0) { | ||
1199 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
1200 | if (destoff + olen > inode->i_size) | ||
1201 | btrfs_i_size_write(inode, destoff + olen); | ||
1202 | BTRFS_I(inode)->flags = BTRFS_I(src)->flags; | ||
1203 | ret = btrfs_update_inode(trans, root, inode); | ||
1204 | } | ||
1205 | btrfs_end_transaction(trans, root); | ||
1206 | unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); | 2027 | unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); |
1207 | if (ret) | ||
1208 | vmtruncate(inode, 0); | ||
1209 | out_unlock: | 2028 | out_unlock: |
1210 | mutex_unlock(&src->i_mutex); | 2029 | mutex_unlock(&src->i_mutex); |
1211 | mutex_unlock(&inode->i_mutex); | 2030 | mutex_unlock(&inode->i_mutex); |
@@ -1249,6 +2068,10 @@ static long btrfs_ioctl_trans_start(struct file *file) | |||
1249 | if (file->private_data) | 2068 | if (file->private_data) |
1250 | goto out; | 2069 | goto out; |
1251 | 2070 | ||
2071 | ret = -EROFS; | ||
2072 | if (btrfs_root_readonly(root)) | ||
2073 | goto out; | ||
2074 | |||
1252 | ret = mnt_want_write(file->f_path.mnt); | 2075 | ret = mnt_want_write(file->f_path.mnt); |
1253 | if (ret) | 2076 | if (ret) |
1254 | goto out; | 2077 | goto out; |
@@ -1274,6 +2097,209 @@ out: | |||
1274 | return ret; | 2097 | return ret; |
1275 | } | 2098 | } |
1276 | 2099 | ||
2100 | static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | ||
2101 | { | ||
2102 | struct inode *inode = fdentry(file)->d_inode; | ||
2103 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
2104 | struct btrfs_root *new_root; | ||
2105 | struct btrfs_dir_item *di; | ||
2106 | struct btrfs_trans_handle *trans; | ||
2107 | struct btrfs_path *path; | ||
2108 | struct btrfs_key location; | ||
2109 | struct btrfs_disk_key disk_key; | ||
2110 | struct btrfs_super_block *disk_super; | ||
2111 | u64 features; | ||
2112 | u64 objectid = 0; | ||
2113 | u64 dir_id; | ||
2114 | |||
2115 | if (!capable(CAP_SYS_ADMIN)) | ||
2116 | return -EPERM; | ||
2117 | |||
2118 | if (copy_from_user(&objectid, argp, sizeof(objectid))) | ||
2119 | return -EFAULT; | ||
2120 | |||
2121 | if (!objectid) | ||
2122 | objectid = root->root_key.objectid; | ||
2123 | |||
2124 | location.objectid = objectid; | ||
2125 | location.type = BTRFS_ROOT_ITEM_KEY; | ||
2126 | location.offset = (u64)-1; | ||
2127 | |||
2128 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | ||
2129 | if (IS_ERR(new_root)) | ||
2130 | return PTR_ERR(new_root); | ||
2131 | |||
2132 | if (btrfs_root_refs(&new_root->root_item) == 0) | ||
2133 | return -ENOENT; | ||
2134 | |||
2135 | path = btrfs_alloc_path(); | ||
2136 | if (!path) | ||
2137 | return -ENOMEM; | ||
2138 | path->leave_spinning = 1; | ||
2139 | |||
2140 | trans = btrfs_start_transaction(root, 1); | ||
2141 | if (!trans) { | ||
2142 | btrfs_free_path(path); | ||
2143 | return -ENOMEM; | ||
2144 | } | ||
2145 | |||
2146 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | ||
2147 | di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, | ||
2148 | dir_id, "default", 7, 1); | ||
2149 | if (IS_ERR_OR_NULL(di)) { | ||
2150 | btrfs_free_path(path); | ||
2151 | btrfs_end_transaction(trans, root); | ||
2152 | printk(KERN_ERR "Umm, you don't have the default dir item, " | ||
2153 | "this isn't going to work\n"); | ||
2154 | return -ENOENT; | ||
2155 | } | ||
2156 | |||
2157 | btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key); | ||
2158 | btrfs_set_dir_item_key(path->nodes[0], di, &disk_key); | ||
2159 | btrfs_mark_buffer_dirty(path->nodes[0]); | ||
2160 | btrfs_free_path(path); | ||
2161 | |||
2162 | disk_super = &root->fs_info->super_copy; | ||
2163 | features = btrfs_super_incompat_flags(disk_super); | ||
2164 | if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) { | ||
2165 | features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL; | ||
2166 | btrfs_set_super_incompat_flags(disk_super, features); | ||
2167 | } | ||
2168 | btrfs_end_transaction(trans, root); | ||
2169 | |||
2170 | return 0; | ||
2171 | } | ||
2172 | |||
2173 | static void get_block_group_info(struct list_head *groups_list, | ||
2174 | struct btrfs_ioctl_space_info *space) | ||
2175 | { | ||
2176 | struct btrfs_block_group_cache *block_group; | ||
2177 | |||
2178 | space->total_bytes = 0; | ||
2179 | space->used_bytes = 0; | ||
2180 | space->flags = 0; | ||
2181 | list_for_each_entry(block_group, groups_list, list) { | ||
2182 | space->flags = block_group->flags; | ||
2183 | space->total_bytes += block_group->key.offset; | ||
2184 | space->used_bytes += | ||
2185 | btrfs_block_group_used(&block_group->item); | ||
2186 | } | ||
2187 | } | ||
2188 | |||
2189 | long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | ||
2190 | { | ||
2191 | struct btrfs_ioctl_space_args space_args; | ||
2192 | struct btrfs_ioctl_space_info space; | ||
2193 | struct btrfs_ioctl_space_info *dest; | ||
2194 | struct btrfs_ioctl_space_info *dest_orig; | ||
2195 | struct btrfs_ioctl_space_info *user_dest; | ||
2196 | struct btrfs_space_info *info; | ||
2197 | u64 types[] = {BTRFS_BLOCK_GROUP_DATA, | ||
2198 | BTRFS_BLOCK_GROUP_SYSTEM, | ||
2199 | BTRFS_BLOCK_GROUP_METADATA, | ||
2200 | BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA}; | ||
2201 | int num_types = 4; | ||
2202 | int alloc_size; | ||
2203 | int ret = 0; | ||
2204 | int slot_count = 0; | ||
2205 | int i, c; | ||
2206 | |||
2207 | if (copy_from_user(&space_args, | ||
2208 | (struct btrfs_ioctl_space_args __user *)arg, | ||
2209 | sizeof(space_args))) | ||
2210 | return -EFAULT; | ||
2211 | |||
2212 | for (i = 0; i < num_types; i++) { | ||
2213 | struct btrfs_space_info *tmp; | ||
2214 | |||
2215 | info = NULL; | ||
2216 | rcu_read_lock(); | ||
2217 | list_for_each_entry_rcu(tmp, &root->fs_info->space_info, | ||
2218 | list) { | ||
2219 | if (tmp->flags == types[i]) { | ||
2220 | info = tmp; | ||
2221 | break; | ||
2222 | } | ||
2223 | } | ||
2224 | rcu_read_unlock(); | ||
2225 | |||
2226 | if (!info) | ||
2227 | continue; | ||
2228 | |||
2229 | down_read(&info->groups_sem); | ||
2230 | for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) { | ||
2231 | if (!list_empty(&info->block_groups[c])) | ||
2232 | slot_count++; | ||
2233 | } | ||
2234 | up_read(&info->groups_sem); | ||
2235 | } | ||
2236 | |||
2237 | /* space_slots == 0 means they are asking for a count */ | ||
2238 | if (space_args.space_slots == 0) { | ||
2239 | space_args.total_spaces = slot_count; | ||
2240 | goto out; | ||
2241 | } | ||
2242 | |||
2243 | slot_count = min_t(int, space_args.space_slots, slot_count); | ||
2244 | |||
2245 | alloc_size = sizeof(*dest) * slot_count; | ||
2246 | |||
2247 | /* we generally have at most 6 or so space infos, one for each raid | ||
2248 | * level. So, a whole page should be more than enough for everyone | ||
2249 | */ | ||
2250 | if (alloc_size > PAGE_CACHE_SIZE) | ||
2251 | return -ENOMEM; | ||
2252 | |||
2253 | space_args.total_spaces = 0; | ||
2254 | dest = kmalloc(alloc_size, GFP_NOFS); | ||
2255 | if (!dest) | ||
2256 | return -ENOMEM; | ||
2257 | dest_orig = dest; | ||
2258 | |||
2259 | /* now we have a buffer to copy into */ | ||
2260 | for (i = 0; i < num_types; i++) { | ||
2261 | struct btrfs_space_info *tmp; | ||
2262 | |||
2263 | info = NULL; | ||
2264 | rcu_read_lock(); | ||
2265 | list_for_each_entry_rcu(tmp, &root->fs_info->space_info, | ||
2266 | list) { | ||
2267 | if (tmp->flags == types[i]) { | ||
2268 | info = tmp; | ||
2269 | break; | ||
2270 | } | ||
2271 | } | ||
2272 | rcu_read_unlock(); | ||
2273 | |||
2274 | if (!info) | ||
2275 | continue; | ||
2276 | down_read(&info->groups_sem); | ||
2277 | for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) { | ||
2278 | if (!list_empty(&info->block_groups[c])) { | ||
2279 | get_block_group_info(&info->block_groups[c], | ||
2280 | &space); | ||
2281 | memcpy(dest, &space, sizeof(space)); | ||
2282 | dest++; | ||
2283 | space_args.total_spaces++; | ||
2284 | } | ||
2285 | } | ||
2286 | up_read(&info->groups_sem); | ||
2287 | } | ||
2288 | |||
2289 | user_dest = (struct btrfs_ioctl_space_info *) | ||
2290 | (arg + sizeof(struct btrfs_ioctl_space_args)); | ||
2291 | |||
2292 | if (copy_to_user(user_dest, dest_orig, alloc_size)) | ||
2293 | ret = -EFAULT; | ||
2294 | |||
2295 | kfree(dest_orig); | ||
2296 | out: | ||
2297 | if (ret == 0 && copy_to_user(arg, &space_args, sizeof(space_args))) | ||
2298 | ret = -EFAULT; | ||
2299 | |||
2300 | return ret; | ||
2301 | } | ||
2302 | |||
1277 | /* | 2303 | /* |
1278 | * there are many ways the trans_start and trans_end ioctls can lead | 2304 | * there are many ways the trans_start and trans_end ioctls can lead |
1279 | * to deadlocks. They should only be used by applications that | 2305 | * to deadlocks. They should only be used by applications that |
@@ -1301,6 +2327,36 @@ long btrfs_ioctl_trans_end(struct file *file) | |||
1301 | return 0; | 2327 | return 0; |
1302 | } | 2328 | } |
1303 | 2329 | ||
2330 | static noinline long btrfs_ioctl_start_sync(struct file *file, void __user *argp) | ||
2331 | { | ||
2332 | struct btrfs_root *root = BTRFS_I(file->f_dentry->d_inode)->root; | ||
2333 | struct btrfs_trans_handle *trans; | ||
2334 | u64 transid; | ||
2335 | |||
2336 | trans = btrfs_start_transaction(root, 0); | ||
2337 | transid = trans->transid; | ||
2338 | btrfs_commit_transaction_async(trans, root, 0); | ||
2339 | |||
2340 | if (argp) | ||
2341 | if (copy_to_user(argp, &transid, sizeof(transid))) | ||
2342 | return -EFAULT; | ||
2343 | return 0; | ||
2344 | } | ||
2345 | |||
2346 | static noinline long btrfs_ioctl_wait_sync(struct file *file, void __user *argp) | ||
2347 | { | ||
2348 | struct btrfs_root *root = BTRFS_I(file->f_dentry->d_inode)->root; | ||
2349 | u64 transid; | ||
2350 | |||
2351 | if (argp) { | ||
2352 | if (copy_from_user(&transid, argp, sizeof(transid))) | ||
2353 | return -EFAULT; | ||
2354 | } else { | ||
2355 | transid = 0; /* current trans */ | ||
2356 | } | ||
2357 | return btrfs_wait_for_commit(root, transid); | ||
2358 | } | ||
2359 | |||
1304 | long btrfs_ioctl(struct file *file, unsigned int | 2360 | long btrfs_ioctl(struct file *file, unsigned int |
1305 | cmd, unsigned long arg) | 2361 | cmd, unsigned long arg) |
1306 | { | 2362 | { |
@@ -1316,12 +2372,22 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
1316 | return btrfs_ioctl_getversion(file, argp); | 2372 | return btrfs_ioctl_getversion(file, argp); |
1317 | case BTRFS_IOC_SNAP_CREATE: | 2373 | case BTRFS_IOC_SNAP_CREATE: |
1318 | return btrfs_ioctl_snap_create(file, argp, 0); | 2374 | return btrfs_ioctl_snap_create(file, argp, 0); |
2375 | case BTRFS_IOC_SNAP_CREATE_V2: | ||
2376 | return btrfs_ioctl_snap_create_v2(file, argp, 0); | ||
1319 | case BTRFS_IOC_SUBVOL_CREATE: | 2377 | case BTRFS_IOC_SUBVOL_CREATE: |
1320 | return btrfs_ioctl_snap_create(file, argp, 1); | 2378 | return btrfs_ioctl_snap_create(file, argp, 1); |
1321 | case BTRFS_IOC_SNAP_DESTROY: | 2379 | case BTRFS_IOC_SNAP_DESTROY: |
1322 | return btrfs_ioctl_snap_destroy(file, argp); | 2380 | return btrfs_ioctl_snap_destroy(file, argp); |
2381 | case BTRFS_IOC_SUBVOL_GETFLAGS: | ||
2382 | return btrfs_ioctl_subvol_getflags(file, argp); | ||
2383 | case BTRFS_IOC_SUBVOL_SETFLAGS: | ||
2384 | return btrfs_ioctl_subvol_setflags(file, argp); | ||
2385 | case BTRFS_IOC_DEFAULT_SUBVOL: | ||
2386 | return btrfs_ioctl_default_subvol(file, argp); | ||
1323 | case BTRFS_IOC_DEFRAG: | 2387 | case BTRFS_IOC_DEFRAG: |
1324 | return btrfs_ioctl_defrag(file); | 2388 | return btrfs_ioctl_defrag(file, NULL); |
2389 | case BTRFS_IOC_DEFRAG_RANGE: | ||
2390 | return btrfs_ioctl_defrag(file, argp); | ||
1325 | case BTRFS_IOC_RESIZE: | 2391 | case BTRFS_IOC_RESIZE: |
1326 | return btrfs_ioctl_resize(root, argp); | 2392 | return btrfs_ioctl_resize(root, argp); |
1327 | case BTRFS_IOC_ADD_DEV: | 2393 | case BTRFS_IOC_ADD_DEV: |
@@ -1338,9 +2404,19 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
1338 | return btrfs_ioctl_trans_start(file); | 2404 | return btrfs_ioctl_trans_start(file); |
1339 | case BTRFS_IOC_TRANS_END: | 2405 | case BTRFS_IOC_TRANS_END: |
1340 | return btrfs_ioctl_trans_end(file); | 2406 | return btrfs_ioctl_trans_end(file); |
2407 | case BTRFS_IOC_TREE_SEARCH: | ||
2408 | return btrfs_ioctl_tree_search(file, argp); | ||
2409 | case BTRFS_IOC_INO_LOOKUP: | ||
2410 | return btrfs_ioctl_ino_lookup(file, argp); | ||
2411 | case BTRFS_IOC_SPACE_INFO: | ||
2412 | return btrfs_ioctl_space_info(root, argp); | ||
1341 | case BTRFS_IOC_SYNC: | 2413 | case BTRFS_IOC_SYNC: |
1342 | btrfs_sync_fs(file->f_dentry->d_sb, 1); | 2414 | btrfs_sync_fs(file->f_dentry->d_sb, 1); |
1343 | return 0; | 2415 | return 0; |
2416 | case BTRFS_IOC_START_SYNC: | ||
2417 | return btrfs_ioctl_start_sync(file, argp); | ||
2418 | case BTRFS_IOC_WAIT_SYNC: | ||
2419 | return btrfs_ioctl_wait_sync(file, argp); | ||
1344 | } | 2420 | } |
1345 | 2421 | ||
1346 | return -ENOTTY; | 2422 | return -ENOTTY; |