diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/compression.c | 15 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 38 | ||||
| -rw-r--r-- | fs/btrfs/export.c | 76 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.c | 77 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 7 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 294 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 31 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.c | 67 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 41 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 21 | ||||
| -rw-r--r-- | fs/gfs2/quota.c | 15 | ||||
| -rw-r--r-- | fs/ioprio.c | 31 | ||||
| -rw-r--r-- | fs/nfs/dir.c | 62 | ||||
| -rw-r--r-- | fs/nfs/direct.c | 2 | ||||
| -rw-r--r-- | fs/nfs/internal.h | 9 | ||||
| -rw-r--r-- | fs/nfs/nfs2xdr.c | 4 | ||||
| -rw-r--r-- | fs/nfs/nfs3xdr.c | 4 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 6 | ||||
| -rw-r--r-- | fs/nilfs2/dat.c | 2 | ||||
| -rw-r--r-- | fs/nilfs2/ioctl.c | 4 | ||||
| -rw-r--r-- | fs/pipe.c | 14 | ||||
| -rw-r--r-- | fs/splice.c | 24 |
27 files changed, 663 insertions, 200 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 7845d1f7d1d9..b50bc4bd5c56 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -91,23 +91,10 @@ static inline int compressed_bio_size(struct btrfs_root *root, | |||
| 91 | static struct bio *compressed_bio_alloc(struct block_device *bdev, | 91 | static struct bio *compressed_bio_alloc(struct block_device *bdev, |
| 92 | u64 first_byte, gfp_t gfp_flags) | 92 | u64 first_byte, gfp_t gfp_flags) |
| 93 | { | 93 | { |
| 94 | struct bio *bio; | ||
| 95 | int nr_vecs; | 94 | int nr_vecs; |
| 96 | 95 | ||
| 97 | nr_vecs = bio_get_nr_vecs(bdev); | 96 | nr_vecs = bio_get_nr_vecs(bdev); |
| 98 | bio = bio_alloc(gfp_flags, nr_vecs); | 97 | return btrfs_bio_alloc(bdev, first_byte >> 9, nr_vecs, gfp_flags); |
| 99 | |||
| 100 | if (bio == NULL && (current->flags & PF_MEMALLOC)) { | ||
| 101 | while (!bio && (nr_vecs /= 2)) | ||
| 102 | bio = bio_alloc(gfp_flags, nr_vecs); | ||
| 103 | } | ||
| 104 | |||
| 105 | if (bio) { | ||
| 106 | bio->bi_size = 0; | ||
| 107 | bio->bi_bdev = bdev; | ||
| 108 | bio->bi_sector = first_byte >> 9; | ||
| 109 | } | ||
| 110 | return bio; | ||
| 111 | } | 98 | } |
| 112 | 99 | ||
| 113 | static int check_compressed_csum(struct inode *inode, | 100 | static int check_compressed_csum(struct inode *inode, |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8db9234f6b41..af52f6d7a4d8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -808,9 +808,9 @@ struct btrfs_block_group_cache { | |||
| 808 | int extents_thresh; | 808 | int extents_thresh; |
| 809 | int free_extents; | 809 | int free_extents; |
| 810 | int total_bitmaps; | 810 | int total_bitmaps; |
| 811 | int ro:1; | 811 | unsigned int ro:1; |
| 812 | int dirty:1; | 812 | unsigned int dirty:1; |
| 813 | int iref:1; | 813 | unsigned int iref:1; |
| 814 | 814 | ||
| 815 | int disk_cache_state; | 815 | int disk_cache_state; |
| 816 | 816 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index fb827d0d7181..c547cca26a26 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/freezer.h> | 28 | #include <linux/freezer.h> |
| 29 | #include <linux/crc32c.h> | 29 | #include <linux/crc32c.h> |
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/migrate.h> | ||
| 31 | #include "compat.h" | 32 | #include "compat.h" |
| 32 | #include "ctree.h" | 33 | #include "ctree.h" |
| 33 | #include "disk-io.h" | 34 | #include "disk-io.h" |
| @@ -355,6 +356,8 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
| 355 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, | 356 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, |
| 356 | btrfs_header_generation(eb)); | 357 | btrfs_header_generation(eb)); |
| 357 | BUG_ON(ret); | 358 | BUG_ON(ret); |
| 359 | WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN)); | ||
| 360 | |||
| 358 | found_start = btrfs_header_bytenr(eb); | 361 | found_start = btrfs_header_bytenr(eb); |
| 359 | if (found_start != start) { | 362 | if (found_start != start) { |
| 360 | WARN_ON(1); | 363 | WARN_ON(1); |
| @@ -693,6 +696,29 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
| 693 | __btree_submit_bio_done); | 696 | __btree_submit_bio_done); |
| 694 | } | 697 | } |
| 695 | 698 | ||
| 699 | static int btree_migratepage(struct address_space *mapping, | ||
| 700 | struct page *newpage, struct page *page) | ||
| 701 | { | ||
| 702 | /* | ||
| 703 | * we can't safely write a btree page from here, | ||
| 704 | * we haven't done the locking hook | ||
| 705 | */ | ||
| 706 | if (PageDirty(page)) | ||
| 707 | return -EAGAIN; | ||
| 708 | /* | ||
| 709 | * Buffers may be managed in a filesystem specific way. | ||
| 710 | * We must have no buffers or drop them. | ||
| 711 | */ | ||
| 712 | if (page_has_private(page) && | ||
| 713 | !try_to_release_page(page, GFP_KERNEL)) | ||
| 714 | return -EAGAIN; | ||
| 715 | #ifdef CONFIG_MIGRATION | ||
| 716 | return migrate_page(mapping, newpage, page); | ||
| 717 | #else | ||
| 718 | return -ENOSYS; | ||
| 719 | #endif | ||
| 720 | } | ||
| 721 | |||
| 696 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 722 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
| 697 | { | 723 | { |
| 698 | struct extent_io_tree *tree; | 724 | struct extent_io_tree *tree; |
| @@ -707,8 +733,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc) | |||
| 707 | } | 733 | } |
| 708 | 734 | ||
| 709 | redirty_page_for_writepage(wbc, page); | 735 | redirty_page_for_writepage(wbc, page); |
| 710 | eb = btrfs_find_tree_block(root, page_offset(page), | 736 | eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE); |
| 711 | PAGE_CACHE_SIZE); | ||
| 712 | WARN_ON(!eb); | 737 | WARN_ON(!eb); |
| 713 | 738 | ||
| 714 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); | 739 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); |
| @@ -799,6 +824,9 @@ static const struct address_space_operations btree_aops = { | |||
| 799 | .releasepage = btree_releasepage, | 824 | .releasepage = btree_releasepage, |
| 800 | .invalidatepage = btree_invalidatepage, | 825 | .invalidatepage = btree_invalidatepage, |
| 801 | .sync_page = block_sync_page, | 826 | .sync_page = block_sync_page, |
| 827 | #ifdef CONFIG_MIGRATION | ||
| 828 | .migratepage = btree_migratepage, | ||
| 829 | #endif | ||
| 802 | }; | 830 | }; |
| 803 | 831 | ||
| 804 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, | 832 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, |
| @@ -1538,10 +1566,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1538 | GFP_NOFS); | 1566 | GFP_NOFS); |
| 1539 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), | 1567 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), |
| 1540 | GFP_NOFS); | 1568 | GFP_NOFS); |
| 1541 | struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root), | 1569 | struct btrfs_root *tree_root = btrfs_sb(sb); |
| 1542 | GFP_NOFS); | 1570 | struct btrfs_fs_info *fs_info = tree_root->fs_info; |
| 1543 | struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info), | ||
| 1544 | GFP_NOFS); | ||
| 1545 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), | 1571 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), |
| 1546 | GFP_NOFS); | 1572 | GFP_NOFS); |
| 1547 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), | 1573 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 951ef09b82f4..6f0444473594 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -232,9 +232,85 @@ fail: | |||
| 232 | return ERR_PTR(ret); | 232 | return ERR_PTR(ret); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static int btrfs_get_name(struct dentry *parent, char *name, | ||
| 236 | struct dentry *child) | ||
| 237 | { | ||
| 238 | struct inode *inode = child->d_inode; | ||
| 239 | struct inode *dir = parent->d_inode; | ||
| 240 | struct btrfs_path *path; | ||
| 241 | struct btrfs_root *root = BTRFS_I(dir)->root; | ||
| 242 | struct btrfs_inode_ref *iref; | ||
| 243 | struct btrfs_root_ref *rref; | ||
| 244 | struct extent_buffer *leaf; | ||
| 245 | unsigned long name_ptr; | ||
| 246 | struct btrfs_key key; | ||
| 247 | int name_len; | ||
| 248 | int ret; | ||
| 249 | |||
| 250 | if (!dir || !inode) | ||
| 251 | return -EINVAL; | ||
| 252 | |||
| 253 | if (!S_ISDIR(dir->i_mode)) | ||
| 254 | return -EINVAL; | ||
| 255 | |||
| 256 | path = btrfs_alloc_path(); | ||
| 257 | if (!path) | ||
| 258 | return -ENOMEM; | ||
| 259 | path->leave_spinning = 1; | ||
| 260 | |||
| 261 | if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | ||
| 262 | key.objectid = BTRFS_I(inode)->root->root_key.objectid; | ||
| 263 | key.type = BTRFS_ROOT_BACKREF_KEY; | ||
| 264 | key.offset = (u64)-1; | ||
| 265 | root = root->fs_info->tree_root; | ||
| 266 | } else { | ||
| 267 | key.objectid = inode->i_ino; | ||
| 268 | key.offset = dir->i_ino; | ||
| 269 | key.type = BTRFS_INODE_REF_KEY; | ||
| 270 | } | ||
| 271 | |||
| 272 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
| 273 | if (ret < 0) { | ||
| 274 | btrfs_free_path(path); | ||
| 275 | return ret; | ||
| 276 | } else if (ret > 0) { | ||
| 277 | if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | ||
| 278 | path->slots[0]--; | ||
| 279 | } else { | ||
| 280 | btrfs_free_path(path); | ||
| 281 | return -ENOENT; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | leaf = path->nodes[0]; | ||
| 285 | |||
| 286 | if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | ||
| 287 | rref = btrfs_item_ptr(leaf, path->slots[0], | ||
| 288 | struct btrfs_root_ref); | ||
| 289 | name_ptr = (unsigned long)(rref + 1); | ||
| 290 | name_len = btrfs_root_ref_name_len(leaf, rref); | ||
| 291 | } else { | ||
| 292 | iref = btrfs_item_ptr(leaf, path->slots[0], | ||
| 293 | struct btrfs_inode_ref); | ||
| 294 | name_ptr = (unsigned long)(iref + 1); | ||
| 295 | name_len = btrfs_inode_ref_name_len(leaf, iref); | ||
| 296 | } | ||
| 297 | |||
| 298 | read_extent_buffer(leaf, name, name_ptr, name_len); | ||
| 299 | btrfs_free_path(path); | ||
| 300 | |||
| 301 | /* | ||
| 302 | * have to add the null termination to make sure that reconnect_path | ||
| 303 | * gets the right len for strlen | ||
| 304 | */ | ||
| 305 | name[name_len] = '\0'; | ||
| 306 | |||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 235 | const struct export_operations btrfs_export_ops = { | 310 | const struct export_operations btrfs_export_ops = { |
| 236 | .encode_fh = btrfs_encode_fh, | 311 | .encode_fh = btrfs_encode_fh, |
| 237 | .fh_to_dentry = btrfs_fh_to_dentry, | 312 | .fh_to_dentry = btrfs_fh_to_dentry, |
| 238 | .fh_to_parent = btrfs_fh_to_parent, | 313 | .fh_to_parent = btrfs_fh_to_parent, |
| 239 | .get_parent = btrfs_get_parent, | 314 | .get_parent = btrfs_get_parent, |
| 315 | .get_name = btrfs_get_name, | ||
| 240 | }; | 316 | }; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 0c097f3aec41..bcd59c7dfb57 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -3412,7 +3412,7 @@ again: | |||
| 3412 | * our reservation. | 3412 | * our reservation. |
| 3413 | */ | 3413 | */ |
| 3414 | if (unused <= space_info->total_bytes) { | 3414 | if (unused <= space_info->total_bytes) { |
| 3415 | unused -= space_info->total_bytes; | 3415 | unused = space_info->total_bytes - unused; |
| 3416 | if (unused >= num_bytes) { | 3416 | if (unused >= num_bytes) { |
| 3417 | if (!reserved) | 3417 | if (!reserved) |
| 3418 | space_info->bytes_reserved += orig_bytes; | 3418 | space_info->bytes_reserved += orig_bytes; |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index eac10e3260a9..3e86b9f36507 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -1828,9 +1828,9 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err) | |||
| 1828 | bio_put(bio); | 1828 | bio_put(bio); |
| 1829 | } | 1829 | } |
| 1830 | 1830 | ||
| 1831 | static struct bio * | 1831 | struct bio * |
| 1832 | extent_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | 1832 | btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, |
| 1833 | gfp_t gfp_flags) | 1833 | gfp_t gfp_flags) |
| 1834 | { | 1834 | { |
| 1835 | struct bio *bio; | 1835 | struct bio *bio; |
| 1836 | 1836 | ||
| @@ -1919,7 +1919,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, | |||
| 1919 | else | 1919 | else |
| 1920 | nr = bio_get_nr_vecs(bdev); | 1920 | nr = bio_get_nr_vecs(bdev); |
| 1921 | 1921 | ||
| 1922 | bio = extent_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH); | 1922 | bio = btrfs_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH); |
| 1923 | 1923 | ||
| 1924 | bio_add_page(bio, page, page_size, offset); | 1924 | bio_add_page(bio, page, page_size, offset); |
| 1925 | bio->bi_end_io = end_io_func; | 1925 | bio->bi_end_io = end_io_func; |
| @@ -2901,21 +2901,53 @@ out: | |||
| 2901 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 2901 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 2902 | __u64 start, __u64 len, get_extent_t *get_extent) | 2902 | __u64 start, __u64 len, get_extent_t *get_extent) |
| 2903 | { | 2903 | { |
| 2904 | int ret; | 2904 | int ret = 0; |
| 2905 | u64 off = start; | 2905 | u64 off = start; |
| 2906 | u64 max = start + len; | 2906 | u64 max = start + len; |
| 2907 | u32 flags = 0; | 2907 | u32 flags = 0; |
| 2908 | u32 found_type; | ||
| 2909 | u64 last; | ||
| 2908 | u64 disko = 0; | 2910 | u64 disko = 0; |
| 2911 | struct btrfs_key found_key; | ||
| 2909 | struct extent_map *em = NULL; | 2912 | struct extent_map *em = NULL; |
| 2910 | struct extent_state *cached_state = NULL; | 2913 | struct extent_state *cached_state = NULL; |
| 2914 | struct btrfs_path *path; | ||
| 2915 | struct btrfs_file_extent_item *item; | ||
| 2911 | int end = 0; | 2916 | int end = 0; |
| 2912 | u64 em_start = 0, em_len = 0; | 2917 | u64 em_start = 0, em_len = 0; |
| 2913 | unsigned long emflags; | 2918 | unsigned long emflags; |
| 2914 | ret = 0; | 2919 | int hole = 0; |
| 2915 | 2920 | ||
| 2916 | if (len == 0) | 2921 | if (len == 0) |
| 2917 | return -EINVAL; | 2922 | return -EINVAL; |
| 2918 | 2923 | ||
| 2924 | path = btrfs_alloc_path(); | ||
| 2925 | if (!path) | ||
| 2926 | return -ENOMEM; | ||
| 2927 | path->leave_spinning = 1; | ||
| 2928 | |||
| 2929 | ret = btrfs_lookup_file_extent(NULL, BTRFS_I(inode)->root, | ||
| 2930 | path, inode->i_ino, -1, 0); | ||
| 2931 | if (ret < 0) { | ||
| 2932 | btrfs_free_path(path); | ||
| 2933 | return ret; | ||
| 2934 | } | ||
| 2935 | WARN_ON(!ret); | ||
| 2936 | path->slots[0]--; | ||
| 2937 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | ||
| 2938 | struct btrfs_file_extent_item); | ||
| 2939 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]); | ||
| 2940 | found_type = btrfs_key_type(&found_key); | ||
| 2941 | |||
| 2942 | /* No extents, just return */ | ||
| 2943 | if (found_key.objectid != inode->i_ino || | ||
| 2944 | found_type != BTRFS_EXTENT_DATA_KEY) { | ||
| 2945 | btrfs_free_path(path); | ||
| 2946 | return 0; | ||
| 2947 | } | ||
| 2948 | last = found_key.offset; | ||
| 2949 | btrfs_free_path(path); | ||
| 2950 | |||
| 2919 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, | 2951 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, |
| 2920 | &cached_state, GFP_NOFS); | 2952 | &cached_state, GFP_NOFS); |
| 2921 | em = get_extent(inode, NULL, 0, off, max - off, 0); | 2953 | em = get_extent(inode, NULL, 0, off, max - off, 0); |
| @@ -2925,11 +2957,18 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2925 | ret = PTR_ERR(em); | 2957 | ret = PTR_ERR(em); |
| 2926 | goto out; | 2958 | goto out; |
| 2927 | } | 2959 | } |
| 2960 | |||
| 2928 | while (!end) { | 2961 | while (!end) { |
| 2962 | hole = 0; | ||
| 2929 | off = em->start + em->len; | 2963 | off = em->start + em->len; |
| 2930 | if (off >= max) | 2964 | if (off >= max) |
| 2931 | end = 1; | 2965 | end = 1; |
| 2932 | 2966 | ||
| 2967 | if (em->block_start == EXTENT_MAP_HOLE) { | ||
| 2968 | hole = 1; | ||
| 2969 | goto next; | ||
| 2970 | } | ||
| 2971 | |||
| 2933 | em_start = em->start; | 2972 | em_start = em->start; |
| 2934 | em_len = em->len; | 2973 | em_len = em->len; |
| 2935 | 2974 | ||
| @@ -2939,8 +2978,6 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2939 | if (em->block_start == EXTENT_MAP_LAST_BYTE) { | 2978 | if (em->block_start == EXTENT_MAP_LAST_BYTE) { |
| 2940 | end = 1; | 2979 | end = 1; |
| 2941 | flags |= FIEMAP_EXTENT_LAST; | 2980 | flags |= FIEMAP_EXTENT_LAST; |
| 2942 | } else if (em->block_start == EXTENT_MAP_HOLE) { | ||
| 2943 | flags |= FIEMAP_EXTENT_UNWRITTEN; | ||
| 2944 | } else if (em->block_start == EXTENT_MAP_INLINE) { | 2981 | } else if (em->block_start == EXTENT_MAP_INLINE) { |
| 2945 | flags |= (FIEMAP_EXTENT_DATA_INLINE | | 2982 | flags |= (FIEMAP_EXTENT_DATA_INLINE | |
| 2946 | FIEMAP_EXTENT_NOT_ALIGNED); | 2983 | FIEMAP_EXTENT_NOT_ALIGNED); |
| @@ -2953,10 +2990,10 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2953 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) | 2990 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) |
| 2954 | flags |= FIEMAP_EXTENT_ENCODED; | 2991 | flags |= FIEMAP_EXTENT_ENCODED; |
| 2955 | 2992 | ||
| 2993 | next: | ||
| 2956 | emflags = em->flags; | 2994 | emflags = em->flags; |
| 2957 | free_extent_map(em); | 2995 | free_extent_map(em); |
| 2958 | em = NULL; | 2996 | em = NULL; |
| 2959 | |||
| 2960 | if (!end) { | 2997 | if (!end) { |
| 2961 | em = get_extent(inode, NULL, 0, off, max - off, 0); | 2998 | em = get_extent(inode, NULL, 0, off, max - off, 0); |
| 2962 | if (!em) | 2999 | if (!em) |
| @@ -2967,15 +3004,23 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2967 | } | 3004 | } |
| 2968 | emflags = em->flags; | 3005 | emflags = em->flags; |
| 2969 | } | 3006 | } |
| 3007 | |||
| 2970 | if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { | 3008 | if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { |
| 2971 | flags |= FIEMAP_EXTENT_LAST; | 3009 | flags |= FIEMAP_EXTENT_LAST; |
| 2972 | end = 1; | 3010 | end = 1; |
| 2973 | } | 3011 | } |
| 2974 | 3012 | ||
| 2975 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | 3013 | if (em_start == last) { |
| 2976 | em_len, flags); | 3014 | flags |= FIEMAP_EXTENT_LAST; |
| 2977 | if (ret) | 3015 | end = 1; |
| 2978 | goto out_free; | 3016 | } |
| 3017 | |||
| 3018 | if (!hole) { | ||
| 3019 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | ||
| 3020 | em_len, flags); | ||
| 3021 | if (ret) | ||
| 3022 | goto out_free; | ||
| 3023 | } | ||
| 2979 | } | 3024 | } |
| 2980 | out_free: | 3025 | out_free: |
| 2981 | free_extent_map(em); | 3026 | free_extent_map(em); |
| @@ -3836,8 +3881,10 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page) | |||
| 3836 | 3881 | ||
| 3837 | spin_lock(&tree->buffer_lock); | 3882 | spin_lock(&tree->buffer_lock); |
| 3838 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | 3883 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); |
| 3839 | if (!eb) | 3884 | if (!eb) { |
| 3840 | goto out; | 3885 | spin_unlock(&tree->buffer_lock); |
| 3886 | return ret; | ||
| 3887 | } | ||
| 3841 | 3888 | ||
| 3842 | if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { | 3889 | if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { |
| 3843 | ret = 0; | 3890 | ret = 0; |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 1c6d4f342ef7..4183c8178f01 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
| @@ -310,4 +310,7 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
| 310 | struct extent_io_tree *tree, | 310 | struct extent_io_tree *tree, |
| 311 | u64 start, u64 end, struct page *locked_page, | 311 | u64 start, u64 end, struct page *locked_page, |
| 312 | unsigned long op); | 312 | unsigned long op); |
| 313 | struct bio * | ||
| 314 | btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | ||
| 315 | gfp_t gfp_flags); | ||
| 313 | #endif | 316 | #endif |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e354c33df082..c1faded5fca0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1047,8 +1047,14 @@ out: | |||
| 1047 | 1047 | ||
| 1048 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { | 1048 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { |
| 1049 | trans = btrfs_start_transaction(root, 0); | 1049 | trans = btrfs_start_transaction(root, 0); |
| 1050 | if (IS_ERR(trans)) { | ||
| 1051 | num_written = PTR_ERR(trans); | ||
| 1052 | goto done; | ||
| 1053 | } | ||
| 1054 | mutex_lock(&inode->i_mutex); | ||
| 1050 | ret = btrfs_log_dentry_safe(trans, root, | 1055 | ret = btrfs_log_dentry_safe(trans, root, |
| 1051 | file->f_dentry); | 1056 | file->f_dentry); |
| 1057 | mutex_unlock(&inode->i_mutex); | ||
| 1052 | if (ret == 0) { | 1058 | if (ret == 0) { |
| 1053 | ret = btrfs_sync_log(trans, root); | 1059 | ret = btrfs_sync_log(trans, root); |
| 1054 | if (ret == 0) | 1060 | if (ret == 0) |
| @@ -1067,6 +1073,7 @@ out: | |||
| 1067 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); | 1073 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); |
| 1068 | } | 1074 | } |
| 1069 | } | 1075 | } |
| 1076 | done: | ||
| 1070 | current->backing_dev_info = NULL; | 1077 | current->backing_dev_info = NULL; |
| 1071 | return num_written ? num_written : err; | 1078 | return num_written ? num_written : err; |
| 1072 | } | 1079 | } |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 558cac2dfa54..8039390bd6a6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -4501,6 +4501,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 4501 | BTRFS_I(inode)->index_cnt = 2; | 4501 | BTRFS_I(inode)->index_cnt = 2; |
| 4502 | BTRFS_I(inode)->root = root; | 4502 | BTRFS_I(inode)->root = root; |
| 4503 | BTRFS_I(inode)->generation = trans->transid; | 4503 | BTRFS_I(inode)->generation = trans->transid; |
| 4504 | inode->i_generation = BTRFS_I(inode)->generation; | ||
| 4504 | btrfs_set_inode_space_info(root, inode); | 4505 | btrfs_set_inode_space_info(root, inode); |
| 4505 | 4506 | ||
| 4506 | if (mode & S_IFDIR) | 4507 | if (mode & S_IFDIR) |
| @@ -4622,12 +4623,12 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
| 4622 | } | 4623 | } |
| 4623 | 4624 | ||
| 4624 | static int btrfs_add_nondir(struct btrfs_trans_handle *trans, | 4625 | static int btrfs_add_nondir(struct btrfs_trans_handle *trans, |
| 4625 | struct dentry *dentry, struct inode *inode, | 4626 | struct inode *dir, struct dentry *dentry, |
| 4626 | int backref, u64 index) | 4627 | struct inode *inode, int backref, u64 index) |
| 4627 | { | 4628 | { |
| 4628 | int err = btrfs_add_link(trans, dentry->d_parent->d_inode, | 4629 | int err = btrfs_add_link(trans, dir, inode, |
| 4629 | inode, dentry->d_name.name, | 4630 | dentry->d_name.name, dentry->d_name.len, |
| 4630 | dentry->d_name.len, backref, index); | 4631 | backref, index); |
| 4631 | if (!err) { | 4632 | if (!err) { |
| 4632 | d_instantiate(dentry, inode); | 4633 | d_instantiate(dentry, inode); |
| 4633 | return 0; | 4634 | return 0; |
| @@ -4668,8 +4669,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 4668 | btrfs_set_trans_block_group(trans, dir); | 4669 | btrfs_set_trans_block_group(trans, dir); |
| 4669 | 4670 | ||
| 4670 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4671 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4671 | dentry->d_name.len, | 4672 | dentry->d_name.len, dir->i_ino, objectid, |
| 4672 | dentry->d_parent->d_inode->i_ino, objectid, | ||
| 4673 | BTRFS_I(dir)->block_group, mode, &index); | 4673 | BTRFS_I(dir)->block_group, mode, &index); |
| 4674 | err = PTR_ERR(inode); | 4674 | err = PTR_ERR(inode); |
| 4675 | if (IS_ERR(inode)) | 4675 | if (IS_ERR(inode)) |
| @@ -4682,7 +4682,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 4682 | } | 4682 | } |
| 4683 | 4683 | ||
| 4684 | btrfs_set_trans_block_group(trans, inode); | 4684 | btrfs_set_trans_block_group(trans, inode); |
| 4685 | err = btrfs_add_nondir(trans, dentry, inode, 0, index); | 4685 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 4686 | if (err) | 4686 | if (err) |
| 4687 | drop_inode = 1; | 4687 | drop_inode = 1; |
| 4688 | else { | 4688 | else { |
| @@ -4730,10 +4730,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 4730 | btrfs_set_trans_block_group(trans, dir); | 4730 | btrfs_set_trans_block_group(trans, dir); |
| 4731 | 4731 | ||
| 4732 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4732 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4733 | dentry->d_name.len, | 4733 | dentry->d_name.len, dir->i_ino, objectid, |
| 4734 | dentry->d_parent->d_inode->i_ino, | 4734 | BTRFS_I(dir)->block_group, mode, &index); |
| 4735 | objectid, BTRFS_I(dir)->block_group, mode, | ||
| 4736 | &index); | ||
| 4737 | err = PTR_ERR(inode); | 4735 | err = PTR_ERR(inode); |
| 4738 | if (IS_ERR(inode)) | 4736 | if (IS_ERR(inode)) |
| 4739 | goto out_unlock; | 4737 | goto out_unlock; |
| @@ -4745,7 +4743,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 4745 | } | 4743 | } |
| 4746 | 4744 | ||
| 4747 | btrfs_set_trans_block_group(trans, inode); | 4745 | btrfs_set_trans_block_group(trans, inode); |
| 4748 | err = btrfs_add_nondir(trans, dentry, inode, 0, index); | 4746 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 4749 | if (err) | 4747 | if (err) |
| 4750 | drop_inode = 1; | 4748 | drop_inode = 1; |
| 4751 | else { | 4749 | else { |
| @@ -4787,6 +4785,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 4787 | return -EPERM; | 4785 | return -EPERM; |
| 4788 | 4786 | ||
| 4789 | btrfs_inc_nlink(inode); | 4787 | btrfs_inc_nlink(inode); |
| 4788 | inode->i_ctime = CURRENT_TIME; | ||
| 4790 | 4789 | ||
| 4791 | err = btrfs_set_inode_index(dir, &index); | 4790 | err = btrfs_set_inode_index(dir, &index); |
| 4792 | if (err) | 4791 | if (err) |
| @@ -4805,15 +4804,17 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 4805 | btrfs_set_trans_block_group(trans, dir); | 4804 | btrfs_set_trans_block_group(trans, dir); |
| 4806 | ihold(inode); | 4805 | ihold(inode); |
| 4807 | 4806 | ||
| 4808 | err = btrfs_add_nondir(trans, dentry, inode, 1, index); | 4807 | err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index); |
| 4809 | 4808 | ||
| 4810 | if (err) { | 4809 | if (err) { |
| 4811 | drop_inode = 1; | 4810 | drop_inode = 1; |
| 4812 | } else { | 4811 | } else { |
| 4812 | struct dentry *parent = dget_parent(dentry); | ||
| 4813 | btrfs_update_inode_block_group(trans, dir); | 4813 | btrfs_update_inode_block_group(trans, dir); |
| 4814 | err = btrfs_update_inode(trans, root, inode); | 4814 | err = btrfs_update_inode(trans, root, inode); |
| 4815 | BUG_ON(err); | 4815 | BUG_ON(err); |
| 4816 | btrfs_log_new_name(trans, inode, NULL, dentry->d_parent); | 4816 | btrfs_log_new_name(trans, inode, NULL, parent); |
| 4817 | dput(parent); | ||
| 4817 | } | 4818 | } |
| 4818 | 4819 | ||
| 4819 | nr = trans->blocks_used; | 4820 | nr = trans->blocks_used; |
| @@ -4853,8 +4854,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 4853 | btrfs_set_trans_block_group(trans, dir); | 4854 | btrfs_set_trans_block_group(trans, dir); |
| 4854 | 4855 | ||
| 4855 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4856 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4856 | dentry->d_name.len, | 4857 | dentry->d_name.len, dir->i_ino, objectid, |
| 4857 | dentry->d_parent->d_inode->i_ino, objectid, | ||
| 4858 | BTRFS_I(dir)->block_group, S_IFDIR | mode, | 4858 | BTRFS_I(dir)->block_group, S_IFDIR | mode, |
| 4859 | &index); | 4859 | &index); |
| 4860 | if (IS_ERR(inode)) { | 4860 | if (IS_ERR(inode)) { |
| @@ -4877,9 +4877,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 4877 | if (err) | 4877 | if (err) |
| 4878 | goto out_fail; | 4878 | goto out_fail; |
| 4879 | 4879 | ||
| 4880 | err = btrfs_add_link(trans, dentry->d_parent->d_inode, | 4880 | err = btrfs_add_link(trans, dir, inode, dentry->d_name.name, |
| 4881 | inode, dentry->d_name.name, | 4881 | dentry->d_name.len, 0, index); |
| 4882 | dentry->d_name.len, 0, index); | ||
| 4883 | if (err) | 4882 | if (err) |
| 4884 | goto out_fail; | 4883 | goto out_fail; |
| 4885 | 4884 | ||
| @@ -5535,13 +5534,21 @@ struct btrfs_dio_private { | |||
| 5535 | u64 bytes; | 5534 | u64 bytes; |
| 5536 | u32 *csums; | 5535 | u32 *csums; |
| 5537 | void *private; | 5536 | void *private; |
| 5537 | |||
| 5538 | /* number of bios pending for this dio */ | ||
| 5539 | atomic_t pending_bios; | ||
| 5540 | |||
| 5541 | /* IO errors */ | ||
| 5542 | int errors; | ||
| 5543 | |||
| 5544 | struct bio *orig_bio; | ||
| 5538 | }; | 5545 | }; |
| 5539 | 5546 | ||
| 5540 | static void btrfs_endio_direct_read(struct bio *bio, int err) | 5547 | static void btrfs_endio_direct_read(struct bio *bio, int err) |
| 5541 | { | 5548 | { |
| 5549 | struct btrfs_dio_private *dip = bio->bi_private; | ||
| 5542 | struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; | 5550 | struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; |
| 5543 | struct bio_vec *bvec = bio->bi_io_vec; | 5551 | struct bio_vec *bvec = bio->bi_io_vec; |
| 5544 | struct btrfs_dio_private *dip = bio->bi_private; | ||
| 5545 | struct inode *inode = dip->inode; | 5552 | struct inode *inode = dip->inode; |
| 5546 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5553 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 5547 | u64 start; | 5554 | u64 start; |
| @@ -5595,15 +5602,18 @@ static void btrfs_endio_direct_write(struct bio *bio, int err) | |||
| 5595 | struct btrfs_trans_handle *trans; | 5602 | struct btrfs_trans_handle *trans; |
| 5596 | struct btrfs_ordered_extent *ordered = NULL; | 5603 | struct btrfs_ordered_extent *ordered = NULL; |
| 5597 | struct extent_state *cached_state = NULL; | 5604 | struct extent_state *cached_state = NULL; |
| 5605 | u64 ordered_offset = dip->logical_offset; | ||
| 5606 | u64 ordered_bytes = dip->bytes; | ||
| 5598 | int ret; | 5607 | int ret; |
| 5599 | 5608 | ||
| 5600 | if (err) | 5609 | if (err) |
| 5601 | goto out_done; | 5610 | goto out_done; |
| 5602 | 5611 | again: | |
| 5603 | ret = btrfs_dec_test_ordered_pending(inode, &ordered, | 5612 | ret = btrfs_dec_test_first_ordered_pending(inode, &ordered, |
| 5604 | dip->logical_offset, dip->bytes); | 5613 | &ordered_offset, |
| 5614 | ordered_bytes); | ||
| 5605 | if (!ret) | 5615 | if (!ret) |
| 5606 | goto out_done; | 5616 | goto out_test; |
| 5607 | 5617 | ||
| 5608 | BUG_ON(!ordered); | 5618 | BUG_ON(!ordered); |
| 5609 | 5619 | ||
| @@ -5663,8 +5673,20 @@ out_unlock: | |||
| 5663 | out: | 5673 | out: |
| 5664 | btrfs_delalloc_release_metadata(inode, ordered->len); | 5674 | btrfs_delalloc_release_metadata(inode, ordered->len); |
| 5665 | btrfs_end_transaction(trans, root); | 5675 | btrfs_end_transaction(trans, root); |
| 5676 | ordered_offset = ordered->file_offset + ordered->len; | ||
| 5666 | btrfs_put_ordered_extent(ordered); | 5677 | btrfs_put_ordered_extent(ordered); |
| 5667 | btrfs_put_ordered_extent(ordered); | 5678 | btrfs_put_ordered_extent(ordered); |
| 5679 | |||
| 5680 | out_test: | ||
| 5681 | /* | ||
| 5682 | * our bio might span multiple ordered extents. If we haven't | ||
| 5683 | * completed the accounting for the whole dio, go back and try again | ||
| 5684 | */ | ||
| 5685 | if (ordered_offset < dip->logical_offset + dip->bytes) { | ||
| 5686 | ordered_bytes = dip->logical_offset + dip->bytes - | ||
| 5687 | ordered_offset; | ||
| 5688 | goto again; | ||
| 5689 | } | ||
| 5668 | out_done: | 5690 | out_done: |
| 5669 | bio->bi_private = dip->private; | 5691 | bio->bi_private = dip->private; |
| 5670 | 5692 | ||
| @@ -5684,6 +5706,176 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, | |||
| 5684 | return 0; | 5706 | return 0; |
| 5685 | } | 5707 | } |
| 5686 | 5708 | ||
| 5709 | static void btrfs_end_dio_bio(struct bio *bio, int err) | ||
| 5710 | { | ||
| 5711 | struct btrfs_dio_private *dip = bio->bi_private; | ||
| 5712 | |||
| 5713 | if (err) { | ||
| 5714 | printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " | ||
| 5715 | "disk_bytenr %lu len %u err no %d\n", | ||
| 5716 | dip->inode->i_ino, bio->bi_rw, bio->bi_sector, | ||
| 5717 | bio->bi_size, err); | ||
| 5718 | dip->errors = 1; | ||
| 5719 | |||
| 5720 | /* | ||
| 5721 | * before atomic variable goto zero, we must make sure | ||
| 5722 | * dip->errors is perceived to be set. | ||
| 5723 | */ | ||
| 5724 | smp_mb__before_atomic_dec(); | ||
| 5725 | } | ||
| 5726 | |||
| 5727 | /* if there are more bios still pending for this dio, just exit */ | ||
| 5728 | if (!atomic_dec_and_test(&dip->pending_bios)) | ||
| 5729 | goto out; | ||
| 5730 | |||
| 5731 | if (dip->errors) | ||
| 5732 | bio_io_error(dip->orig_bio); | ||
| 5733 | else { | ||
| 5734 | set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags); | ||
| 5735 | bio_endio(dip->orig_bio, 0); | ||
| 5736 | } | ||
| 5737 | out: | ||
| 5738 | bio_put(bio); | ||
| 5739 | } | ||
| 5740 | |||
| 5741 | static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, | ||
| 5742 | u64 first_sector, gfp_t gfp_flags) | ||
| 5743 | { | ||
| 5744 | int nr_vecs = bio_get_nr_vecs(bdev); | ||
| 5745 | return btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags); | ||
| 5746 | } | ||
| 5747 | |||
| 5748 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | ||
| 5749 | int rw, u64 file_offset, int skip_sum, | ||
| 5750 | u32 *csums) | ||
| 5751 | { | ||
| 5752 | int write = rw & REQ_WRITE; | ||
| 5753 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 5754 | int ret; | ||
| 5755 | |||
| 5756 | bio_get(bio); | ||
| 5757 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); | ||
| 5758 | if (ret) | ||
| 5759 | goto err; | ||
| 5760 | |||
| 5761 | if (write && !skip_sum) { | ||
| 5762 | ret = btrfs_wq_submit_bio(root->fs_info, | ||
| 5763 | inode, rw, bio, 0, 0, | ||
| 5764 | file_offset, | ||
| 5765 | __btrfs_submit_bio_start_direct_io, | ||
| 5766 | __btrfs_submit_bio_done); | ||
| 5767 | goto err; | ||
| 5768 | } else if (!skip_sum) | ||
| 5769 | btrfs_lookup_bio_sums_dio(root, inode, bio, | ||
| 5770 | file_offset, csums); | ||
| 5771 | |||
| 5772 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | ||
| 5773 | err: | ||
| 5774 | bio_put(bio); | ||
| 5775 | return ret; | ||
| 5776 | } | ||
| 5777 | |||
| 5778 | static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | ||
| 5779 | int skip_sum) | ||
| 5780 | { | ||
| 5781 | struct inode *inode = dip->inode; | ||
| 5782 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 5783 | struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; | ||
| 5784 | struct bio *bio; | ||
| 5785 | struct bio *orig_bio = dip->orig_bio; | ||
| 5786 | struct bio_vec *bvec = orig_bio->bi_io_vec; | ||
| 5787 | u64 start_sector = orig_bio->bi_sector; | ||
| 5788 | u64 file_offset = dip->logical_offset; | ||
| 5789 | u64 submit_len = 0; | ||
| 5790 | u64 map_length; | ||
| 5791 | int nr_pages = 0; | ||
| 5792 | u32 *csums = dip->csums; | ||
| 5793 | int ret = 0; | ||
| 5794 | |||
| 5795 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
| 5796 | if (!bio) | ||
| 5797 | return -ENOMEM; | ||
| 5798 | bio->bi_private = dip; | ||
| 5799 | bio->bi_end_io = btrfs_end_dio_bio; | ||
| 5800 | atomic_inc(&dip->pending_bios); | ||
| 5801 | |||
| 5802 | map_length = orig_bio->bi_size; | ||
| 5803 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | ||
| 5804 | &map_length, NULL, 0); | ||
| 5805 | if (ret) { | ||
| 5806 | bio_put(bio); | ||
| 5807 | return -EIO; | ||
| 5808 | } | ||
| 5809 | |||
| 5810 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { | ||
| 5811 | if (unlikely(map_length < submit_len + bvec->bv_len || | ||
| 5812 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, | ||
| 5813 | bvec->bv_offset) < bvec->bv_len)) { | ||
| 5814 | /* | ||
| 5815 | * inc the count before we submit the bio so | ||
| 5816 | * we know the end IO handler won't happen before | ||
| 5817 | * we inc the count. Otherwise, the dip might get freed | ||
| 5818 | * before we're done setting it up | ||
| 5819 | */ | ||
| 5820 | atomic_inc(&dip->pending_bios); | ||
| 5821 | ret = __btrfs_submit_dio_bio(bio, inode, rw, | ||
| 5822 | file_offset, skip_sum, | ||
| 5823 | csums); | ||
| 5824 | if (ret) { | ||
| 5825 | bio_put(bio); | ||
| 5826 | atomic_dec(&dip->pending_bios); | ||
| 5827 | goto out_err; | ||
| 5828 | } | ||
| 5829 | |||
| 5830 | if (!skip_sum) | ||
| 5831 | csums = csums + nr_pages; | ||
| 5832 | start_sector += submit_len >> 9; | ||
| 5833 | file_offset += submit_len; | ||
| 5834 | |||
| 5835 | submit_len = 0; | ||
| 5836 | nr_pages = 0; | ||
| 5837 | |||
| 5838 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, | ||
| 5839 | start_sector, GFP_NOFS); | ||
| 5840 | if (!bio) | ||
| 5841 | goto out_err; | ||
| 5842 | bio->bi_private = dip; | ||
| 5843 | bio->bi_end_io = btrfs_end_dio_bio; | ||
| 5844 | |||
| 5845 | map_length = orig_bio->bi_size; | ||
| 5846 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | ||
| 5847 | &map_length, NULL, 0); | ||
| 5848 | if (ret) { | ||
| 5849 | bio_put(bio); | ||
| 5850 | goto out_err; | ||
| 5851 | } | ||
| 5852 | } else { | ||
| 5853 | submit_len += bvec->bv_len; | ||
| 5854 | nr_pages ++; | ||
| 5855 | bvec++; | ||
| 5856 | } | ||
| 5857 | } | ||
| 5858 | |||
| 5859 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, | ||
| 5860 | csums); | ||
| 5861 | if (!ret) | ||
| 5862 | return 0; | ||
| 5863 | |||
| 5864 | bio_put(bio); | ||
| 5865 | out_err: | ||
| 5866 | dip->errors = 1; | ||
| 5867 | /* | ||
| 5868 | * before atomic variable goto zero, we must | ||
| 5869 | * make sure dip->errors is perceived to be set. | ||
| 5870 | */ | ||
| 5871 | smp_mb__before_atomic_dec(); | ||
| 5872 | if (atomic_dec_and_test(&dip->pending_bios)) | ||
| 5873 | bio_io_error(dip->orig_bio); | ||
| 5874 | |||
| 5875 | /* bio_end_io() will handle error, so we needn't return it */ | ||
| 5876 | return 0; | ||
| 5877 | } | ||
| 5878 | |||
| 5687 | static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, | 5879 | static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, |
| 5688 | loff_t file_offset) | 5880 | loff_t file_offset) |
| 5689 | { | 5881 | { |
| @@ -5723,36 +5915,18 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, | |||
| 5723 | 5915 | ||
| 5724 | dip->disk_bytenr = (u64)bio->bi_sector << 9; | 5916 | dip->disk_bytenr = (u64)bio->bi_sector << 9; |
| 5725 | bio->bi_private = dip; | 5917 | bio->bi_private = dip; |
| 5918 | dip->errors = 0; | ||
| 5919 | dip->orig_bio = bio; | ||
| 5920 | atomic_set(&dip->pending_bios, 0); | ||
| 5726 | 5921 | ||
| 5727 | if (write) | 5922 | if (write) |
| 5728 | bio->bi_end_io = btrfs_endio_direct_write; | 5923 | bio->bi_end_io = btrfs_endio_direct_write; |
| 5729 | else | 5924 | else |
| 5730 | bio->bi_end_io = btrfs_endio_direct_read; | 5925 | bio->bi_end_io = btrfs_endio_direct_read; |
| 5731 | 5926 | ||
| 5732 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); | 5927 | ret = btrfs_submit_direct_hook(rw, dip, skip_sum); |
| 5733 | if (ret) | 5928 | if (!ret) |
| 5734 | goto out_err; | ||
| 5735 | |||
| 5736 | if (write && !skip_sum) { | ||
| 5737 | ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, | ||
| 5738 | inode, rw, bio, 0, 0, | ||
| 5739 | dip->logical_offset, | ||
| 5740 | __btrfs_submit_bio_start_direct_io, | ||
| 5741 | __btrfs_submit_bio_done); | ||
| 5742 | if (ret) | ||
| 5743 | goto out_err; | ||
| 5744 | return; | 5929 | return; |
| 5745 | } else if (!skip_sum) | ||
| 5746 | btrfs_lookup_bio_sums_dio(root, inode, bio, | ||
| 5747 | dip->logical_offset, dip->csums); | ||
| 5748 | |||
| 5749 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | ||
| 5750 | if (ret) | ||
| 5751 | goto out_err; | ||
| 5752 | return; | ||
| 5753 | out_err: | ||
| 5754 | kfree(dip->csums); | ||
| 5755 | kfree(dip); | ||
| 5756 | free_ordered: | 5930 | free_ordered: |
| 5757 | /* | 5931 | /* |
| 5758 | * If this is a write, we need to clean up the reserved space and kill | 5932 | * If this is a write, we need to clean up the reserved space and kill |
| @@ -6607,8 +6781,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 6607 | BUG_ON(ret); | 6781 | BUG_ON(ret); |
| 6608 | 6782 | ||
| 6609 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { | 6783 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { |
| 6610 | btrfs_log_new_name(trans, old_inode, old_dir, | 6784 | struct dentry *parent = dget_parent(new_dentry); |
| 6611 | new_dentry->d_parent); | 6785 | btrfs_log_new_name(trans, old_inode, old_dir, parent); |
| 6786 | dput(parent); | ||
| 6612 | btrfs_end_log_trans(root); | 6787 | btrfs_end_log_trans(root); |
| 6613 | } | 6788 | } |
| 6614 | out_fail: | 6789 | out_fail: |
| @@ -6758,8 +6933,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 6758 | btrfs_set_trans_block_group(trans, dir); | 6933 | btrfs_set_trans_block_group(trans, dir); |
| 6759 | 6934 | ||
| 6760 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 6935 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 6761 | dentry->d_name.len, | 6936 | dentry->d_name.len, dir->i_ino, objectid, |
| 6762 | dentry->d_parent->d_inode->i_ino, objectid, | ||
| 6763 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, | 6937 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, |
| 6764 | &index); | 6938 | &index); |
| 6765 | err = PTR_ERR(inode); | 6939 | err = PTR_ERR(inode); |
| @@ -6773,7 +6947,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 6773 | } | 6947 | } |
| 6774 | 6948 | ||
| 6775 | btrfs_set_trans_block_group(trans, inode); | 6949 | btrfs_set_trans_block_group(trans, inode); |
| 6776 | err = btrfs_add_nondir(trans, dentry, inode, 0, index); | 6950 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 6777 | if (err) | 6951 | if (err) |
| 6778 | drop_inode = 1; | 6952 | drop_inode = 1; |
| 6779 | else { | 6953 | else { |
| @@ -6844,6 +7018,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 6844 | struct btrfs_root *root = BTRFS_I(inode)->root; | 7018 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 6845 | struct btrfs_key ins; | 7019 | struct btrfs_key ins; |
| 6846 | u64 cur_offset = start; | 7020 | u64 cur_offset = start; |
| 7021 | u64 i_size; | ||
| 6847 | int ret = 0; | 7022 | int ret = 0; |
| 6848 | bool own_trans = true; | 7023 | bool own_trans = true; |
| 6849 | 7024 | ||
| @@ -6885,11 +7060,11 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 6885 | (actual_len > inode->i_size) && | 7060 | (actual_len > inode->i_size) && |
| 6886 | (cur_offset > inode->i_size)) { | 7061 | (cur_offset > inode->i_size)) { |
| 6887 | if (cur_offset > actual_len) | 7062 | if (cur_offset > actual_len) |
| 6888 | i_size_write(inode, actual_len); | 7063 | i_size = actual_len; |
| 6889 | else | 7064 | else |
| 6890 | i_size_write(inode, cur_offset); | 7065 | i_size = cur_offset; |
| 6891 | i_size_write(inode, cur_offset); | 7066 | i_size_write(inode, i_size); |
| 6892 | btrfs_ordered_update_i_size(inode, cur_offset, NULL); | 7067 | btrfs_ordered_update_i_size(inode, i_size, NULL); |
| 6893 | } | 7068 | } |
| 6894 | 7069 | ||
| 6895 | ret = btrfs_update_inode(trans, root, inode); | 7070 | ret = btrfs_update_inode(trans, root, inode); |
| @@ -6943,6 +7118,10 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
| 6943 | btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start); | 7118 | btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start); |
| 6944 | 7119 | ||
| 6945 | mutex_lock(&inode->i_mutex); | 7120 | mutex_lock(&inode->i_mutex); |
| 7121 | ret = inode_newsize_ok(inode, alloc_end); | ||
| 7122 | if (ret) | ||
| 7123 | goto out; | ||
| 7124 | |||
| 6946 | if (alloc_start > inode->i_size) { | 7125 | if (alloc_start > inode->i_size) { |
| 6947 | ret = btrfs_cont_expand(inode, alloc_start); | 7126 | ret = btrfs_cont_expand(inode, alloc_start); |
| 6948 | if (ret) | 7127 | if (ret) |
| @@ -7139,6 +7318,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
| 7139 | .readlink = generic_readlink, | 7318 | .readlink = generic_readlink, |
| 7140 | .follow_link = page_follow_link_light, | 7319 | .follow_link = page_follow_link_light, |
| 7141 | .put_link = page_put_link, | 7320 | .put_link = page_put_link, |
| 7321 | .getattr = btrfs_getattr, | ||
| 7142 | .permission = btrfs_permission, | 7322 | .permission = btrfs_permission, |
| 7143 | .setxattr = btrfs_setxattr, | 7323 | .setxattr = btrfs_setxattr, |
| 7144 | .getxattr = btrfs_getxattr, | 7324 | .getxattr = btrfs_getxattr, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 463d91b4dd3a..f1c9bb4079ed 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -233,7 +233,8 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 233 | struct btrfs_inode_item *inode_item; | 233 | struct btrfs_inode_item *inode_item; |
| 234 | struct extent_buffer *leaf; | 234 | struct extent_buffer *leaf; |
| 235 | struct btrfs_root *new_root; | 235 | struct btrfs_root *new_root; |
| 236 | struct inode *dir = dentry->d_parent->d_inode; | 236 | struct dentry *parent = dget_parent(dentry); |
| 237 | struct inode *dir; | ||
| 237 | int ret; | 238 | int ret; |
| 238 | int err; | 239 | int err; |
| 239 | u64 objectid; | 240 | u64 objectid; |
| @@ -242,8 +243,13 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 242 | 243 | ||
| 243 | ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root, | 244 | ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root, |
| 244 | 0, &objectid); | 245 | 0, &objectid); |
| 245 | if (ret) | 246 | if (ret) { |
| 247 | dput(parent); | ||
| 246 | return ret; | 248 | return ret; |
| 249 | } | ||
| 250 | |||
| 251 | dir = parent->d_inode; | ||
| 252 | |||
| 247 | /* | 253 | /* |
| 248 | * 1 - inode item | 254 | * 1 - inode item |
| 249 | * 2 - refs | 255 | * 2 - refs |
| @@ -251,8 +257,10 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 251 | * 2 - dir items | 257 | * 2 - dir items |
| 252 | */ | 258 | */ |
| 253 | trans = btrfs_start_transaction(root, 6); | 259 | trans = btrfs_start_transaction(root, 6); |
| 254 | if (IS_ERR(trans)) | 260 | if (IS_ERR(trans)) { |
| 261 | dput(parent); | ||
| 255 | return PTR_ERR(trans); | 262 | return PTR_ERR(trans); |
| 263 | } | ||
| 256 | 264 | ||
| 257 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 265 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
| 258 | 0, objectid, NULL, 0, 0, 0); | 266 | 0, objectid, NULL, 0, 0, 0); |
| @@ -339,6 +347,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 339 | 347 | ||
| 340 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); | 348 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); |
| 341 | fail: | 349 | fail: |
| 350 | dput(parent); | ||
| 342 | if (async_transid) { | 351 | if (async_transid) { |
| 343 | *async_transid = trans->transid; | 352 | *async_transid = trans->transid; |
| 344 | err = btrfs_commit_transaction_async(trans, root, 1); | 353 | err = btrfs_commit_transaction_async(trans, root, 1); |
| @@ -354,6 +363,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
| 354 | char *name, int namelen, u64 *async_transid) | 363 | char *name, int namelen, u64 *async_transid) |
| 355 | { | 364 | { |
| 356 | struct inode *inode; | 365 | struct inode *inode; |
| 366 | struct dentry *parent; | ||
| 357 | struct btrfs_pending_snapshot *pending_snapshot; | 367 | struct btrfs_pending_snapshot *pending_snapshot; |
| 358 | struct btrfs_trans_handle *trans; | 368 | struct btrfs_trans_handle *trans; |
| 359 | int ret; | 369 | int ret; |
| @@ -396,7 +406,9 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
| 396 | 406 | ||
| 397 | btrfs_orphan_cleanup(pending_snapshot->snap); | 407 | btrfs_orphan_cleanup(pending_snapshot->snap); |
| 398 | 408 | ||
| 399 | inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); | 409 | parent = dget_parent(dentry); |
| 410 | inode = btrfs_lookup_dentry(parent->d_inode, dentry); | ||
| 411 | dput(parent); | ||
| 400 | if (IS_ERR(inode)) { | 412 | if (IS_ERR(inode)) { |
| 401 | ret = PTR_ERR(inode); | 413 | ret = PTR_ERR(inode); |
| 402 | goto fail; | 414 | goto fail; |
| @@ -1669,12 +1681,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1669 | olen = len = src->i_size - off; | 1681 | olen = len = src->i_size - off; |
| 1670 | /* if we extend to eof, continue to block boundary */ | 1682 | /* if we extend to eof, continue to block boundary */ |
| 1671 | if (off + len == src->i_size) | 1683 | if (off + len == src->i_size) |
| 1672 | len = ((src->i_size + bs-1) & ~(bs-1)) | 1684 | len = ALIGN(src->i_size, bs) - off; |
| 1673 | - off; | ||
| 1674 | 1685 | ||
| 1675 | /* verify the end result is block aligned */ | 1686 | /* verify the end result is block aligned */ |
| 1676 | if ((off & (bs-1)) || | 1687 | if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) || |
| 1677 | ((off + len) & (bs-1))) | 1688 | !IS_ALIGNED(destoff, bs)) |
| 1678 | goto out_unlock; | 1689 | goto out_unlock; |
| 1679 | 1690 | ||
| 1680 | /* do any pending delalloc/csum calc on src, one way or | 1691 | /* do any pending delalloc/csum calc on src, one way or |
| @@ -1874,8 +1885,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1874 | * but shouldn't round up the file size | 1885 | * but shouldn't round up the file size |
| 1875 | */ | 1886 | */ |
| 1876 | endoff = new_key.offset + datal; | 1887 | endoff = new_key.offset + datal; |
| 1877 | if (endoff > off+olen) | 1888 | if (endoff > destoff+olen) |
| 1878 | endoff = off+olen; | 1889 | endoff = destoff+olen; |
| 1879 | if (endoff > inode->i_size) | 1890 | if (endoff > inode->i_size) |
| 1880 | btrfs_i_size_write(inode, endoff); | 1891 | btrfs_i_size_write(inode, endoff); |
| 1881 | 1892 | ||
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index f4621f6deca1..ae7737e352c9 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
| @@ -250,6 +250,73 @@ int btrfs_add_ordered_sum(struct inode *inode, | |||
| 250 | 250 | ||
| 251 | /* | 251 | /* |
| 252 | * this is used to account for finished IO across a given range | 252 | * this is used to account for finished IO across a given range |
| 253 | * of the file. The IO may span ordered extents. If | ||
| 254 | * a given ordered_extent is completely done, 1 is returned, otherwise | ||
| 255 | * 0. | ||
| 256 | * | ||
| 257 | * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used | ||
| 258 | * to make sure this function only returns 1 once for a given ordered extent. | ||
| 259 | * | ||
| 260 | * file_offset is updated to one byte past the range that is recorded as | ||
| 261 | * complete. This allows you to walk forward in the file. | ||
| 262 | */ | ||
| 263 | int btrfs_dec_test_first_ordered_pending(struct inode *inode, | ||
| 264 | struct btrfs_ordered_extent **cached, | ||
| 265 | u64 *file_offset, u64 io_size) | ||
| 266 | { | ||
| 267 | struct btrfs_ordered_inode_tree *tree; | ||
| 268 | struct rb_node *node; | ||
| 269 | struct btrfs_ordered_extent *entry = NULL; | ||
| 270 | int ret; | ||
| 271 | u64 dec_end; | ||
| 272 | u64 dec_start; | ||
| 273 | u64 to_dec; | ||
| 274 | |||
| 275 | tree = &BTRFS_I(inode)->ordered_tree; | ||
| 276 | spin_lock(&tree->lock); | ||
| 277 | node = tree_search(tree, *file_offset); | ||
| 278 | if (!node) { | ||
| 279 | ret = 1; | ||
| 280 | goto out; | ||
| 281 | } | ||
| 282 | |||
| 283 | entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); | ||
| 284 | if (!offset_in_entry(entry, *file_offset)) { | ||
| 285 | ret = 1; | ||
| 286 | goto out; | ||
| 287 | } | ||
| 288 | |||
| 289 | dec_start = max(*file_offset, entry->file_offset); | ||
| 290 | dec_end = min(*file_offset + io_size, entry->file_offset + | ||
| 291 | entry->len); | ||
| 292 | *file_offset = dec_end; | ||
| 293 | if (dec_start > dec_end) { | ||
| 294 | printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n", | ||
| 295 | (unsigned long long)dec_start, | ||
| 296 | (unsigned long long)dec_end); | ||
| 297 | } | ||
| 298 | to_dec = dec_end - dec_start; | ||
| 299 | if (to_dec > entry->bytes_left) { | ||
| 300 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", | ||
| 301 | (unsigned long long)entry->bytes_left, | ||
| 302 | (unsigned long long)to_dec); | ||
| 303 | } | ||
| 304 | entry->bytes_left -= to_dec; | ||
| 305 | if (entry->bytes_left == 0) | ||
| 306 | ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); | ||
| 307 | else | ||
| 308 | ret = 1; | ||
| 309 | out: | ||
| 310 | if (!ret && cached && entry) { | ||
| 311 | *cached = entry; | ||
| 312 | atomic_inc(&entry->refs); | ||
| 313 | } | ||
| 314 | spin_unlock(&tree->lock); | ||
| 315 | return ret == 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 319 | * this is used to account for finished IO across a given range | ||
| 253 | * of the file. The IO should not span ordered extents. If | 320 | * of the file. The IO should not span ordered extents. If |
| 254 | * a given ordered_extent is completely done, 1 is returned, otherwise | 321 | * a given ordered_extent is completely done, 1 is returned, otherwise |
| 255 | * 0. | 322 | * 0. |
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 8ac365492a3f..61dca83119dd 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h | |||
| @@ -141,6 +141,9 @@ int btrfs_remove_ordered_extent(struct inode *inode, | |||
| 141 | int btrfs_dec_test_ordered_pending(struct inode *inode, | 141 | int btrfs_dec_test_ordered_pending(struct inode *inode, |
| 142 | struct btrfs_ordered_extent **cached, | 142 | struct btrfs_ordered_extent **cached, |
| 143 | u64 file_offset, u64 io_size); | 143 | u64 file_offset, u64 io_size); |
| 144 | int btrfs_dec_test_first_ordered_pending(struct inode *inode, | ||
| 145 | struct btrfs_ordered_extent **cached, | ||
| 146 | u64 *file_offset, u64 io_size); | ||
| 144 | int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | 147 | int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, |
| 145 | u64 start, u64 len, u64 disk_len, int type); | 148 | u64 start, u64 len, u64 disk_len, int type); |
| 146 | int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, | 149 | int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8299a25ffc8f..dbb51ea7a13c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -244,6 +244,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
| 244 | case Opt_space_cache: | 244 | case Opt_space_cache: |
| 245 | printk(KERN_INFO "btrfs: enabling disk space caching\n"); | 245 | printk(KERN_INFO "btrfs: enabling disk space caching\n"); |
| 246 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); | 246 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); |
| 247 | break; | ||
| 247 | case Opt_clear_cache: | 248 | case Opt_clear_cache: |
| 248 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); | 249 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); |
| 249 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); | 250 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); |
| @@ -562,12 +563,26 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 562 | 563 | ||
| 563 | static int btrfs_test_super(struct super_block *s, void *data) | 564 | static int btrfs_test_super(struct super_block *s, void *data) |
| 564 | { | 565 | { |
| 565 | struct btrfs_fs_devices *test_fs_devices = data; | 566 | struct btrfs_root *test_root = data; |
| 566 | struct btrfs_root *root = btrfs_sb(s); | 567 | struct btrfs_root *root = btrfs_sb(s); |
| 567 | 568 | ||
| 568 | return root->fs_info->fs_devices == test_fs_devices; | 569 | /* |
| 570 | * If this super block is going away, return false as it | ||
| 571 | * can't match as an existing super block. | ||
| 572 | */ | ||
| 573 | if (!atomic_read(&s->s_active)) | ||
| 574 | return 0; | ||
| 575 | return root->fs_info->fs_devices == test_root->fs_info->fs_devices; | ||
| 576 | } | ||
| 577 | |||
| 578 | static int btrfs_set_super(struct super_block *s, void *data) | ||
| 579 | { | ||
| 580 | s->s_fs_info = data; | ||
| 581 | |||
| 582 | return set_anon_super(s, data); | ||
| 569 | } | 583 | } |
| 570 | 584 | ||
| 585 | |||
| 571 | /* | 586 | /* |
| 572 | * Find a superblock for the given device / mount point. | 587 | * Find a superblock for the given device / mount point. |
| 573 | * | 588 | * |
| @@ -581,6 +596,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 581 | struct super_block *s; | 596 | struct super_block *s; |
| 582 | struct dentry *root; | 597 | struct dentry *root; |
| 583 | struct btrfs_fs_devices *fs_devices = NULL; | 598 | struct btrfs_fs_devices *fs_devices = NULL; |
| 599 | struct btrfs_root *tree_root = NULL; | ||
| 600 | struct btrfs_fs_info *fs_info = NULL; | ||
| 584 | fmode_t mode = FMODE_READ; | 601 | fmode_t mode = FMODE_READ; |
| 585 | char *subvol_name = NULL; | 602 | char *subvol_name = NULL; |
| 586 | u64 subvol_objectid = 0; | 603 | u64 subvol_objectid = 0; |
| @@ -608,8 +625,24 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 608 | goto error_close_devices; | 625 | goto error_close_devices; |
| 609 | } | 626 | } |
| 610 | 627 | ||
| 628 | /* | ||
| 629 | * Setup a dummy root and fs_info for test/set super. This is because | ||
| 630 | * we don't actually fill this stuff out until open_ctree, but we need | ||
| 631 | * it for searching for existing supers, so this lets us do that and | ||
| 632 | * then open_ctree will properly initialize everything later. | ||
| 633 | */ | ||
| 634 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); | ||
| 635 | tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
| 636 | if (!fs_info || !tree_root) { | ||
| 637 | error = -ENOMEM; | ||
| 638 | goto error_close_devices; | ||
| 639 | } | ||
| 640 | fs_info->tree_root = tree_root; | ||
| 641 | fs_info->fs_devices = fs_devices; | ||
| 642 | tree_root->fs_info = fs_info; | ||
| 643 | |||
| 611 | bdev = fs_devices->latest_bdev; | 644 | bdev = fs_devices->latest_bdev; |
| 612 | s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices); | 645 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); |
| 613 | if (IS_ERR(s)) | 646 | if (IS_ERR(s)) |
| 614 | goto error_s; | 647 | goto error_s; |
| 615 | 648 | ||
| @@ -675,6 +708,8 @@ error_s: | |||
| 675 | error = PTR_ERR(s); | 708 | error = PTR_ERR(s); |
| 676 | error_close_devices: | 709 | error_close_devices: |
| 677 | btrfs_close_devices(fs_devices); | 710 | btrfs_close_devices(fs_devices); |
| 711 | kfree(fs_info); | ||
| 712 | kfree(tree_root); | ||
| 678 | error_free_subvol_name: | 713 | error_free_subvol_name: |
| 679 | kfree(subvol_name); | 714 | kfree(subvol_name); |
| 680 | return ERR_PTR(error); | 715 | return ERR_PTR(error); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 1fffbc017bdf..f50e931fc217 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -902,6 +902,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 902 | struct btrfs_root *root = pending->root; | 902 | struct btrfs_root *root = pending->root; |
| 903 | struct btrfs_root *parent_root; | 903 | struct btrfs_root *parent_root; |
| 904 | struct inode *parent_inode; | 904 | struct inode *parent_inode; |
| 905 | struct dentry *parent; | ||
| 905 | struct dentry *dentry; | 906 | struct dentry *dentry; |
| 906 | struct extent_buffer *tmp; | 907 | struct extent_buffer *tmp; |
| 907 | struct extent_buffer *old; | 908 | struct extent_buffer *old; |
| @@ -941,7 +942,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 941 | trans->block_rsv = &pending->block_rsv; | 942 | trans->block_rsv = &pending->block_rsv; |
| 942 | 943 | ||
| 943 | dentry = pending->dentry; | 944 | dentry = pending->dentry; |
| 944 | parent_inode = dentry->d_parent->d_inode; | 945 | parent = dget_parent(dentry); |
| 946 | parent_inode = parent->d_inode; | ||
| 945 | parent_root = BTRFS_I(parent_inode)->root; | 947 | parent_root = BTRFS_I(parent_inode)->root; |
| 946 | record_root_in_trans(trans, parent_root); | 948 | record_root_in_trans(trans, parent_root); |
| 947 | 949 | ||
| @@ -989,6 +991,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 989 | parent_inode->i_ino, index, | 991 | parent_inode->i_ino, index, |
| 990 | dentry->d_name.name, dentry->d_name.len); | 992 | dentry->d_name.name, dentry->d_name.len); |
| 991 | BUG_ON(ret); | 993 | BUG_ON(ret); |
| 994 | dput(parent); | ||
| 992 | 995 | ||
| 993 | key.offset = (u64)-1; | 996 | key.offset = (u64)-1; |
| 994 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); | 997 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index a29f19384a27..054744ac5719 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -2869,6 +2869,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
| 2869 | { | 2869 | { |
| 2870 | int ret = 0; | 2870 | int ret = 0; |
| 2871 | struct btrfs_root *root; | 2871 | struct btrfs_root *root; |
| 2872 | struct dentry *old_parent = NULL; | ||
| 2872 | 2873 | ||
| 2873 | /* | 2874 | /* |
| 2874 | * for regular files, if its inode is already on disk, we don't | 2875 | * for regular files, if its inode is already on disk, we don't |
| @@ -2910,10 +2911,13 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
| 2910 | if (IS_ROOT(parent)) | 2911 | if (IS_ROOT(parent)) |
| 2911 | break; | 2912 | break; |
| 2912 | 2913 | ||
| 2913 | parent = parent->d_parent; | 2914 | parent = dget_parent(parent); |
| 2915 | dput(old_parent); | ||
| 2916 | old_parent = parent; | ||
| 2914 | inode = parent->d_inode; | 2917 | inode = parent->d_inode; |
| 2915 | 2918 | ||
| 2916 | } | 2919 | } |
| 2920 | dput(old_parent); | ||
| 2917 | out: | 2921 | out: |
| 2918 | return ret; | 2922 | return ret; |
| 2919 | } | 2923 | } |
| @@ -2945,6 +2949,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 2945 | { | 2949 | { |
| 2946 | int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL; | 2950 | int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL; |
| 2947 | struct super_block *sb; | 2951 | struct super_block *sb; |
| 2952 | struct dentry *old_parent = NULL; | ||
| 2948 | int ret = 0; | 2953 | int ret = 0; |
| 2949 | u64 last_committed = root->fs_info->last_trans_committed; | 2954 | u64 last_committed = root->fs_info->last_trans_committed; |
| 2950 | 2955 | ||
| @@ -3016,10 +3021,13 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 3016 | if (IS_ROOT(parent)) | 3021 | if (IS_ROOT(parent)) |
| 3017 | break; | 3022 | break; |
| 3018 | 3023 | ||
| 3019 | parent = parent->d_parent; | 3024 | parent = dget_parent(parent); |
| 3025 | dput(old_parent); | ||
| 3026 | old_parent = parent; | ||
| 3020 | } | 3027 | } |
| 3021 | ret = 0; | 3028 | ret = 0; |
| 3022 | end_trans: | 3029 | end_trans: |
| 3030 | dput(old_parent); | ||
| 3023 | if (ret < 0) { | 3031 | if (ret < 0) { |
| 3024 | BUG_ON(ret != -ENOSPC); | 3032 | BUG_ON(ret != -ENOSPC); |
| 3025 | root->fs_info->last_trans_log_full_commit = trans->transid; | 3033 | root->fs_info->last_trans_log_full_commit = trans->transid; |
| @@ -3039,8 +3047,13 @@ end_no_trans: | |||
| 3039 | int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans, | 3047 | int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans, |
| 3040 | struct btrfs_root *root, struct dentry *dentry) | 3048 | struct btrfs_root *root, struct dentry *dentry) |
| 3041 | { | 3049 | { |
| 3042 | return btrfs_log_inode_parent(trans, root, dentry->d_inode, | 3050 | struct dentry *parent = dget_parent(dentry); |
| 3043 | dentry->d_parent, 0); | 3051 | int ret; |
| 3052 | |||
| 3053 | ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent, 0); | ||
| 3054 | dput(parent); | ||
| 3055 | |||
| 3056 | return ret; | ||
| 3044 | } | 3057 | } |
| 3045 | 3058 | ||
| 3046 | /* | 3059 | /* |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 58a9b9998b42..f606baf9ba72 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
| @@ -631,6 +631,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, | |||
| 631 | struct fs_disk_quota *fdq) | 631 | struct fs_disk_quota *fdq) |
| 632 | { | 632 | { |
| 633 | struct inode *inode = &ip->i_inode; | 633 | struct inode *inode = &ip->i_inode; |
| 634 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
| 634 | struct address_space *mapping = inode->i_mapping; | 635 | struct address_space *mapping = inode->i_mapping; |
| 635 | unsigned long index = loc >> PAGE_CACHE_SHIFT; | 636 | unsigned long index = loc >> PAGE_CACHE_SHIFT; |
| 636 | unsigned offset = loc & (PAGE_CACHE_SIZE - 1); | 637 | unsigned offset = loc & (PAGE_CACHE_SIZE - 1); |
| @@ -658,11 +659,11 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, | |||
| 658 | qd->qd_qb.qb_value = qp->qu_value; | 659 | qd->qd_qb.qb_value = qp->qu_value; |
| 659 | if (fdq) { | 660 | if (fdq) { |
| 660 | if (fdq->d_fieldmask & FS_DQ_BSOFT) { | 661 | if (fdq->d_fieldmask & FS_DQ_BSOFT) { |
| 661 | qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit); | 662 | qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift); |
| 662 | qd->qd_qb.qb_warn = qp->qu_warn; | 663 | qd->qd_qb.qb_warn = qp->qu_warn; |
| 663 | } | 664 | } |
| 664 | if (fdq->d_fieldmask & FS_DQ_BHARD) { | 665 | if (fdq->d_fieldmask & FS_DQ_BHARD) { |
| 665 | qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit); | 666 | qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift); |
| 666 | qd->qd_qb.qb_limit = qp->qu_limit; | 667 | qd->qd_qb.qb_limit = qp->qu_limit; |
| 667 | } | 668 | } |
| 668 | } | 669 | } |
| @@ -1497,9 +1498,9 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
| 1497 | fdq->d_version = FS_DQUOT_VERSION; | 1498 | fdq->d_version = FS_DQUOT_VERSION; |
| 1498 | fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; | 1499 | fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; |
| 1499 | fdq->d_id = id; | 1500 | fdq->d_id = id; |
| 1500 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit); | 1501 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; |
| 1501 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn); | 1502 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; |
| 1502 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value); | 1503 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; |
| 1503 | 1504 | ||
| 1504 | gfs2_glock_dq_uninit(&q_gh); | 1505 | gfs2_glock_dq_uninit(&q_gh); |
| 1505 | out: | 1506 | out: |
| @@ -1566,10 +1567,10 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
| 1566 | 1567 | ||
| 1567 | /* If nothing has changed, this is a no-op */ | 1568 | /* If nothing has changed, this is a no-op */ |
| 1568 | if ((fdq->d_fieldmask & FS_DQ_BSOFT) && | 1569 | if ((fdq->d_fieldmask & FS_DQ_BSOFT) && |
| 1569 | (fdq->d_blk_softlimit == be64_to_cpu(qd->qd_qb.qb_warn))) | 1570 | ((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn))) |
| 1570 | fdq->d_fieldmask ^= FS_DQ_BSOFT; | 1571 | fdq->d_fieldmask ^= FS_DQ_BSOFT; |
| 1571 | if ((fdq->d_fieldmask & FS_DQ_BHARD) && | 1572 | if ((fdq->d_fieldmask & FS_DQ_BHARD) && |
| 1572 | (fdq->d_blk_hardlimit == be64_to_cpu(qd->qd_qb.qb_limit))) | 1573 | ((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit))) |
| 1573 | fdq->d_fieldmask ^= FS_DQ_BHARD; | 1574 | fdq->d_fieldmask ^= FS_DQ_BHARD; |
| 1574 | if (fdq->d_fieldmask == 0) | 1575 | if (fdq->d_fieldmask == 0) |
| 1575 | goto out_i; | 1576 | goto out_i; |
diff --git a/fs/ioprio.c b/fs/ioprio.c index 2f7d05c89922..7da2a06508e5 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
| @@ -103,22 +103,15 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) | |||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | ret = -ESRCH; | 105 | ret = -ESRCH; |
| 106 | /* | 106 | rcu_read_lock(); |
| 107 | * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic", | ||
| 108 | * so we can't use rcu_read_lock(). See re-copy of ->ioprio | ||
| 109 | * in copy_process(). | ||
| 110 | */ | ||
| 111 | read_lock(&tasklist_lock); | ||
| 112 | switch (which) { | 107 | switch (which) { |
| 113 | case IOPRIO_WHO_PROCESS: | 108 | case IOPRIO_WHO_PROCESS: |
| 114 | rcu_read_lock(); | ||
| 115 | if (!who) | 109 | if (!who) |
| 116 | p = current; | 110 | p = current; |
| 117 | else | 111 | else |
| 118 | p = find_task_by_vpid(who); | 112 | p = find_task_by_vpid(who); |
| 119 | if (p) | 113 | if (p) |
| 120 | ret = set_task_ioprio(p, ioprio); | 114 | ret = set_task_ioprio(p, ioprio); |
| 121 | rcu_read_unlock(); | ||
| 122 | break; | 115 | break; |
| 123 | case IOPRIO_WHO_PGRP: | 116 | case IOPRIO_WHO_PGRP: |
| 124 | if (!who) | 117 | if (!who) |
| @@ -141,12 +134,7 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) | |||
| 141 | break; | 134 | break; |
| 142 | 135 | ||
| 143 | do_each_thread(g, p) { | 136 | do_each_thread(g, p) { |
| 144 | int match; | 137 | if (__task_cred(p)->uid != who) |
| 145 | |||
| 146 | rcu_read_lock(); | ||
| 147 | match = __task_cred(p)->uid == who; | ||
| 148 | rcu_read_unlock(); | ||
| 149 | if (!match) | ||
| 150 | continue; | 138 | continue; |
| 151 | ret = set_task_ioprio(p, ioprio); | 139 | ret = set_task_ioprio(p, ioprio); |
| 152 | if (ret) | 140 | if (ret) |
| @@ -160,7 +148,7 @@ free_uid: | |||
| 160 | ret = -EINVAL; | 148 | ret = -EINVAL; |
| 161 | } | 149 | } |
| 162 | 150 | ||
| 163 | read_unlock(&tasklist_lock); | 151 | rcu_read_unlock(); |
| 164 | return ret; | 152 | return ret; |
| 165 | } | 153 | } |
| 166 | 154 | ||
| @@ -204,17 +192,15 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) | |||
| 204 | int ret = -ESRCH; | 192 | int ret = -ESRCH; |
| 205 | int tmpio; | 193 | int tmpio; |
| 206 | 194 | ||
| 207 | read_lock(&tasklist_lock); | 195 | rcu_read_lock(); |
| 208 | switch (which) { | 196 | switch (which) { |
| 209 | case IOPRIO_WHO_PROCESS: | 197 | case IOPRIO_WHO_PROCESS: |
| 210 | rcu_read_lock(); | ||
| 211 | if (!who) | 198 | if (!who) |
| 212 | p = current; | 199 | p = current; |
| 213 | else | 200 | else |
| 214 | p = find_task_by_vpid(who); | 201 | p = find_task_by_vpid(who); |
| 215 | if (p) | 202 | if (p) |
| 216 | ret = get_task_ioprio(p); | 203 | ret = get_task_ioprio(p); |
| 217 | rcu_read_unlock(); | ||
| 218 | break; | 204 | break; |
| 219 | case IOPRIO_WHO_PGRP: | 205 | case IOPRIO_WHO_PGRP: |
| 220 | if (!who) | 206 | if (!who) |
| @@ -241,12 +227,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) | |||
| 241 | break; | 227 | break; |
| 242 | 228 | ||
| 243 | do_each_thread(g, p) { | 229 | do_each_thread(g, p) { |
| 244 | int match; | 230 | if (__task_cred(p)->uid != user->uid) |
| 245 | |||
| 246 | rcu_read_lock(); | ||
| 247 | match = __task_cred(p)->uid == user->uid; | ||
| 248 | rcu_read_unlock(); | ||
| 249 | if (!match) | ||
| 250 | continue; | 231 | continue; |
| 251 | tmpio = get_task_ioprio(p); | 232 | tmpio = get_task_ioprio(p); |
| 252 | if (tmpio < 0) | 233 | if (tmpio < 0) |
| @@ -264,6 +245,6 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) | |||
| 264 | ret = -EINVAL; | 245 | ret = -EINVAL; |
| 265 | } | 246 | } |
| 266 | 247 | ||
| 267 | read_unlock(&tasklist_lock); | 248 | rcu_read_unlock(); |
| 268 | return ret; | 249 | return ret; |
| 269 | } | 250 | } |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 662df2a5fad5..8ea4a4180a87 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -162,6 +162,7 @@ struct nfs_cache_array_entry { | |||
| 162 | u64 cookie; | 162 | u64 cookie; |
| 163 | u64 ino; | 163 | u64 ino; |
| 164 | struct qstr string; | 164 | struct qstr string; |
| 165 | unsigned char d_type; | ||
| 165 | }; | 166 | }; |
| 166 | 167 | ||
| 167 | struct nfs_cache_array { | 168 | struct nfs_cache_array { |
| @@ -171,8 +172,6 @@ struct nfs_cache_array { | |||
| 171 | struct nfs_cache_array_entry array[0]; | 172 | struct nfs_cache_array_entry array[0]; |
| 172 | }; | 173 | }; |
| 173 | 174 | ||
| 174 | #define MAX_READDIR_ARRAY ((PAGE_SIZE - sizeof(struct nfs_cache_array)) / sizeof(struct nfs_cache_array_entry)) | ||
| 175 | |||
| 176 | typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); | 175 | typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); |
| 177 | typedef struct { | 176 | typedef struct { |
| 178 | struct file *file; | 177 | struct file *file; |
| @@ -257,13 +256,17 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) | |||
| 257 | 256 | ||
| 258 | if (IS_ERR(array)) | 257 | if (IS_ERR(array)) |
| 259 | return PTR_ERR(array); | 258 | return PTR_ERR(array); |
| 259 | |||
| 260 | cache_entry = &array->array[array->size]; | ||
| 261 | |||
| 262 | /* Check that this entry lies within the page bounds */ | ||
| 260 | ret = -ENOSPC; | 263 | ret = -ENOSPC; |
| 261 | if (array->size >= MAX_READDIR_ARRAY) | 264 | if ((char *)&cache_entry[1] - (char *)page_address(page) > PAGE_SIZE) |
| 262 | goto out; | 265 | goto out; |
| 263 | 266 | ||
| 264 | cache_entry = &array->array[array->size]; | ||
| 265 | cache_entry->cookie = entry->prev_cookie; | 267 | cache_entry->cookie = entry->prev_cookie; |
| 266 | cache_entry->ino = entry->ino; | 268 | cache_entry->ino = entry->ino; |
| 269 | cache_entry->d_type = entry->d_type; | ||
| 267 | ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len); | 270 | ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len); |
| 268 | if (ret) | 271 | if (ret) |
| 269 | goto out; | 272 | goto out; |
| @@ -466,8 +469,9 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
| 466 | struct xdr_stream stream; | 469 | struct xdr_stream stream; |
| 467 | struct xdr_buf buf; | 470 | struct xdr_buf buf; |
| 468 | __be32 *ptr = xdr_page; | 471 | __be32 *ptr = xdr_page; |
| 469 | int status; | ||
| 470 | struct nfs_cache_array *array; | 472 | struct nfs_cache_array *array; |
| 473 | unsigned int count = 0; | ||
| 474 | int status; | ||
| 471 | 475 | ||
| 472 | buf.head->iov_base = xdr_page; | 476 | buf.head->iov_base = xdr_page; |
| 473 | buf.head->iov_len = buflen; | 477 | buf.head->iov_len = buflen; |
| @@ -488,6 +492,8 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
| 488 | break; | 492 | break; |
| 489 | } | 493 | } |
| 490 | 494 | ||
| 495 | count++; | ||
| 496 | |||
| 491 | if (desc->plus == 1) | 497 | if (desc->plus == 1) |
| 492 | nfs_prime_dcache(desc->file->f_path.dentry, entry); | 498 | nfs_prime_dcache(desc->file->f_path.dentry, entry); |
| 493 | 499 | ||
| @@ -496,13 +502,14 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
| 496 | break; | 502 | break; |
| 497 | } while (!entry->eof); | 503 | } while (!entry->eof); |
| 498 | 504 | ||
| 499 | if (status == -EBADCOOKIE && entry->eof) { | 505 | if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) { |
| 500 | array = nfs_readdir_get_array(page); | 506 | array = nfs_readdir_get_array(page); |
| 501 | if (!IS_ERR(array)) { | 507 | if (!IS_ERR(array)) { |
| 502 | array->eof_index = array->size; | 508 | array->eof_index = array->size; |
| 503 | status = 0; | 509 | status = 0; |
| 504 | nfs_readdir_release_array(page); | 510 | nfs_readdir_release_array(page); |
| 505 | } | 511 | } else |
| 512 | status = PTR_ERR(array); | ||
| 506 | } | 513 | } |
| 507 | return status; | 514 | return status; |
| 508 | } | 515 | } |
| @@ -696,21 +703,23 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
| 696 | int i = 0; | 703 | int i = 0; |
| 697 | int res = 0; | 704 | int res = 0; |
| 698 | struct nfs_cache_array *array = NULL; | 705 | struct nfs_cache_array *array = NULL; |
| 699 | unsigned int d_type = DT_UNKNOWN; | ||
| 700 | struct dentry *dentry = NULL; | ||
| 701 | 706 | ||
| 702 | array = nfs_readdir_get_array(desc->page); | 707 | array = nfs_readdir_get_array(desc->page); |
| 703 | if (IS_ERR(array)) | 708 | if (IS_ERR(array)) { |
| 704 | return PTR_ERR(array); | 709 | res = PTR_ERR(array); |
| 710 | goto out; | ||
| 711 | } | ||
| 705 | 712 | ||
| 706 | for (i = desc->cache_entry_index; i < array->size; i++) { | 713 | for (i = desc->cache_entry_index; i < array->size; i++) { |
| 707 | d_type = DT_UNKNOWN; | 714 | struct nfs_cache_array_entry *ent; |
| 708 | 715 | ||
| 709 | res = filldir(dirent, array->array[i].string.name, | 716 | ent = &array->array[i]; |
| 710 | array->array[i].string.len, file->f_pos, | 717 | if (filldir(dirent, ent->string.name, ent->string.len, |
| 711 | nfs_compat_user_ino64(array->array[i].ino), d_type); | 718 | file->f_pos, nfs_compat_user_ino64(ent->ino), |
| 712 | if (res < 0) | 719 | ent->d_type) < 0) { |
| 720 | desc->eof = 1; | ||
| 713 | break; | 721 | break; |
| 722 | } | ||
| 714 | file->f_pos++; | 723 | file->f_pos++; |
| 715 | desc->cache_entry_index = i; | 724 | desc->cache_entry_index = i; |
| 716 | if (i < (array->size-1)) | 725 | if (i < (array->size-1)) |
| @@ -722,9 +731,8 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
| 722 | desc->eof = 1; | 731 | desc->eof = 1; |
| 723 | 732 | ||
| 724 | nfs_readdir_release_array(desc->page); | 733 | nfs_readdir_release_array(desc->page); |
| 734 | out: | ||
| 725 | cache_page_release(desc); | 735 | cache_page_release(desc); |
| 726 | if (dentry != NULL) | ||
| 727 | dput(dentry); | ||
| 728 | dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", | 736 | dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", |
| 729 | (unsigned long long)*desc->dir_cookie, res); | 737 | (unsigned long long)*desc->dir_cookie, res); |
| 730 | return res; | 738 | return res; |
| @@ -759,13 +767,13 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
| 759 | goto out; | 767 | goto out; |
| 760 | } | 768 | } |
| 761 | 769 | ||
| 762 | if (nfs_readdir_xdr_to_array(desc, page, inode) == -1) { | ||
| 763 | status = -EIO; | ||
| 764 | goto out_release; | ||
| 765 | } | ||
| 766 | |||
| 767 | desc->page_index = 0; | 770 | desc->page_index = 0; |
| 768 | desc->page = page; | 771 | desc->page = page; |
| 772 | |||
| 773 | status = nfs_readdir_xdr_to_array(desc, page, inode); | ||
| 774 | if (status < 0) | ||
| 775 | goto out_release; | ||
| 776 | |||
| 769 | status = nfs_do_filldir(desc, dirent, filldir); | 777 | status = nfs_do_filldir(desc, dirent, filldir); |
| 770 | 778 | ||
| 771 | out: | 779 | out: |
| @@ -816,14 +824,14 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 816 | res = readdir_search_pagecache(desc); | 824 | res = readdir_search_pagecache(desc); |
| 817 | 825 | ||
| 818 | if (res == -EBADCOOKIE) { | 826 | if (res == -EBADCOOKIE) { |
| 827 | res = 0; | ||
| 819 | /* This means either end of directory */ | 828 | /* This means either end of directory */ |
| 820 | if (*desc->dir_cookie && desc->eof == 0) { | 829 | if (*desc->dir_cookie && desc->eof == 0) { |
| 821 | /* Or that the server has 'lost' a cookie */ | 830 | /* Or that the server has 'lost' a cookie */ |
| 822 | res = uncached_readdir(desc, dirent, filldir); | 831 | res = uncached_readdir(desc, dirent, filldir); |
| 823 | if (res >= 0) | 832 | if (res == 0) |
| 824 | continue; | 833 | continue; |
| 825 | } | 834 | } |
| 826 | res = 0; | ||
| 827 | break; | 835 | break; |
| 828 | } | 836 | } |
| 829 | if (res == -ETOOSMALL && desc->plus) { | 837 | if (res == -ETOOSMALL && desc->plus) { |
| @@ -838,10 +846,8 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 838 | break; | 846 | break; |
| 839 | 847 | ||
| 840 | res = nfs_do_filldir(desc, dirent, filldir); | 848 | res = nfs_do_filldir(desc, dirent, filldir); |
| 841 | if (res < 0) { | 849 | if (res < 0) |
| 842 | res = 0; | ||
| 843 | break; | 850 | break; |
| 844 | } | ||
| 845 | } | 851 | } |
| 846 | out: | 852 | out: |
| 847 | nfs_unblock_sillyrename(dentry); | 853 | nfs_unblock_sillyrename(dentry); |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 84d3c8b90206..e6ace0d93c71 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
| @@ -867,7 +867,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 867 | goto out; | 867 | goto out; |
| 868 | nfs_alloc_commit_data(dreq); | 868 | nfs_alloc_commit_data(dreq); |
| 869 | 869 | ||
| 870 | if (dreq->commit_data == NULL || count < wsize) | 870 | if (dreq->commit_data == NULL || count <= wsize) |
| 871 | sync = NFS_FILE_SYNC; | 871 | sync = NFS_FILE_SYNC; |
| 872 | 872 | ||
| 873 | dreq->inode = inode; | 873 | dreq->inode = inode; |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index db08ff3ff454..e6356b750b77 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
| @@ -362,6 +362,15 @@ unsigned int nfs_page_length(struct page *page) | |||
| 362 | } | 362 | } |
| 363 | 363 | ||
| 364 | /* | 364 | /* |
| 365 | * Convert a umode to a dirent->d_type | ||
| 366 | */ | ||
| 367 | static inline | ||
| 368 | unsigned char nfs_umode_to_dtype(umode_t mode) | ||
| 369 | { | ||
| 370 | return (mode >> 12) & 15; | ||
| 371 | } | ||
| 372 | |||
| 373 | /* | ||
| 365 | * Determine the number of pages in an array of length 'len' and | 374 | * Determine the number of pages in an array of length 'len' and |
| 366 | * with a base offset of 'base' | 375 | * with a base offset of 'base' |
| 367 | */ | 376 | */ |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 2563f765c9b4..5914a1911c95 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
| @@ -485,6 +485,8 @@ nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_se | |||
| 485 | entry->prev_cookie = entry->cookie; | 485 | entry->prev_cookie = entry->cookie; |
| 486 | entry->cookie = ntohl(*p++); | 486 | entry->cookie = ntohl(*p++); |
| 487 | 487 | ||
| 488 | entry->d_type = DT_UNKNOWN; | ||
| 489 | |||
| 488 | p = xdr_inline_peek(xdr, 8); | 490 | p = xdr_inline_peek(xdr, 8); |
| 489 | if (p != NULL) | 491 | if (p != NULL) |
| 490 | entry->eof = !p[0] && p[1]; | 492 | entry->eof = !p[0] && p[1]; |
| @@ -495,7 +497,7 @@ nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_se | |||
| 495 | 497 | ||
| 496 | out_overflow: | 498 | out_overflow: |
| 497 | print_overflow_msg(__func__, xdr); | 499 | print_overflow_msg(__func__, xdr); |
| 498 | return ERR_PTR(-EIO); | 500 | return ERR_PTR(-EAGAIN); |
| 499 | } | 501 | } |
| 500 | 502 | ||
| 501 | /* | 503 | /* |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 748dc91a4a14..f6cc60f06dac 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
| @@ -622,11 +622,13 @@ nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_s | |||
| 622 | entry->prev_cookie = entry->cookie; | 622 | entry->prev_cookie = entry->cookie; |
| 623 | p = xdr_decode_hyper(p, &entry->cookie); | 623 | p = xdr_decode_hyper(p, &entry->cookie); |
| 624 | 624 | ||
| 625 | entry->d_type = DT_UNKNOWN; | ||
| 625 | if (plus) { | 626 | if (plus) { |
| 626 | entry->fattr->valid = 0; | 627 | entry->fattr->valid = 0; |
| 627 | p = xdr_decode_post_op_attr_stream(xdr, entry->fattr); | 628 | p = xdr_decode_post_op_attr_stream(xdr, entry->fattr); |
| 628 | if (IS_ERR(p)) | 629 | if (IS_ERR(p)) |
| 629 | goto out_overflow_exit; | 630 | goto out_overflow_exit; |
| 631 | entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); | ||
| 630 | /* In fact, a post_op_fh3: */ | 632 | /* In fact, a post_op_fh3: */ |
| 631 | p = xdr_inline_decode(xdr, 4); | 633 | p = xdr_inline_decode(xdr, 4); |
| 632 | if (unlikely(!p)) | 634 | if (unlikely(!p)) |
| @@ -656,7 +658,7 @@ nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_s | |||
| 656 | out_overflow: | 658 | out_overflow: |
| 657 | print_overflow_msg(__func__, xdr); | 659 | print_overflow_msg(__func__, xdr); |
| 658 | out_overflow_exit: | 660 | out_overflow_exit: |
| 659 | return ERR_PTR(-EIO); | 661 | return ERR_PTR(-EAGAIN); |
| 660 | } | 662 | } |
| 661 | 663 | ||
| 662 | /* | 664 | /* |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index b7a204ff6fe1..9f1826b012e6 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -6208,6 +6208,10 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
| 6208 | if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) | 6208 | if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) |
| 6209 | entry->ino = entry->fattr->fileid; | 6209 | entry->ino = entry->fattr->fileid; |
| 6210 | 6210 | ||
| 6211 | entry->d_type = DT_UNKNOWN; | ||
| 6212 | if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE) | ||
| 6213 | entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); | ||
| 6214 | |||
| 6211 | if (verify_attr_len(xdr, p, len) < 0) | 6215 | if (verify_attr_len(xdr, p, len) < 0) |
| 6212 | goto out_overflow; | 6216 | goto out_overflow; |
| 6213 | 6217 | ||
| @@ -6221,7 +6225,7 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
| 6221 | 6225 | ||
| 6222 | out_overflow: | 6226 | out_overflow: |
| 6223 | print_overflow_msg(__func__, xdr); | 6227 | print_overflow_msg(__func__, xdr); |
| 6224 | return ERR_PTR(-EIO); | 6228 | return ERR_PTR(-EAGAIN); |
| 6225 | } | 6229 | } |
| 6226 | 6230 | ||
| 6227 | /* | 6231 | /* |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 49c844dab33a..59e5fe742f7b 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
| @@ -335,7 +335,7 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr) | |||
| 335 | * the device at this point. | 335 | * the device at this point. |
| 336 | * | 336 | * |
| 337 | * To prevent nilfs_dat_translate() from returning the | 337 | * To prevent nilfs_dat_translate() from returning the |
| 338 | * uncommited block number, this makes a copy of the entry | 338 | * uncommitted block number, this makes a copy of the entry |
| 339 | * buffer and redirects nilfs_dat_translate() to the copy. | 339 | * buffer and redirects nilfs_dat_translate() to the copy. |
| 340 | */ | 340 | */ |
| 341 | if (!buffer_nilfs_redirected(entry_bh)) { | 341 | if (!buffer_nilfs_redirected(entry_bh)) { |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 3e90f86d5bfe..e00d9457c256 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
| @@ -349,8 +349,8 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb, | |||
| 349 | ino = vdesc->vd_ino; | 349 | ino = vdesc->vd_ino; |
| 350 | cno = vdesc->vd_cno; | 350 | cno = vdesc->vd_cno; |
| 351 | inode = nilfs_iget_for_gc(sb, ino, cno); | 351 | inode = nilfs_iget_for_gc(sb, ino, cno); |
| 352 | if (unlikely(inode == NULL)) { | 352 | if (IS_ERR(inode)) { |
| 353 | ret = -ENOMEM; | 353 | ret = PTR_ERR(inode); |
| 354 | goto failed; | 354 | goto failed; |
| 355 | } | 355 | } |
| 356 | do { | 356 | do { |
| @@ -1199,12 +1199,24 @@ int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, | |||
| 1199 | return ret; | 1199 | return ret; |
| 1200 | } | 1200 | } |
| 1201 | 1201 | ||
| 1202 | /* | ||
| 1203 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same | ||
| 1204 | * location, so checking ->i_pipe is not enough to verify that this is a | ||
| 1205 | * pipe. | ||
| 1206 | */ | ||
| 1207 | struct pipe_inode_info *get_pipe_info(struct file *file) | ||
| 1208 | { | ||
| 1209 | struct inode *i = file->f_path.dentry->d_inode; | ||
| 1210 | |||
| 1211 | return S_ISFIFO(i->i_mode) ? i->i_pipe : NULL; | ||
| 1212 | } | ||
| 1213 | |||
| 1202 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | 1214 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) |
| 1203 | { | 1215 | { |
| 1204 | struct pipe_inode_info *pipe; | 1216 | struct pipe_inode_info *pipe; |
| 1205 | long ret; | 1217 | long ret; |
| 1206 | 1218 | ||
| 1207 | pipe = file->f_path.dentry->d_inode->i_pipe; | 1219 | pipe = get_pipe_info(file); |
| 1208 | if (!pipe) | 1220 | if (!pipe) |
| 1209 | return -EBADF; | 1221 | return -EBADF; |
| 1210 | 1222 | ||
diff --git a/fs/splice.c b/fs/splice.c index 8f1dfaecc8f0..ce2f02579e35 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -1311,18 +1311,6 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
| 1311 | static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, | 1311 | static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, |
| 1312 | struct pipe_inode_info *opipe, | 1312 | struct pipe_inode_info *opipe, |
| 1313 | size_t len, unsigned int flags); | 1313 | size_t len, unsigned int flags); |
| 1314 | /* | ||
| 1315 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same | ||
| 1316 | * location, so checking ->i_pipe is not enough to verify that this is a | ||
| 1317 | * pipe. | ||
| 1318 | */ | ||
| 1319 | static inline struct pipe_inode_info *pipe_info(struct inode *inode) | ||
| 1320 | { | ||
| 1321 | if (S_ISFIFO(inode->i_mode)) | ||
| 1322 | return inode->i_pipe; | ||
| 1323 | |||
| 1324 | return NULL; | ||
| 1325 | } | ||
| 1326 | 1314 | ||
| 1327 | /* | 1315 | /* |
| 1328 | * Determine where to splice to/from. | 1316 | * Determine where to splice to/from. |
| @@ -1336,8 +1324,8 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
| 1336 | loff_t offset, *off; | 1324 | loff_t offset, *off; |
| 1337 | long ret; | 1325 | long ret; |
| 1338 | 1326 | ||
| 1339 | ipipe = pipe_info(in->f_path.dentry->d_inode); | 1327 | ipipe = get_pipe_info(in); |
| 1340 | opipe = pipe_info(out->f_path.dentry->d_inode); | 1328 | opipe = get_pipe_info(out); |
| 1341 | 1329 | ||
| 1342 | if (ipipe && opipe) { | 1330 | if (ipipe && opipe) { |
| 1343 | if (off_in || off_out) | 1331 | if (off_in || off_out) |
| @@ -1555,7 +1543,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *iov, | |||
| 1555 | int error; | 1543 | int error; |
| 1556 | long ret; | 1544 | long ret; |
| 1557 | 1545 | ||
| 1558 | pipe = pipe_info(file->f_path.dentry->d_inode); | 1546 | pipe = get_pipe_info(file); |
| 1559 | if (!pipe) | 1547 | if (!pipe) |
| 1560 | return -EBADF; | 1548 | return -EBADF; |
| 1561 | 1549 | ||
| @@ -1642,7 +1630,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, | |||
| 1642 | }; | 1630 | }; |
| 1643 | long ret; | 1631 | long ret; |
| 1644 | 1632 | ||
| 1645 | pipe = pipe_info(file->f_path.dentry->d_inode); | 1633 | pipe = get_pipe_info(file); |
| 1646 | if (!pipe) | 1634 | if (!pipe) |
| 1647 | return -EBADF; | 1635 | return -EBADF; |
| 1648 | 1636 | ||
| @@ -2022,8 +2010,8 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
| 2022 | static long do_tee(struct file *in, struct file *out, size_t len, | 2010 | static long do_tee(struct file *in, struct file *out, size_t len, |
| 2023 | unsigned int flags) | 2011 | unsigned int flags) |
| 2024 | { | 2012 | { |
| 2025 | struct pipe_inode_info *ipipe = pipe_info(in->f_path.dentry->d_inode); | 2013 | struct pipe_inode_info *ipipe = get_pipe_info(in); |
| 2026 | struct pipe_inode_info *opipe = pipe_info(out->f_path.dentry->d_inode); | 2014 | struct pipe_inode_info *opipe = get_pipe_info(out); |
| 2027 | int ret = -EINVAL; | 2015 | int ret = -EINVAL; |
| 2028 | 2016 | ||
| 2029 | /* | 2017 | /* |
