xfs: fixes for 3.10-rc3
- Fix for corruption with FSX on 512 byte blocksize filesystems - Fix rounding error in xfs_free_file_space - Fix use-after-free with extent free intents - Add several missing KM_NOFS flags to fix lockdep reports - Several fixes for CRC related code -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIcBAABAgAGBQJRn93mAAoJENaLyazVq6ZOPw8P/1ab7Gr4K7ccpuRvC+JiBPx9 /Eb1l2A68r8rWJq3bEvLM/XgN7F0IESastS+iA8lrNuLWJAHCb+Y37mdbyWymhWO J6LFg/Mic+n5uGmg6nXrqLJ8epTd3L+V+cCEHLpa/20zEwa5yd8sSTV0P1pfcMRi S36Uof7boe+s4H/s2z4YX8Y+dkaVn1tN7j4PDs5Zd/wiUq0EKA5le4AkbqIJlCDn E9mJL1S2t3QwfgQWL+pe8f5jzReGTAxJUQWX2ErajX4vYI7PnR1WTYf7YJB291f0 XPfkjqvaK0WCdipSkgb58t/Rj2IxoHItdryvBHa/rnL4e95aBQMpNyY8btNX28ou NgcIQnqQB+xlJeHpSyb1xNusamGzWw0CEYsXPcDQbXj1uJjd7/GfqTwtVbB4zOlW Hua7/6N22vaY1dfQcQFwgi1XcKF9jSVKBVOvy7yHEmdNuT7mFejaG1gVO7NpTIgd s7R91pQVlYpLTmZHK6ZqZap5OC6kS/YJr9HxVxS3FQhaJmFwGqvf6UUjSWOK1MnJ obTbbygo2Orvh10lgzDNsd+xRJZ9aFn+UfywSeQGTfm91HvTnEQje3xqctv3zmBy adrWSXXg/eN07nciNk0zTgHnQZo1v/ZeAFlz0AcSslMMQ7Pq4+Pv4LPtdxMIdrxU 1IZ32GunGTUXqm6GRW6v =hQCM -----END PGP SIGNATURE----- Merge tag 'for-linus-v3.10-rc3' of git://oss.sgi.com/xfs/xfs Pull xfs fixes from Ben Myers: "Here are fixes for corruption on 512 byte filesystems, a rounding error, a use-after-free, some flags to fix lockdep reports, and several fixes related to CRCs. We have a somewhat larger post -rc1 queue than usual due to fixes related to the CRC feature we merged for 3.10: - Fix for corruption with FSX on 512 byte blocksize filesystems - Fix rounding error in xfs_free_file_space - Fix use-after-free with extent free intents - Add several missing KM_NOFS flags to fix lockdep reports - Several fixes for CRC related code" * tag 'for-linus-v3.10-rc3' of git://oss.sgi.com/xfs/xfs: xfs: remote attribute lookups require the value length xfs: xfs_attr_shortform_allfit() does not handle attr3 format. xfs: xfs_da3_node_read_verify() doesn't handle XFS_ATTR3_LEAF_MAGIC xfs: fix missing KM_NOFS tags to keep lockdep happy xfs: Don't reference the EFI after it is freed xfs: fix rounding in xfs_free_file_space xfs: fix sub-page blocksize data integrity writes
This commit is contained in:
Коммит
088d812fe9
|
@ -725,6 +725,25 @@ xfs_convert_page(
|
|||
(xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
|
||||
i_size_read(inode));
|
||||
|
||||
/*
|
||||
* If the current map does not span the entire page we are about to try
|
||||
* to write, then give up. The only way we can write a page that spans
|
||||
* multiple mappings in a single writeback iteration is via the
|
||||
* xfs_vm_writepage() function. Data integrity writeback requires the
|
||||
* entire page to be written in a single attempt, otherwise the part of
|
||||
* the page we don't write here doesn't get written as part of the data
|
||||
* integrity sync.
|
||||
*
|
||||
* For normal writeback, we also don't attempt to write partial pages
|
||||
* here as it simply means that write_cache_pages() will see it under
|
||||
* writeback and ignore the page until some point in the future, at
|
||||
* which time this will be the only page in the file that needs
|
||||
* writeback. Hence for more optimal IO patterns, we should always
|
||||
* avoid partial page writeback due to multiple mappings on a page here.
|
||||
*/
|
||||
if (!xfs_imap_valid(inode, imap, end_offset))
|
||||
goto fail_unlock_page;
|
||||
|
||||
len = 1 << inode->i_blkbits;
|
||||
p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),
|
||||
PAGE_CACHE_SIZE);
|
||||
|
|
|
@ -931,20 +931,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
|
|||
*/
|
||||
int
|
||||
xfs_attr_shortform_allfit(
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_inode *dp)
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_inode *dp)
|
||||
{
|
||||
xfs_attr_leafblock_t *leaf;
|
||||
xfs_attr_leaf_entry_t *entry;
|
||||
struct xfs_attr_leafblock *leaf;
|
||||
struct xfs_attr_leaf_entry *entry;
|
||||
xfs_attr_leaf_name_local_t *name_loc;
|
||||
int bytes, i;
|
||||
struct xfs_attr3_icleaf_hdr leafhdr;
|
||||
int bytes;
|
||||
int i;
|
||||
|
||||
leaf = bp->b_addr;
|
||||
ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
|
||||
xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
entry = xfs_attr3_leaf_entryp(leaf);
|
||||
|
||||
entry = &leaf->entries[0];
|
||||
bytes = sizeof(struct xfs_attr_sf_hdr);
|
||||
for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
|
||||
for (i = 0; i < leafhdr.count; entry++, i++) {
|
||||
if (entry->flags & XFS_ATTR_INCOMPLETE)
|
||||
continue; /* don't copy partial entries */
|
||||
if (!(entry->flags & XFS_ATTR_LOCAL))
|
||||
|
@ -954,15 +956,15 @@ xfs_attr_shortform_allfit(
|
|||
return(0);
|
||||
if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
|
||||
return(0);
|
||||
bytes += sizeof(struct xfs_attr_sf_entry)-1
|
||||
bytes += sizeof(struct xfs_attr_sf_entry) - 1
|
||||
+ name_loc->namelen
|
||||
+ be16_to_cpu(name_loc->valuelen);
|
||||
}
|
||||
if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
|
||||
(dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
|
||||
(bytes == sizeof(struct xfs_attr_sf_hdr)))
|
||||
return(-1);
|
||||
return(xfs_attr_shortform_bytesfit(dp, bytes));
|
||||
return -1;
|
||||
return xfs_attr_shortform_bytesfit(dp, bytes);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2330,9 +2332,10 @@ xfs_attr3_leaf_lookup_int(
|
|||
if (!xfs_attr_namesp_match(args->flags, entry->flags))
|
||||
continue;
|
||||
args->index = probe;
|
||||
args->valuelen = be32_to_cpu(name_rmt->valuelen);
|
||||
args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
|
||||
args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount,
|
||||
be32_to_cpu(name_rmt->valuelen));
|
||||
args->valuelen);
|
||||
return XFS_ERROR(EEXIST);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1649,7 +1649,7 @@ xfs_alloc_buftarg(
|
|||
{
|
||||
xfs_buftarg_t *btp;
|
||||
|
||||
btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
|
||||
btp = kmem_zalloc(sizeof(*btp), KM_SLEEP | KM_NOFS);
|
||||
|
||||
btp->bt_mount = mp;
|
||||
btp->bt_dev = bdev->bd_dev;
|
||||
|
|
|
@ -270,6 +270,7 @@ xfs_da3_node_read_verify(
|
|||
break;
|
||||
return;
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
case XFS_ATTR3_LEAF_MAGIC:
|
||||
bp->b_ops = &xfs_attr3_leaf_buf_ops;
|
||||
bp->b_ops->verify_read(bp);
|
||||
return;
|
||||
|
@ -2464,7 +2465,8 @@ xfs_buf_map_from_irec(
|
|||
ASSERT(nirecs >= 1);
|
||||
|
||||
if (nirecs > 1) {
|
||||
map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP);
|
||||
map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map),
|
||||
KM_SLEEP | KM_NOFS);
|
||||
if (!map)
|
||||
return ENOMEM;
|
||||
*mapp = map;
|
||||
|
@ -2520,7 +2522,8 @@ xfs_dabuf_map(
|
|||
* Optimize the one-block case.
|
||||
*/
|
||||
if (nfsb != 1)
|
||||
irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP);
|
||||
irecs = kmem_zalloc(sizeof(irec) * nfsb,
|
||||
KM_SLEEP | KM_NOFS);
|
||||
|
||||
nirecs = nfsb;
|
||||
error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs,
|
||||
|
|
|
@ -1336,7 +1336,7 @@ xfs_dir2_leaf_getdents(
|
|||
mp->m_sb.sb_blocksize);
|
||||
map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
|
||||
(length * sizeof(struct xfs_bmbt_irec)),
|
||||
KM_SLEEP);
|
||||
KM_SLEEP | KM_NOFS);
|
||||
map_info->map_size = length;
|
||||
|
||||
/*
|
||||
|
|
|
@ -305,11 +305,12 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
|
|||
{
|
||||
ASSERT(atomic_read(&efip->efi_next_extent) >= nextents);
|
||||
if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) {
|
||||
__xfs_efi_release(efip);
|
||||
|
||||
/* recovery needs us to drop the EFI reference, too */
|
||||
if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))
|
||||
__xfs_efi_release(efip);
|
||||
|
||||
__xfs_efi_release(efip);
|
||||
/* efip may now have been freed, do not reference it again. */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ xlog_cil_prepare_log_vecs(
|
|||
|
||||
new_lv = kmem_zalloc(sizeof(*new_lv) +
|
||||
niovecs * sizeof(struct xfs_log_iovec),
|
||||
KM_SLEEP);
|
||||
KM_SLEEP|KM_NOFS);
|
||||
|
||||
/* The allocated iovec region lies beyond the log vector. */
|
||||
new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1];
|
||||
|
|
|
@ -1453,7 +1453,7 @@ xfs_free_file_space(
|
|||
xfs_mount_t *mp;
|
||||
int nimap;
|
||||
uint resblks;
|
||||
uint rounding;
|
||||
xfs_off_t rounding;
|
||||
int rt;
|
||||
xfs_fileoff_t startoffset_fsb;
|
||||
xfs_trans_t *tp;
|
||||
|
@ -1482,7 +1482,7 @@ xfs_free_file_space(
|
|||
inode_dio_wait(VFS_I(ip));
|
||||
}
|
||||
|
||||
rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
|
||||
rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
|
||||
ioffset = offset & ~(rounding - 1);
|
||||
error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
|
||||
ioffset, -1);
|
||||
|
|
Загрузка…
Ссылка в новой задаче