diff options
| -rw-r--r-- | fs/xfs/xfs_aops.c | 19 | ||||
| -rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 27 | ||||
| -rw-r--r-- | fs/xfs/xfs_buf.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_da_btree.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_extfree_item.c | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_cil.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 4 |
8 files changed, 47 insertions, 21 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 2b2691b73428..41a695048be7 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
| @@ -725,6 +725,25 @@ xfs_convert_page( | |||
| 725 | (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, | 725 | (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, |
| 726 | i_size_read(inode)); | 726 | i_size_read(inode)); |
| 727 | 727 | ||
| 728 | /* | ||
| 729 | * If the current map does not span the entire page we are about to try | ||
| 730 | * to write, then give up. The only way we can write a page that spans | ||
| 731 | * multiple mappings in a single writeback iteration is via the | ||
| 732 | * xfs_vm_writepage() function. Data integrity writeback requires the | ||
| 733 | * entire page to be written in a single attempt, otherwise the part of | ||
| 734 | * the page we don't write here doesn't get written as part of the data | ||
| 735 | * integrity sync. | ||
| 736 | * | ||
| 737 | * For normal writeback, we also don't attempt to write partial pages | ||
| 738 | * here as it simply means that write_cache_pages() will see it under | ||
| 739 | * writeback and ignore the page until some point in the future, at | ||
| 740 | * which time this will be the only page in the file that needs | ||
| 741 | * writeback. Hence for more optimal IO patterns, we should always | ||
| 742 | * avoid partial page writeback due to multiple mappings on a page here. | ||
| 743 | */ | ||
| 744 | if (!xfs_imap_valid(inode, imap, end_offset)) | ||
| 745 | goto fail_unlock_page; | ||
| 746 | |||
| 728 | len = 1 << inode->i_blkbits; | 747 | len = 1 << inode->i_blkbits; |
| 729 | p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1), | 748 | p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1), |
| 730 | PAGE_CACHE_SIZE); | 749 | PAGE_CACHE_SIZE); |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 08d5457c948e..0bce1b348580 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
| @@ -931,20 +931,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) | |||
| 931 | */ | 931 | */ |
| 932 | int | 932 | int |
| 933 | xfs_attr_shortform_allfit( | 933 | xfs_attr_shortform_allfit( |
| 934 | struct xfs_buf *bp, | 934 | struct xfs_buf *bp, |
| 935 | struct xfs_inode *dp) | 935 | struct xfs_inode *dp) |
| 936 | { | 936 | { |
| 937 | xfs_attr_leafblock_t *leaf; | 937 | struct xfs_attr_leafblock *leaf; |
| 938 | xfs_attr_leaf_entry_t *entry; | 938 | struct xfs_attr_leaf_entry *entry; |
| 939 | xfs_attr_leaf_name_local_t *name_loc; | 939 | xfs_attr_leaf_name_local_t *name_loc; |
| 940 | int bytes, i; | 940 | struct xfs_attr3_icleaf_hdr leafhdr; |
| 941 | int bytes; | ||
| 942 | int i; | ||
| 941 | 943 | ||
| 942 | leaf = bp->b_addr; | 944 | leaf = bp->b_addr; |
| 943 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 945 | xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); |
| 946 | entry = xfs_attr3_leaf_entryp(leaf); | ||
| 944 | 947 | ||
| 945 | entry = &leaf->entries[0]; | ||
| 946 | bytes = sizeof(struct xfs_attr_sf_hdr); | 948 | bytes = sizeof(struct xfs_attr_sf_hdr); |
| 947 | for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { | 949 | for (i = 0; i < leafhdr.count; entry++, i++) { |
| 948 | if (entry->flags & XFS_ATTR_INCOMPLETE) | 950 | if (entry->flags & XFS_ATTR_INCOMPLETE) |
| 949 | continue; /* don't copy partial entries */ | 951 | continue; /* don't copy partial entries */ |
| 950 | if (!(entry->flags & XFS_ATTR_LOCAL)) | 952 | if (!(entry->flags & XFS_ATTR_LOCAL)) |
| @@ -954,15 +956,15 @@ xfs_attr_shortform_allfit( | |||
| 954 | return(0); | 956 | return(0); |
| 955 | if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) | 957 | if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) |
| 956 | return(0); | 958 | return(0); |
| 957 | bytes += sizeof(struct xfs_attr_sf_entry)-1 | 959 | bytes += sizeof(struct xfs_attr_sf_entry) - 1 |
| 958 | + name_loc->namelen | 960 | + name_loc->namelen |
| 959 | + be16_to_cpu(name_loc->valuelen); | 961 | + be16_to_cpu(name_loc->valuelen); |
| 960 | } | 962 | } |
| 961 | if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && | 963 | if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && |
| 962 | (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && | 964 | (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && |
| 963 | (bytes == sizeof(struct xfs_attr_sf_hdr))) | 965 | (bytes == sizeof(struct xfs_attr_sf_hdr))) |
| 964 | return(-1); | 966 | return -1; |
| 965 | return(xfs_attr_shortform_bytesfit(dp, bytes)); | 967 | return xfs_attr_shortform_bytesfit(dp, bytes); |
| 966 | } | 968 | } |
| 967 | 969 | ||
| 968 | /* | 970 | /* |
| @@ -2330,9 +2332,10 @@ xfs_attr3_leaf_lookup_int( | |||
| 2330 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) | 2332 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) |
| 2331 | continue; | 2333 | continue; |
| 2332 | args->index = probe; | 2334 | args->index = probe; |
| 2335 | args->valuelen = be32_to_cpu(name_rmt->valuelen); | ||
| 2333 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); | 2336 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
| 2334 | args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, | 2337 | args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, |
| 2335 | be32_to_cpu(name_rmt->valuelen)); | 2338 | args->valuelen); |
| 2336 | return XFS_ERROR(EEXIST); | 2339 | return XFS_ERROR(EEXIST); |
| 2337 | } | 2340 | } |
| 2338 | } | 2341 | } |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 82b70bda9f47..0d2554299688 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
| @@ -1649,7 +1649,7 @@ xfs_alloc_buftarg( | |||
| 1649 | { | 1649 | { |
| 1650 | xfs_buftarg_t *btp; | 1650 | xfs_buftarg_t *btp; |
| 1651 | 1651 | ||
| 1652 | btp = kmem_zalloc(sizeof(*btp), KM_SLEEP); | 1652 | btp = kmem_zalloc(sizeof(*btp), KM_SLEEP | KM_NOFS); |
| 1653 | 1653 | ||
| 1654 | btp->bt_mount = mp; | 1654 | btp->bt_mount = mp; |
| 1655 | btp->bt_dev = bdev->bd_dev; | 1655 | btp->bt_dev = bdev->bd_dev; |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 9b26a99ebfe9..0b8b2a13cd24 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
| @@ -270,6 +270,7 @@ xfs_da3_node_read_verify( | |||
| 270 | break; | 270 | break; |
| 271 | return; | 271 | return; |
| 272 | case XFS_ATTR_LEAF_MAGIC: | 272 | case XFS_ATTR_LEAF_MAGIC: |
| 273 | case XFS_ATTR3_LEAF_MAGIC: | ||
| 273 | bp->b_ops = &xfs_attr3_leaf_buf_ops; | 274 | bp->b_ops = &xfs_attr3_leaf_buf_ops; |
| 274 | bp->b_ops->verify_read(bp); | 275 | bp->b_ops->verify_read(bp); |
| 275 | return; | 276 | return; |
| @@ -2464,7 +2465,8 @@ xfs_buf_map_from_irec( | |||
| 2464 | ASSERT(nirecs >= 1); | 2465 | ASSERT(nirecs >= 1); |
| 2465 | 2466 | ||
| 2466 | if (nirecs > 1) { | 2467 | if (nirecs > 1) { |
| 2467 | map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP); | 2468 | map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), |
| 2469 | KM_SLEEP | KM_NOFS); | ||
| 2468 | if (!map) | 2470 | if (!map) |
| 2469 | return ENOMEM; | 2471 | return ENOMEM; |
| 2470 | *mapp = map; | 2472 | *mapp = map; |
| @@ -2520,7 +2522,8 @@ xfs_dabuf_map( | |||
| 2520 | * Optimize the one-block case. | 2522 | * Optimize the one-block case. |
| 2521 | */ | 2523 | */ |
| 2522 | if (nfsb != 1) | 2524 | if (nfsb != 1) |
| 2523 | irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP); | 2525 | irecs = kmem_zalloc(sizeof(irec) * nfsb, |
| 2526 | KM_SLEEP | KM_NOFS); | ||
| 2524 | 2527 | ||
| 2525 | nirecs = nfsb; | 2528 | nirecs = nfsb; |
| 2526 | error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, | 2529 | error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 721ba2fe8e54..da71a1819d78 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
| @@ -1336,7 +1336,7 @@ xfs_dir2_leaf_getdents( | |||
| 1336 | mp->m_sb.sb_blocksize); | 1336 | mp->m_sb.sb_blocksize); |
| 1337 | map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) + | 1337 | map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) + |
| 1338 | (length * sizeof(struct xfs_bmbt_irec)), | 1338 | (length * sizeof(struct xfs_bmbt_irec)), |
| 1339 | KM_SLEEP); | 1339 | KM_SLEEP | KM_NOFS); |
| 1340 | map_info->map_size = length; | 1340 | map_info->map_size = length; |
| 1341 | 1341 | ||
| 1342 | /* | 1342 | /* |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index c0f375087efc..452920a3f03f 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
| @@ -305,11 +305,12 @@ xfs_efi_release(xfs_efi_log_item_t *efip, | |||
| 305 | { | 305 | { |
| 306 | ASSERT(atomic_read(&efip->efi_next_extent) >= nextents); | 306 | ASSERT(atomic_read(&efip->efi_next_extent) >= nextents); |
| 307 | if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) { | 307 | if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) { |
| 308 | __xfs_efi_release(efip); | ||
| 309 | |||
| 310 | /* recovery needs us to drop the EFI reference, too */ | 308 | /* recovery needs us to drop the EFI reference, too */ |
| 311 | if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)) | 309 | if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)) |
| 312 | __xfs_efi_release(efip); | 310 | __xfs_efi_release(efip); |
| 311 | |||
| 312 | __xfs_efi_release(efip); | ||
| 313 | /* efip may now have been freed, do not reference it again. */ | ||
| 313 | } | 314 | } |
| 314 | } | 315 | } |
| 315 | 316 | ||
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index e3d0b85d852b..d0833b54e55d 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
| @@ -139,7 +139,7 @@ xlog_cil_prepare_log_vecs( | |||
| 139 | 139 | ||
| 140 | new_lv = kmem_zalloc(sizeof(*new_lv) + | 140 | new_lv = kmem_zalloc(sizeof(*new_lv) + |
| 141 | niovecs * sizeof(struct xfs_log_iovec), | 141 | niovecs * sizeof(struct xfs_log_iovec), |
| 142 | KM_SLEEP); | 142 | KM_SLEEP|KM_NOFS); |
| 143 | 143 | ||
| 144 | /* The allocated iovec region lies beyond the log vector. */ | 144 | /* The allocated iovec region lies beyond the log vector. */ |
| 145 | new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1]; | 145 | new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1]; |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 1501f4fa51a6..0176bb21f09a 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -1453,7 +1453,7 @@ xfs_free_file_space( | |||
| 1453 | xfs_mount_t *mp; | 1453 | xfs_mount_t *mp; |
| 1454 | int nimap; | 1454 | int nimap; |
| 1455 | uint resblks; | 1455 | uint resblks; |
| 1456 | uint rounding; | 1456 | xfs_off_t rounding; |
| 1457 | int rt; | 1457 | int rt; |
| 1458 | xfs_fileoff_t startoffset_fsb; | 1458 | xfs_fileoff_t startoffset_fsb; |
| 1459 | xfs_trans_t *tp; | 1459 | xfs_trans_t *tp; |
| @@ -1482,7 +1482,7 @@ xfs_free_file_space( | |||
| 1482 | inode_dio_wait(VFS_I(ip)); | 1482 | inode_dio_wait(VFS_I(ip)); |
| 1483 | } | 1483 | } |
| 1484 | 1484 | ||
| 1485 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); | 1485 | rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); |
| 1486 | ioffset = offset & ~(rounding - 1); | 1486 | ioffset = offset & ~(rounding - 1); |
| 1487 | error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, | 1487 | error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, |
| 1488 | ioffset, -1); | 1488 | ioffset, -1); |
