Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'xfs-4.12-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull XFS fixes from Darrick Wong:
"A few miscellaneous bug fixes & cleanups:

- Fix indlen block reservation accounting bug when splitting delalloc
extent

- Fix warnings about unused variables that appeared in -rc1.

- Don't spew errors when bmapping a local format directory

- Fix an off-by-one error in a delalloc eof assertion

- Make fsmap only return inode information for CAP_SYS_ADMIN

- Fix a potential mount time deadlock recovering cow extents

- Fix unaligned memory access in _btree_visit_blocks

- Fix various SEEK_HOLE/SEEK_DATA bugs"

* tag 'xfs-4.12-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: Move handling of missing page into one place in xfs_find_get_desired_pgoff()
xfs: Fix off-by-in in loop termination in xfs_find_get_desired_pgoff()
xfs: Fix missed holes in SEEK_HOLE implementation
xfs: fix off-by-one on max nr_pages in xfs_find_get_desired_pgoff()
xfs: fix unaligned access in xfs_btree_visit_blocks
xfs: avoid mount-time deadlock in CoW extent recovery
xfs: only return detailed fsmap info if the caller has CAP_SYS_ADMIN
xfs: bad assertion for delalloc an extent that start at i_size
xfs: fix warnings about unused stack variables
xfs: BMAPX shouldn't barf on inline-format directories
xfs: fix indlen accounting error on partial delalloc conversion

+66 -74
+4 -5
fs/xfs/libxfs/xfs_bmap.c
··· 1280 1280 xfs_bmbt_rec_t *frp; 1281 1281 xfs_fsblock_t nextbno; 1282 1282 xfs_extnum_t num_recs; 1283 - xfs_extnum_t start; 1284 1283 1285 1284 num_recs = xfs_btree_get_numrecs(block); 1286 1285 if (unlikely(i + num_recs > room)) { ··· 1302 1303 * Copy records into the extent records. 1303 1304 */ 1304 1305 frp = XFS_BMBT_REC_ADDR(mp, block, 1); 1305 - start = i; 1306 1306 for (j = 0; j < num_recs; j++, i++, frp++) { 1307 1307 xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i); 1308 1308 trp->l0 = be64_to_cpu(frp->l0); ··· 2063 2065 } 2064 2066 temp = xfs_bmap_worst_indlen(bma->ip, temp); 2065 2067 temp2 = xfs_bmap_worst_indlen(bma->ip, temp2); 2066 - diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - 2067 - (bma->cur ? bma->cur->bc_private.b.allocated : 0)); 2068 + diff = (int)(temp + temp2 - 2069 + (startblockval(PREV.br_startblock) - 2070 + (bma->cur ? 2071 + bma->cur->bc_private.b.allocated : 0))); 2068 2072 if (diff > 0) { 2069 2073 error = xfs_mod_fdblocks(bma->ip->i_mount, 2070 2074 -((int64_t)diff), false); ··· 2123 2123 temp = da_new; 2124 2124 if (bma->cur) 2125 2125 temp += bma->cur->bc_private.b.allocated; 2126 - ASSERT(temp <= da_old); 2127 2126 if (temp < da_old) 2128 2127 xfs_mod_fdblocks(bma->ip->i_mount, 2129 2128 (int64_t)(da_old - temp), false);
+1 -1
fs/xfs/libxfs/xfs_btree.c
··· 4395 4395 xfs_btree_readahead_ptr(cur, ptr, 1); 4396 4396 4397 4397 /* save for the next iteration of the loop */ 4398 - lptr = *ptr; 4398 + xfs_btree_copy_ptrs(cur, &lptr, ptr, 1); 4399 4399 } 4400 4400 4401 4401 /* for each buffer in the level */
+31 -12
fs/xfs/libxfs/xfs_refcount.c
··· 1629 1629 if (mp->m_sb.sb_agblocks >= XFS_REFC_COW_START) 1630 1630 return -EOPNOTSUPP; 1631 1631 1632 - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); 1632 + INIT_LIST_HEAD(&debris); 1633 + 1634 + /* 1635 + * In this first part, we use an empty transaction to gather up 1636 + * all the leftover CoW extents so that we can subsequently 1637 + * delete them. The empty transaction is used to avoid 1638 + * a buffer lock deadlock if there happens to be a loop in the 1639 + * refcountbt because we're allowed to re-grab a buffer that is 1640 + * already attached to our transaction. When we're done 1641 + * recording the CoW debris we cancel the (empty) transaction 1642 + * and everything goes away cleanly. 1643 + */ 1644 + error = xfs_trans_alloc_empty(mp, &tp); 1633 1645 if (error) 1634 1646 return error; 1635 - cur = xfs_refcountbt_init_cursor(mp, NULL, agbp, agno, NULL); 1647 + 1648 + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); 1649 + if (error) 1650 + goto out_trans; 1651 + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL); 1636 1652 1637 1653 /* Find all the leftover CoW staging extents. */ 1638 - INIT_LIST_HEAD(&debris); 1639 1654 memset(&low, 0, sizeof(low)); 1640 1655 memset(&high, 0, sizeof(high)); 1641 1656 low.rc.rc_startblock = XFS_REFC_COW_START; ··· 1660 1645 if (error) 1661 1646 goto out_cursor; 1662 1647 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1663 - xfs_buf_relse(agbp); 1648 + xfs_trans_brelse(tp, agbp); 1649 + xfs_trans_cancel(tp); 1664 1650 1665 1651 /* Now iterate the list to free the leftovers */ 1666 - list_for_each_entry(rr, &debris, rr_list) { 1652 + list_for_each_entry_safe(rr, n, &debris, rr_list) { 1667 1653 /* Set up transaction. */ 1668 1654 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp); 1669 1655 if (error) ··· 1692 1676 error = xfs_trans_commit(tp); 1693 1677 if (error) 1694 1678 goto out_free; 1679 + 1680 + list_del(&rr->rr_list); 1681 + kmem_free(rr); 1695 1682 } 1696 1683 1684 + return error; 1685 + out_defer: 1686 + xfs_defer_cancel(&dfops); 1687 + out_trans: 1688 + xfs_trans_cancel(tp); 1697 1689 out_free: 1698 1690 /* Free the leftover list */ 1699 1691 list_for_each_entry_safe(rr, n, &debris, rr_list) { ··· 1712 1688 1713 1689 out_cursor: 1714 1690 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); 1715 - xfs_buf_relse(agbp); 1716 - goto out_free; 1717 - 1718 - out_defer: 1719 - xfs_defer_cancel(&dfops); 1720 - xfs_trans_cancel(tp); 1721 - goto out_free; 1691 + xfs_trans_brelse(tp, agbp); 1692 + goto out_trans; 1722 1693 }
+7 -3
fs/xfs/xfs_bmap_util.c
··· 582 582 } 583 583 break; 584 584 default: 585 + /* Local format data forks report no extents. */ 586 + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { 587 + bmv->bmv_entries = 0; 588 + return 0; 589 + } 585 590 if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && 586 - ip->i_d.di_format != XFS_DINODE_FMT_BTREE && 587 - ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) 591 + ip->i_d.di_format != XFS_DINODE_FMT_BTREE) 588 592 return -EINVAL; 589 593 590 594 if (xfs_get_extsz_hint(ip) || ··· 716 712 * extents. 717 713 */ 718 714 if (map[i].br_startblock == DELAYSTARTBLOCK && 719 - map[i].br_startoff <= XFS_B_TO_FSB(mp, XFS_ISIZE(ip))) 715 + map[i].br_startoff < XFS_B_TO_FSB(mp, XFS_ISIZE(ip))) 720 716 ASSERT((iflags & BMV_IF_DELALLOC) != 0); 721 717 722 718 if (map[i].br_startblock == HOLESTARTBLOCK &&
+19 -52
fs/xfs/xfs_file.c
··· 1043 1043 1044 1044 index = startoff >> PAGE_SHIFT; 1045 1045 endoff = XFS_FSB_TO_B(mp, map->br_startoff + map->br_blockcount); 1046 - end = endoff >> PAGE_SHIFT; 1046 + end = (endoff - 1) >> PAGE_SHIFT; 1047 1047 do { 1048 1048 int want; 1049 1049 unsigned nr_pages; 1050 1050 unsigned int i; 1051 1051 1052 - want = min_t(pgoff_t, end - index, PAGEVEC_SIZE); 1052 + want = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1; 1053 1053 nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index, 1054 1054 want); 1055 - /* 1056 - * No page mapped into given range. If we are searching holes 1057 - * and if this is the first time we got into the loop, it means 1058 - * that the given offset is landed in a hole, return it. 1059 - * 1060 - * If we have already stepped through some block buffers to find 1061 - * holes but they all contains data. In this case, the last 1062 - * offset is already updated and pointed to the end of the last 1063 - * mapped page, if it does not reach the endpoint to search, 1064 - * that means there should be a hole between them. 1065 - */ 1066 - if (nr_pages == 0) { 1067 - /* Data search found nothing */ 1068 - if (type == DATA_OFF) 1069 - break; 1070 - 1071 - ASSERT(type == HOLE_OFF); 1072 - if (lastoff == startoff || lastoff < endoff) { 1073 - found = true; 1074 - *offset = lastoff; 1075 - } 1055 + if (nr_pages == 0) 1076 1056 break; 1077 - } 1078 - 1079 - /* 1080 - * At lease we found one page. If this is the first time we 1081 - * step into the loop, and if the first page index offset is 1082 - * greater than the given search offset, a hole was found. 1083 - */ 1084 - if (type == HOLE_OFF && lastoff == startoff && 1085 - lastoff < page_offset(pvec.pages[0])) { 1086 - found = true; 1087 - break; 1088 - } 1089 1057 1090 1058 for (i = 0; i < nr_pages; i++) { 1091 1059 struct page *page = pvec.pages[i]; ··· 1066 1098 * file mapping. However, page->index will not change 1067 1099 * because we have a reference on the page. 1068 1100 * 1069 - * Searching done if the page index is out of range. 1070 - * If the current offset is not reaches the end of 1071 - * the specified search range, there should be a hole 1072 - * between them. 1101 + * If current page offset is beyond where we've ended, 1102 + * we've found a hole. 1073 1103 */ 1074 - if (page->index > end) { 1075 - if (type == HOLE_OFF && lastoff < endoff) { 1076 - *offset = lastoff; 1077 - found = true; 1078 - } 1104 + if (type == HOLE_OFF && lastoff < endoff && 1105 + lastoff < page_offset(pvec.pages[i])) { 1106 + found = true; 1107 + *offset = lastoff; 1079 1108 goto out; 1080 1109 } 1110 + /* Searching done if the page index is out of range. */ 1111 + if (page->index > end) 1112 + goto out; 1081 1113 1082 1114 lock_page(page); 1083 1115 /* ··· 1119 1151 1120 1152 /* 1121 1153 * The number of returned pages less than our desired, search 1122 - * done. In this case, nothing was found for searching data, 1123 - * but we found a hole behind the last offset. 1154 + * done. 1124 1155 */ 1125 - if (nr_pages < want) { 1126 - if (type == HOLE_OFF) { 1127 - *offset = lastoff; 1128 - found = true; 1129 - } 1156 + if (nr_pages < want) 1130 1157 break; 1131 - } 1132 1158 1133 1159 index = pvec.pages[i - 1]->index + 1; 1134 1160 pagevec_release(&pvec); 1135 1161 } while (index <= end); 1136 1162 1163 + /* No page at lastoff and we are not done - we found a hole. */ 1164 + if (type == HOLE_OFF && lastoff < endoff) { 1165 + *offset = lastoff; 1166 + found = true; 1167 + } 1137 1168 out: 1138 1169 pagevec_release(&pvec); 1139 1170 return found;
+4 -1
fs/xfs/xfs_fsmap.c
··· 828 828 struct xfs_fsmap dkeys[2]; /* per-dev keys */ 829 829 struct xfs_getfsmap_dev handlers[XFS_GETFSMAP_DEVS]; 830 830 struct xfs_getfsmap_info info = { NULL }; 831 + bool use_rmap; 831 832 int i; 832 833 int error = 0; 833 834 ··· 838 837 !xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[1])) 839 838 return -EINVAL; 840 839 840 + use_rmap = capable(CAP_SYS_ADMIN) && 841 + xfs_sb_version_hasrmapbt(&mp->m_sb); 841 842 head->fmh_entries = 0; 842 843 843 844 /* Set up our device handlers. */ 844 845 memset(handlers, 0, sizeof(handlers)); 845 846 handlers[0].dev = new_encode_dev(mp->m_ddev_targp->bt_dev); 846 - if (xfs_sb_version_hasrmapbt(&mp->m_sb)) 847 + if (use_rmap) 847 848 handlers[0].fn = xfs_getfsmap_datadev_rmapbt; 848 849 else 849 850 handlers[0].fn = xfs_getfsmap_datadev_bnobt;