Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs

* 'for-linus' of git://oss.sgi.com/xfs/xfs:
xfs: Make fiemap work with sparse files
xfs: prevent 32bit overflow in space reservation
xfs: Disallow 32bit project quota id
xfs: improve buffer cache hash scalability

+35 -14
+1 -7
fs/xfs/linux-2.6/xfs_buf.c
··· 440 440 ASSERT(btp == bp->b_target); 441 441 if (bp->b_file_offset == range_base && 442 442 bp->b_buffer_length == range_length) { 443 - /* 444 - * If we look at something, bring it to the 445 - * front of the list for next time. 446 - */ 447 443 atomic_inc(&bp->b_hold); 448 - list_move(&bp->b_hash_list, &hash->bh_list); 449 444 goto found; 450 445 } 451 446 } ··· 1438 1443 { 1439 1444 unsigned int i; 1440 1445 1441 - btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */ 1442 - btp->bt_hashmask = (1 << btp->bt_hashshift) - 1; 1446 + btp->bt_hashshift = external ? 3 : 12; /* 8 or 4096 buckets */ 1443 1447 btp->bt_hash = kmem_zalloc_large((1 << btp->bt_hashshift) * 1444 1448 sizeof(xfs_bufhash_t)); 1445 1449 for (i = 0; i < (1 << btp->bt_hashshift); i++) {
-1
fs/xfs/linux-2.6/xfs_buf.h
··· 137 137 size_t bt_smask; 138 138 139 139 /* per device buffer hash table */ 140 - uint bt_hashmask; 141 140 uint bt_hashshift; 142 141 xfs_bufhash_t *bt_hash; 143 142
+7
fs/xfs/linux-2.6/xfs_ioctl.c
··· 907 907 return XFS_ERROR(EIO); 908 908 909 909 /* 910 + * Disallow 32bit project ids because on-disk structure 911 + * is 16bit only. 912 + */ 913 + if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1)) 914 + return XFS_ERROR(EINVAL); 915 + 916 + /* 910 917 * If disk quotas is on, we make sure that the dquots do exist on disk, 911 918 * before we start any other transactions. Trying to do this later 912 919 * is messy. We don't care to take a readlock to look at the ids
+1 -1
fs/xfs/linux-2.6/xfs_iops.c
··· 664 664 fieinfo->fi_extents_max + 1; 665 665 bm.bmv_count = min_t(__s32, bm.bmv_count, 666 666 (PAGE_SIZE * 16 / sizeof(struct getbmapx))); 667 - bm.bmv_iflags = BMV_IF_PREALLOC; 667 + bm.bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES; 668 668 if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) 669 669 bm.bmv_iflags |= BMV_IF_ATTRFORK; 670 670 if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC))
+13 -1
fs/xfs/xfs_bmap.c
··· 5533 5533 map[i].br_startblock)) 5534 5534 goto out_free_map; 5535 5535 5536 - nexleft--; 5537 5536 bmv->bmv_offset = 5538 5537 out[cur_ext].bmv_offset + 5539 5538 out[cur_ext].bmv_length; 5540 5539 bmv->bmv_length = 5541 5540 max_t(__int64_t, 0, bmvend - bmv->bmv_offset); 5541 + 5542 + /* 5543 + * In case we don't want to return the hole, 5544 + * don't increase cur_ext so that we can reuse 5545 + * it in the next loop. 5546 + */ 5547 + if ((iflags & BMV_IF_NO_HOLES) && 5548 + map[i].br_startblock == HOLESTARTBLOCK) { 5549 + memset(&out[cur_ext], 0, sizeof(out[cur_ext])); 5550 + continue; 5551 + } 5552 + 5553 + nexleft--; 5542 5554 bmv->bmv_entries++; 5543 5555 cur_ext++; 5544 5556 }
+3 -1
fs/xfs/xfs_fs.h
··· 114 114 #define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ 115 115 #define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ 116 116 #define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */ 117 + #define BMV_IF_NO_HOLES 0x10 /* Do not return holes */ 117 118 #define BMV_IF_VALID \ 118 - (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC|BMV_IF_DELALLOC) 119 + (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC| \ 120 + BMV_IF_DELALLOC|BMV_IF_NO_HOLES) 119 121 120 122 /* bmv_oflags values - returned for each non-header segment */ 121 123 #define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */
+10 -3
fs/xfs/xfs_vnodeops.c
··· 2299 2299 e = allocatesize_fsb; 2300 2300 } 2301 2301 2302 + /* 2303 + * The transaction reservation is limited to a 32-bit block 2304 + * count, hence we need to limit the number of blocks we are 2305 + * trying to reserve to avoid an overflow. We can't allocate 2306 + * more than @nimaps extents, and an extent is limited on disk 2307 + * to MAXEXTLEN (21 bits), so use that to enforce the limit. 2308 + */ 2309 + resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps)); 2302 2310 if (unlikely(rt)) { 2303 - resrtextents = qblocks = (uint)(e - s); 2311 + resrtextents = qblocks = resblks; 2304 2312 resrtextents /= mp->m_sb.sb_rextsize; 2305 2313 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); 2306 2314 quota_flag = XFS_QMOPT_RES_RTBLKS; 2307 2315 } else { 2308 2316 resrtextents = 0; 2309 - resblks = qblocks = \ 2310 - XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s)); 2317 + resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks); 2311 2318 quota_flag = XFS_QMOPT_RES_REGBLKS; 2312 2319 } 2313 2320