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 branch 'for-linus' of git://oss.sgi.com/xfs/xfs

* 'for-linus' of git://oss.sgi.com/xfs/xfs:
xfs: remove block number from inode lookup code
xfs: rename XFS_IGET_BULKSTAT to XFS_IGET_UNTRUSTED
xfs: validate untrusted inode numbers during lookup
xfs: always use iget in bulkstat
xfs: prevent swapext from operating on write-only files

+174 -390
+5 -6
fs/xfs/linux-2.6/xfs_export.c
··· 128 128 return ERR_PTR(-ESTALE); 129 129 130 130 /* 131 - * The XFS_IGET_BULKSTAT means that an invalid inode number is just 132 - * fine and not an indication of a corrupted filesystem. Because 133 - * clients can send any kind of invalid file handle, e.g. after 134 - * a restore on the server we have to deal with this case gracefully. 131 + * The XFS_IGET_UNTRUSTED means that an invalid inode number is just 132 + * fine and not an indication of a corrupted filesystem as clients can 133 + * send invalid file handles and we have to handle it gracefully.. 135 134 */ 136 - error = xfs_iget(mp, NULL, ino, XFS_IGET_BULKSTAT, 137 - XFS_ILOCK_SHARED, &ip, 0); 135 + error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED, 136 + XFS_ILOCK_SHARED, &ip); 138 137 if (error) { 139 138 /* 140 139 * EINVAL means the inode cluster doesn't exist anymore.
+3 -4
fs/xfs/linux-2.6/xfs_ioctl.c
··· 679 679 error = xfs_bulkstat_single(mp, &inlast, 680 680 bulkreq.ubuffer, &done); 681 681 else /* XFS_IOC_FSBULKSTAT */ 682 - error = xfs_bulkstat(mp, &inlast, &count, 683 - (bulkstat_one_pf)xfs_bulkstat_one, NULL, 684 - sizeof(xfs_bstat_t), bulkreq.ubuffer, 685 - BULKSTAT_FG_QUICK, &done); 682 + error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one, 683 + sizeof(xfs_bstat_t), bulkreq.ubuffer, 684 + &done); 686 685 687 686 if (error) 688 687 return -error;
+5 -10
fs/xfs/linux-2.6/xfs_ioctl32.c
··· 237 237 xfs_ino_t ino, /* inode number to get data for */ 238 238 void __user *buffer, /* buffer to place output in */ 239 239 int ubsize, /* size of buffer */ 240 - void *private_data, /* my private data */ 241 - xfs_daddr_t bno, /* starting bno of inode cluster */ 242 240 int *ubused, /* bytes used by me */ 243 - void *dibuff, /* on-disk inode buffer */ 244 241 int *stat) /* BULKSTAT_RV_... */ 245 242 { 246 243 return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, 247 - xfs_bulkstat_one_fmt_compat, bno, 248 - ubused, dibuff, stat); 244 + xfs_bulkstat_one_fmt_compat, 245 + ubused, stat); 249 246 } 250 247 251 248 /* copied from xfs_ioctl.c */ ··· 295 298 int res; 296 299 297 300 error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer, 298 - sizeof(compat_xfs_bstat_t), 299 - NULL, 0, NULL, NULL, &res); 301 + sizeof(compat_xfs_bstat_t), 0, &res); 300 302 } else if (cmd == XFS_IOC_FSBULKSTAT_32) { 301 303 error = xfs_bulkstat(mp, &inlast, &count, 302 - xfs_bulkstat_one_compat, NULL, 303 - sizeof(compat_xfs_bstat_t), bulkreq.ubuffer, 304 - BULKSTAT_FG_QUICK, &done); 304 + xfs_bulkstat_one_compat, sizeof(compat_xfs_bstat_t), 305 + bulkreq.ubuffer, &done); 305 306 } else 306 307 error = XFS_ERROR(EINVAL); 307 308 if (error)
+8 -10
fs/xfs/quota/xfs_qm.c
··· 1632 1632 xfs_ino_t ino, /* inode number to get data for */ 1633 1633 void __user *buffer, /* not used */ 1634 1634 int ubsize, /* not used */ 1635 - void *private_data, /* not used */ 1636 - xfs_daddr_t bno, /* starting block of inode cluster */ 1637 1635 int *ubused, /* not used */ 1638 - void *dip, /* on-disk inode pointer (not used) */ 1639 1636 int *res) /* result code value */ 1640 1637 { 1641 1638 xfs_inode_t *ip; ··· 1657 1660 * the case in all other instances. It's OK that we do this because 1658 1661 * quotacheck is done only at mount time. 1659 1662 */ 1660 - if ((error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip, bno))) { 1663 + if ((error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip))) { 1661 1664 *res = BULKSTAT_RV_NOTHING; 1662 1665 return error; 1663 1666 } ··· 1793 1796 * Iterate thru all the inodes in the file system, 1794 1797 * adjusting the corresponding dquot counters in core. 1795 1798 */ 1796 - if ((error = xfs_bulkstat(mp, &lastino, &count, 1797 - xfs_qm_dqusage_adjust, NULL, 1798 - structsz, NULL, BULKSTAT_FG_IGET, &done))) 1799 + error = xfs_bulkstat(mp, &lastino, &count, 1800 + xfs_qm_dqusage_adjust, 1801 + structsz, NULL, &done); 1802 + if (error) 1799 1803 break; 1800 1804 1801 - } while (! done); 1805 + } while (!done); 1802 1806 1803 1807 /* 1804 1808 * We've made all the changes that we need to make incore. ··· 1887 1889 mp->m_sb.sb_uquotino != NULLFSINO) { 1888 1890 ASSERT(mp->m_sb.sb_uquotino > 0); 1889 1891 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 1890 - 0, 0, &uip, 0))) 1892 + 0, 0, &uip))) 1891 1893 return XFS_ERROR(error); 1892 1894 } 1893 1895 if (XFS_IS_OQUOTA_ON(mp) && 1894 1896 mp->m_sb.sb_gquotino != NULLFSINO) { 1895 1897 ASSERT(mp->m_sb.sb_gquotino > 0); 1896 1898 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 1897 - 0, 0, &gip, 0))) { 1899 + 0, 0, &gip))) { 1898 1900 if (uip) 1899 1901 IRELE(uip); 1900 1902 return XFS_ERROR(error);
+12 -15
fs/xfs/quota/xfs_qm_syscalls.c
··· 262 262 } 263 263 264 264 if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) { 265 - error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip, 0); 265 + error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip); 266 266 if (!error) { 267 267 error = xfs_truncate_file(mp, qip); 268 268 IRELE(qip); ··· 271 271 272 272 if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && 273 273 mp->m_sb.sb_gquotino != NULLFSINO) { 274 - error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); 274 + error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip); 275 275 if (!error2) { 276 276 error2 = xfs_truncate_file(mp, qip); 277 277 IRELE(qip); ··· 417 417 } 418 418 if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { 419 419 if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 420 - 0, 0, &uip, 0) == 0) 420 + 0, 0, &uip) == 0) 421 421 tempuqip = B_TRUE; 422 422 } 423 423 if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { 424 424 if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 425 - 0, 0, &gip, 0) == 0) 425 + 0, 0, &gip) == 0) 426 426 tempgqip = B_TRUE; 427 427 } 428 428 if (uip) { ··· 1109 1109 xfs_ino_t ino, /* inode number to get data for */ 1110 1110 void __user *buffer, /* not used */ 1111 1111 int ubsize, /* not used */ 1112 - void *private_data, /* not used */ 1113 - xfs_daddr_t bno, /* starting block of inode cluster */ 1114 1112 int *ubused, /* not used */ 1115 - void *dip, /* not used */ 1116 1113 int *res) /* bulkstat result code */ 1117 1114 { 1118 1115 xfs_inode_t *ip; ··· 1131 1134 ipreleased = B_FALSE; 1132 1135 again: 1133 1136 lock_flags = XFS_ILOCK_SHARED; 1134 - if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip, bno))) { 1137 + if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip))) { 1135 1138 *res = BULKSTAT_RV_NOTHING; 1136 1139 return (error); 1137 1140 } ··· 1202 1205 * Iterate thru all the inodes in the file system, 1203 1206 * adjusting the corresponding dquot counters 1204 1207 */ 1205 - if ((error = xfs_bulkstat(mp, &lastino, &count, 1206 - xfs_qm_internalqcheck_adjust, NULL, 1207 - 0, NULL, BULKSTAT_FG_IGET, &done))) { 1208 + error = xfs_bulkstat(mp, &lastino, &count, 1209 + xfs_qm_internalqcheck_adjust, 1210 + 0, NULL, &done); 1211 + if (error) { 1212 + cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error); 1208 1213 break; 1209 1214 } 1210 - } while (! done); 1211 - if (error) { 1212 - cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error); 1213 - } 1215 + } while (!done); 1216 + 1214 1217 cmn_err(CE_DEBUG, "Checking results against system dquots"); 1215 1218 for (i = 0; i < qmtest_hashmask; i++) { 1216 1219 xfs_dqtest_t *d, *n;
+4 -1
fs/xfs/xfs_dfrag.c
··· 69 69 goto out; 70 70 } 71 71 72 - if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) { 72 + if (!(file->f_mode & FMODE_WRITE) || 73 + !(file->f_mode & FMODE_READ) || 74 + (file->f_flags & O_APPEND)) { 73 75 error = XFS_ERROR(EBADF); 74 76 goto out_put_file; 75 77 } ··· 83 81 } 84 82 85 83 if (!(tmp_file->f_mode & FMODE_WRITE) || 84 + !(tmp_file->f_mode & FMODE_READ) || 86 85 (tmp_file->f_flags & O_APPEND)) { 87 86 error = XFS_ERROR(EBADF); 88 87 goto out_put_tmp_file;
+82 -60
fs/xfs/xfs_ialloc.c
··· 1203 1203 return error; 1204 1204 } 1205 1205 1206 + STATIC int 1207 + xfs_imap_lookup( 1208 + struct xfs_mount *mp, 1209 + struct xfs_trans *tp, 1210 + xfs_agnumber_t agno, 1211 + xfs_agino_t agino, 1212 + xfs_agblock_t agbno, 1213 + xfs_agblock_t *chunk_agbno, 1214 + xfs_agblock_t *offset_agbno, 1215 + int flags) 1216 + { 1217 + struct xfs_inobt_rec_incore rec; 1218 + struct xfs_btree_cur *cur; 1219 + struct xfs_buf *agbp; 1220 + xfs_agino_t startino; 1221 + int error; 1222 + int i; 1223 + 1224 + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); 1225 + if (error) { 1226 + xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " 1227 + "xfs_ialloc_read_agi() returned " 1228 + "error %d, agno %d", 1229 + error, agno); 1230 + return error; 1231 + } 1232 + 1233 + /* 1234 + * derive and lookup the exact inode record for the given agino. If the 1235 + * record cannot be found, then it's an invalid inode number and we 1236 + * should abort. 1237 + */ 1238 + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); 1239 + startino = agino & ~(XFS_IALLOC_INODES(mp) - 1); 1240 + error = xfs_inobt_lookup(cur, startino, XFS_LOOKUP_EQ, &i); 1241 + if (!error) { 1242 + if (i) 1243 + error = xfs_inobt_get_rec(cur, &rec, &i); 1244 + if (!error && i == 0) 1245 + error = EINVAL; 1246 + } 1247 + 1248 + xfs_trans_brelse(tp, agbp); 1249 + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1250 + if (error) 1251 + return error; 1252 + 1253 + /* for untrusted inodes check it is allocated first */ 1254 + if ((flags & XFS_IGET_UNTRUSTED) && 1255 + (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) 1256 + return EINVAL; 1257 + 1258 + *chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino); 1259 + *offset_agbno = agbno - *chunk_agbno; 1260 + return 0; 1261 + } 1262 + 1206 1263 /* 1207 1264 * Return the location of the inode in imap, for mapping it into a buffer. 1208 1265 */ ··· 1292 1235 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || 1293 1236 ino != XFS_AGINO_TO_INO(mp, agno, agino)) { 1294 1237 #ifdef DEBUG 1295 - /* no diagnostics for bulkstat, ino comes from userspace */ 1296 - if (flags & XFS_IGET_BULKSTAT) 1238 + /* 1239 + * Don't output diagnostic information for untrusted inodes 1240 + * as they can be invalid without implying corruption. 1241 + */ 1242 + if (flags & XFS_IGET_UNTRUSTED) 1297 1243 return XFS_ERROR(EINVAL); 1298 1244 if (agno >= mp->m_sb.sb_agcount) { 1299 1245 xfs_fs_cmn_err(CE_ALERT, mp, ··· 1323 1263 return XFS_ERROR(EINVAL); 1324 1264 } 1325 1265 1266 + blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; 1267 + 1268 + /* 1269 + * For bulkstat and handle lookups, we have an untrusted inode number 1270 + * that we have to verify is valid. We cannot do this just by reading 1271 + * the inode buffer as it may have been unlinked and removed leaving 1272 + * inodes in stale state on disk. Hence we have to do a btree lookup 1273 + * in all cases where an untrusted inode number is passed. 1274 + */ 1275 + if (flags & XFS_IGET_UNTRUSTED) { 1276 + error = xfs_imap_lookup(mp, tp, agno, agino, agbno, 1277 + &chunk_agbno, &offset_agbno, flags); 1278 + if (error) 1279 + return error; 1280 + goto out_map; 1281 + } 1282 + 1326 1283 /* 1327 1284 * If the inode cluster size is the same as the blocksize or 1328 1285 * smaller we get to the buffer by simple arithmetics. ··· 1354 1277 return 0; 1355 1278 } 1356 1279 1357 - blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; 1358 - 1359 - /* 1360 - * If we get a block number passed from bulkstat we can use it to 1361 - * find the buffer easily. 1362 - */ 1363 - if (imap->im_blkno) { 1364 - offset = XFS_INO_TO_OFFSET(mp, ino); 1365 - ASSERT(offset < mp->m_sb.sb_inopblock); 1366 - 1367 - cluster_agbno = xfs_daddr_to_agbno(mp, imap->im_blkno); 1368 - offset += (agbno - cluster_agbno) * mp->m_sb.sb_inopblock; 1369 - 1370 - imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); 1371 - imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog); 1372 - return 0; 1373 - } 1374 - 1375 1280 /* 1376 1281 * If the inode chunks are aligned then use simple maths to 1377 1282 * find the location. Otherwise we have to do a btree ··· 1363 1304 offset_agbno = agbno & mp->m_inoalign_mask; 1364 1305 chunk_agbno = agbno - offset_agbno; 1365 1306 } else { 1366 - xfs_btree_cur_t *cur; /* inode btree cursor */ 1367 - xfs_inobt_rec_incore_t chunk_rec; 1368 - xfs_buf_t *agbp; /* agi buffer */ 1369 - int i; /* temp state */ 1370 - 1371 - error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); 1372 - if (error) { 1373 - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " 1374 - "xfs_ialloc_read_agi() returned " 1375 - "error %d, agno %d", 1376 - error, agno); 1377 - return error; 1378 - } 1379 - 1380 - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); 1381 - error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); 1382 - if (error) { 1383 - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " 1384 - "xfs_inobt_lookup() failed"); 1385 - goto error0; 1386 - } 1387 - 1388 - error = xfs_inobt_get_rec(cur, &chunk_rec, &i); 1389 - if (error) { 1390 - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " 1391 - "xfs_inobt_get_rec() failed"); 1392 - goto error0; 1393 - } 1394 - if (i == 0) { 1395 - #ifdef DEBUG 1396 - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " 1397 - "xfs_inobt_get_rec() failed"); 1398 - #endif /* DEBUG */ 1399 - error = XFS_ERROR(EINVAL); 1400 - } 1401 - error0: 1402 - xfs_trans_brelse(tp, agbp); 1403 - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1307 + error = xfs_imap_lookup(mp, tp, agno, agino, agbno, 1308 + &chunk_agbno, &offset_agbno, flags); 1404 1309 if (error) 1405 1310 return error; 1406 - chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino); 1407 - offset_agbno = agbno - chunk_agbno; 1408 1311 } 1409 1312 1313 + out_map: 1410 1314 ASSERT(agbno >= chunk_agbno); 1411 1315 cluster_agbno = chunk_agbno + 1412 1316 ((offset_agbno / blks_per_cluster) * blks_per_cluster);
+3 -7
fs/xfs/xfs_iget.c
··· 259 259 xfs_trans_t *tp, 260 260 xfs_ino_t ino, 261 261 struct xfs_inode **ipp, 262 - xfs_daddr_t bno, 263 262 int flags, 264 263 int lock_flags) 265 264 { ··· 271 272 if (!ip) 272 273 return ENOMEM; 273 274 274 - error = xfs_iread(mp, tp, ip, bno, flags); 275 + error = xfs_iread(mp, tp, ip, flags); 275 276 if (error) 276 277 goto out_destroy; 277 278 ··· 357 358 * within the file system for the inode being requested. 358 359 * lock_flags -- flags indicating how to lock the inode. See the comment 359 360 * for xfs_ilock() for a list of valid values. 360 - * bno -- the block number starting the buffer containing the inode, 361 - * if known (as by bulkstat), else 0. 362 361 */ 363 362 int 364 363 xfs_iget( ··· 365 368 xfs_ino_t ino, 366 369 uint flags, 367 370 uint lock_flags, 368 - xfs_inode_t **ipp, 369 - xfs_daddr_t bno) 371 + xfs_inode_t **ipp) 370 372 { 371 373 xfs_inode_t *ip; 372 374 int error; ··· 393 397 read_unlock(&pag->pag_ici_lock); 394 398 XFS_STATS_INC(xs_ig_missed); 395 399 396 - error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, bno, 400 + error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, 397 401 flags, lock_flags); 398 402 if (error) 399 403 goto out_error_or_again;
+1 -4
fs/xfs/xfs_inode.c
··· 177 177 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, 178 178 XFS_ERRTAG_ITOBP_INOTOBP, 179 179 XFS_RANDOM_ITOBP_INOTOBP))) { 180 - if (iget_flags & XFS_IGET_BULKSTAT) { 180 + if (iget_flags & XFS_IGET_UNTRUSTED) { 181 181 xfs_trans_brelse(tp, bp); 182 182 return XFS_ERROR(EINVAL); 183 183 } ··· 787 787 xfs_mount_t *mp, 788 788 xfs_trans_t *tp, 789 789 xfs_inode_t *ip, 790 - xfs_daddr_t bno, 791 790 uint iget_flags) 792 791 { 793 792 xfs_buf_t *bp; ··· 796 797 /* 797 798 * Fill in the location information in the in-core inode. 798 799 */ 799 - ip->i_imap.im_blkno = bno; 800 800 error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); 801 801 if (error) 802 802 return error; 803 - ASSERT(bno == 0 || bno == ip->i_imap.im_blkno); 804 803 805 804 /* 806 805 * Get pointers to the on-disk inode and the buffer containing it.
+3 -3
fs/xfs/xfs_inode.h
··· 442 442 * xfs_iget.c prototypes. 443 443 */ 444 444 int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 445 - uint, uint, xfs_inode_t **, xfs_daddr_t); 445 + uint, uint, xfs_inode_t **); 446 446 void xfs_iput(xfs_inode_t *, uint); 447 447 void xfs_iput_new(xfs_inode_t *, uint); 448 448 void xfs_ilock(xfs_inode_t *, uint); ··· 500 500 * Flags for xfs_iget() 501 501 */ 502 502 #define XFS_IGET_CREATE 0x1 503 - #define XFS_IGET_BULKSTAT 0x2 503 + #define XFS_IGET_UNTRUSTED 0x2 504 504 505 505 int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, 506 506 xfs_ino_t, struct xfs_dinode **, ··· 509 509 struct xfs_inode *, struct xfs_dinode **, 510 510 struct xfs_buf **, uint); 511 511 int xfs_iread(struct xfs_mount *, struct xfs_trans *, 512 - struct xfs_inode *, xfs_daddr_t, uint); 512 + struct xfs_inode *, uint); 513 513 void xfs_dinode_to_disk(struct xfs_dinode *, 514 514 struct xfs_icdinode *); 515 515 void xfs_idestroy_fork(struct xfs_inode *, int);
+42 -247
fs/xfs/xfs_itable.c
··· 49 49 (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); 50 50 } 51 51 52 - STATIC int 53 - xfs_bulkstat_one_iget( 54 - xfs_mount_t *mp, /* mount point for filesystem */ 55 - xfs_ino_t ino, /* inode number to get data for */ 56 - xfs_daddr_t bno, /* starting bno of inode cluster */ 57 - xfs_bstat_t *buf, /* return buffer */ 58 - int *stat) /* BULKSTAT_RV_... */ 52 + /* 53 + * Return stat information for one inode. 54 + * Return 0 if ok, else errno. 55 + */ 56 + int 57 + xfs_bulkstat_one_int( 58 + struct xfs_mount *mp, /* mount point for filesystem */ 59 + xfs_ino_t ino, /* inode to get data for */ 60 + void __user *buffer, /* buffer to place output in */ 61 + int ubsize, /* size of buffer */ 62 + bulkstat_one_fmt_pf formatter, /* formatter, copy to user */ 63 + int *ubused, /* bytes used by me */ 64 + int *stat) /* BULKSTAT_RV_... */ 59 65 { 60 - xfs_icdinode_t *dic; /* dinode core info pointer */ 61 - xfs_inode_t *ip; /* incore inode pointer */ 62 - struct inode *inode; 63 - int error; 66 + struct xfs_icdinode *dic; /* dinode core info pointer */ 67 + struct xfs_inode *ip; /* incore inode pointer */ 68 + struct inode *inode; 69 + struct xfs_bstat *buf; /* return buffer */ 70 + int error = 0; /* error value */ 71 + 72 + *stat = BULKSTAT_RV_NOTHING; 73 + 74 + if (!buffer || xfs_internal_inum(mp, ino)) 75 + return XFS_ERROR(EINVAL); 76 + 77 + buf = kmem_alloc(sizeof(*buf), KM_SLEEP | KM_MAYFAIL); 78 + if (!buf) 79 + return XFS_ERROR(ENOMEM); 64 80 65 81 error = xfs_iget(mp, NULL, ino, 66 - XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno); 82 + XFS_IGET_UNTRUSTED, XFS_ILOCK_SHARED, &ip); 67 83 if (error) { 68 84 *stat = BULKSTAT_RV_NOTHING; 69 - return error; 85 + goto out_free; 70 86 } 71 87 72 88 ASSERT(ip != NULL); ··· 143 127 buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks; 144 128 break; 145 129 } 146 - 147 130 xfs_iput(ip, XFS_ILOCK_SHARED); 131 + 132 + error = formatter(buffer, ubsize, ubused, buf); 133 + 134 + if (!error) 135 + *stat = BULKSTAT_RV_DIDONE; 136 + 137 + out_free: 138 + kmem_free(buf); 148 139 return error; 149 - } 150 - 151 - STATIC void 152 - xfs_bulkstat_one_dinode( 153 - xfs_mount_t *mp, /* mount point for filesystem */ 154 - xfs_ino_t ino, /* inode number to get data for */ 155 - xfs_dinode_t *dic, /* dinode inode pointer */ 156 - xfs_bstat_t *buf) /* return buffer */ 157 - { 158 - /* 159 - * The inode format changed when we moved the link count and 160 - * made it 32 bits long. If this is an old format inode, 161 - * convert it in memory to look like a new one. If it gets 162 - * flushed to disk we will convert back before flushing or 163 - * logging it. We zero out the new projid field and the old link 164 - * count field. We'll handle clearing the pad field (the remains 165 - * of the old uuid field) when we actually convert the inode to 166 - * the new format. We don't change the version number so that we 167 - * can distinguish this from a real new format inode. 168 - */ 169 - if (dic->di_version == 1) { 170 - buf->bs_nlink = be16_to_cpu(dic->di_onlink); 171 - buf->bs_projid = 0; 172 - } else { 173 - buf->bs_nlink = be32_to_cpu(dic->di_nlink); 174 - buf->bs_projid = be16_to_cpu(dic->di_projid); 175 - } 176 - 177 - buf->bs_ino = ino; 178 - buf->bs_mode = be16_to_cpu(dic->di_mode); 179 - buf->bs_uid = be32_to_cpu(dic->di_uid); 180 - buf->bs_gid = be32_to_cpu(dic->di_gid); 181 - buf->bs_size = be64_to_cpu(dic->di_size); 182 - buf->bs_atime.tv_sec = be32_to_cpu(dic->di_atime.t_sec); 183 - buf->bs_atime.tv_nsec = be32_to_cpu(dic->di_atime.t_nsec); 184 - buf->bs_mtime.tv_sec = be32_to_cpu(dic->di_mtime.t_sec); 185 - buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec); 186 - buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec); 187 - buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec); 188 - buf->bs_xflags = xfs_dic2xflags(dic); 189 - buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog; 190 - buf->bs_extents = be32_to_cpu(dic->di_nextents); 191 - buf->bs_gen = be32_to_cpu(dic->di_gen); 192 - memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); 193 - buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask); 194 - buf->bs_dmstate = be16_to_cpu(dic->di_dmstate); 195 - buf->bs_aextents = be16_to_cpu(dic->di_anextents); 196 - buf->bs_forkoff = XFS_DFORK_BOFF(dic); 197 - 198 - switch (dic->di_format) { 199 - case XFS_DINODE_FMT_DEV: 200 - buf->bs_rdev = xfs_dinode_get_rdev(dic); 201 - buf->bs_blksize = BLKDEV_IOSIZE; 202 - buf->bs_blocks = 0; 203 - break; 204 - case XFS_DINODE_FMT_LOCAL: 205 - case XFS_DINODE_FMT_UUID: 206 - buf->bs_rdev = 0; 207 - buf->bs_blksize = mp->m_sb.sb_blocksize; 208 - buf->bs_blocks = 0; 209 - break; 210 - case XFS_DINODE_FMT_EXTENTS: 211 - case XFS_DINODE_FMT_BTREE: 212 - buf->bs_rdev = 0; 213 - buf->bs_blksize = mp->m_sb.sb_blocksize; 214 - buf->bs_blocks = be64_to_cpu(dic->di_nblocks); 215 - break; 216 - } 217 140 } 218 141 219 142 /* Return 0 on success or positive error */ ··· 172 217 return 0; 173 218 } 174 219 175 - /* 176 - * Return stat information for one inode. 177 - * Return 0 if ok, else errno. 178 - */ 179 - int /* error status */ 180 - xfs_bulkstat_one_int( 181 - xfs_mount_t *mp, /* mount point for filesystem */ 182 - xfs_ino_t ino, /* inode number to get data for */ 183 - void __user *buffer, /* buffer to place output in */ 184 - int ubsize, /* size of buffer */ 185 - bulkstat_one_fmt_pf formatter, /* formatter, copy to user */ 186 - xfs_daddr_t bno, /* starting bno of inode cluster */ 187 - int *ubused, /* bytes used by me */ 188 - void *dibuff, /* on-disk inode buffer */ 189 - int *stat) /* BULKSTAT_RV_... */ 190 - { 191 - xfs_bstat_t *buf; /* return buffer */ 192 - int error = 0; /* error value */ 193 - xfs_dinode_t *dip; /* dinode inode pointer */ 194 - 195 - dip = (xfs_dinode_t *)dibuff; 196 - *stat = BULKSTAT_RV_NOTHING; 197 - 198 - if (!buffer || xfs_internal_inum(mp, ino)) 199 - return XFS_ERROR(EINVAL); 200 - 201 - buf = kmem_alloc(sizeof(*buf), KM_SLEEP); 202 - 203 - if (dip == NULL) { 204 - /* We're not being passed a pointer to a dinode. This happens 205 - * if BULKSTAT_FG_IGET is selected. Do the iget. 206 - */ 207 - error = xfs_bulkstat_one_iget(mp, ino, bno, buf, stat); 208 - if (error) 209 - goto out_free; 210 - } else { 211 - xfs_bulkstat_one_dinode(mp, ino, dip, buf); 212 - } 213 - 214 - error = formatter(buffer, ubsize, ubused, buf); 215 - if (error) 216 - goto out_free; 217 - 218 - *stat = BULKSTAT_RV_DIDONE; 219 - 220 - out_free: 221 - kmem_free(buf); 222 - return error; 223 - } 224 - 225 220 int 226 221 xfs_bulkstat_one( 227 222 xfs_mount_t *mp, /* mount point for filesystem */ 228 223 xfs_ino_t ino, /* inode number to get data for */ 229 224 void __user *buffer, /* buffer to place output in */ 230 225 int ubsize, /* size of buffer */ 231 - void *private_data, /* my private data */ 232 - xfs_daddr_t bno, /* starting bno of inode cluster */ 233 226 int *ubused, /* bytes used by me */ 234 - void *dibuff, /* on-disk inode buffer */ 235 227 int *stat) /* BULKSTAT_RV_... */ 236 228 { 237 229 return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, 238 - xfs_bulkstat_one_fmt, bno, 239 - ubused, dibuff, stat); 240 - } 241 - 242 - /* 243 - * Test to see whether we can use the ondisk inode directly, based 244 - * on the given bulkstat flags, filling in dipp accordingly. 245 - * Returns zero if the inode is dodgey. 246 - */ 247 - STATIC int 248 - xfs_bulkstat_use_dinode( 249 - xfs_mount_t *mp, 250 - int flags, 251 - xfs_buf_t *bp, 252 - int clustidx, 253 - xfs_dinode_t **dipp) 254 - { 255 - xfs_dinode_t *dip; 256 - unsigned int aformat; 257 - 258 - *dipp = NULL; 259 - if (!bp || (flags & BULKSTAT_FG_IGET)) 260 - return 1; 261 - dip = (xfs_dinode_t *) 262 - xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); 263 - /* 264 - * Check the buffer containing the on-disk inode for di_mode == 0. 265 - * This is to prevent xfs_bulkstat from picking up just reclaimed 266 - * inodes that have their in-core state initialized but not flushed 267 - * to disk yet. This is a temporary hack that would require a proper 268 - * fix in the future. 269 - */ 270 - if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC || 271 - !XFS_DINODE_GOOD_VERSION(dip->di_version) || 272 - !dip->di_mode) 273 - return 0; 274 - if (flags & BULKSTAT_FG_QUICK) { 275 - *dipp = dip; 276 - return 1; 277 - } 278 - /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ 279 - aformat = dip->di_aformat; 280 - if ((XFS_DFORK_Q(dip) == 0) || 281 - (aformat == XFS_DINODE_FMT_LOCAL) || 282 - (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_anextents)) { 283 - *dipp = dip; 284 - return 1; 285 - } 286 - return 1; 230 + xfs_bulkstat_one_fmt, ubused, stat); 287 231 } 288 232 289 233 #define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) ··· 196 342 xfs_ino_t *lastinop, /* last inode returned */ 197 343 int *ubcountp, /* size of buffer/count returned */ 198 344 bulkstat_one_pf formatter, /* func that'd fill a single buf */ 199 - void *private_data,/* private data for formatter */ 200 345 size_t statstruct_size, /* sizeof struct filling */ 201 346 char __user *ubuffer, /* buffer with inode stats */ 202 - int flags, /* defined in xfs_itable.h */ 203 347 int *done) /* 1 if there are more stats to get */ 204 348 { 205 349 xfs_agblock_t agbno=0;/* allocation group block number */ ··· 232 380 int ubelem; /* spaces used in user's buffer */ 233 381 int ubused; /* bytes used by formatter */ 234 382 xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */ 235 - xfs_dinode_t *dip; /* ptr into bp for specific inode */ 236 383 237 384 /* 238 385 * Get the last inode value, see if there's nothing to do. 239 386 */ 240 387 ino = (xfs_ino_t)*lastinop; 241 388 lastino = ino; 242 - dip = NULL; 243 389 agno = XFS_INO_TO_AGNO(mp, ino); 244 390 agino = XFS_INO_TO_AGINO(mp, ino); 245 391 if (agno >= mp->m_sb.sb_agcount || ··· 462 612 irbp->ir_startino) + 463 613 ((chunkidx & nimask) >> 464 614 mp->m_sb.sb_inopblog); 465 - 466 - if (flags & (BULKSTAT_FG_QUICK | 467 - BULKSTAT_FG_INLINE)) { 468 - int offset; 469 - 470 - ino = XFS_AGINO_TO_INO(mp, agno, 471 - agino); 472 - bno = XFS_AGB_TO_DADDR(mp, agno, 473 - agbno); 474 - 475 - /* 476 - * Get the inode cluster buffer 477 - */ 478 - if (bp) 479 - xfs_buf_relse(bp); 480 - 481 - error = xfs_inotobp(mp, NULL, ino, &dip, 482 - &bp, &offset, 483 - XFS_IGET_BULKSTAT); 484 - 485 - if (!error) 486 - clustidx = offset / mp->m_sb.sb_inodesize; 487 - if (XFS_TEST_ERROR(error != 0, 488 - mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK, 489 - XFS_RANDOM_BULKSTAT_READ_CHUNK)) { 490 - bp = NULL; 491 - ubleft = 0; 492 - rval = error; 493 - break; 494 - } 495 - } 496 615 } 497 616 ino = XFS_AGINO_TO_INO(mp, agno, agino); 498 617 bno = XFS_AGB_TO_DADDR(mp, agno, agbno); ··· 477 658 * when the chunk is used up. 478 659 */ 479 660 irbp->ir_freecount++; 480 - if (!xfs_bulkstat_use_dinode(mp, flags, bp, 481 - clustidx, &dip)) { 482 - lastino = ino; 483 - continue; 484 - } 485 - /* 486 - * If we need to do an iget, cannot hold bp. 487 - * Drop it, until starting the next cluster. 488 - */ 489 - if ((flags & BULKSTAT_FG_INLINE) && !dip) { 490 - if (bp) 491 - xfs_buf_relse(bp); 492 - bp = NULL; 493 - } 494 661 495 662 /* 496 663 * Get the inode and fill in a single buffer. 497 - * BULKSTAT_FG_QUICK uses dip to fill it in. 498 - * BULKSTAT_FG_IGET uses igets. 499 - * BULKSTAT_FG_INLINE uses dip if we have an 500 - * inline attr fork, else igets. 501 - * See: xfs_bulkstat_one & xfs_dm_bulkstat_one. 502 - * This is also used to count inodes/blks, etc 503 - * in xfs_qm_quotacheck. 504 664 */ 505 665 ubused = statstruct_size; 506 - error = formatter(mp, ino, ubufp, 507 - ubleft, private_data, 508 - bno, &ubused, dip, &fmterror); 666 + error = formatter(mp, ino, ubufp, ubleft, 667 + &ubused, &fmterror); 509 668 if (fmterror == BULKSTAT_RV_NOTHING) { 510 669 if (error && error != ENOENT && 511 670 error != EINVAL) { ··· 575 778 */ 576 779 577 780 ino = (xfs_ino_t)*lastinop; 578 - error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), 579 - NULL, 0, NULL, NULL, &res); 781 + error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), 0, &res); 580 782 if (error) { 581 783 /* 582 784 * Special case way failed, do it the "long" way ··· 584 788 (*lastinop)--; 585 789 count = 1; 586 790 if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one, 587 - NULL, sizeof(xfs_bstat_t), buffer, 588 - BULKSTAT_FG_IGET, done)) 791 + sizeof(xfs_bstat_t), buffer, done)) 589 792 return error; 590 793 if (count == 0 || (xfs_ino_t)*lastinop != ino) 591 794 return error == EFSCORRUPTED ?
-17
fs/xfs/xfs_itable.h
··· 27 27 xfs_ino_t ino, 28 28 void __user *buffer, 29 29 int ubsize, 30 - void *private_data, 31 - xfs_daddr_t bno, 32 30 int *ubused, 33 - void *dip, 34 31 int *stat); 35 32 36 33 /* ··· 38 41 #define BULKSTAT_RV_GIVEUP 2 39 42 40 43 /* 41 - * Values for bulkstat flag argument. 42 - */ 43 - #define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ 44 - #define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ 45 - #define BULKSTAT_FG_INLINE 0x4 /* No iget if inline attrs */ 46 - 47 - /* 48 44 * Return stat information in bulk (by-inode) for the filesystem. 49 45 */ 50 46 int /* error status */ ··· 46 56 xfs_ino_t *lastino, /* last inode returned */ 47 57 int *count, /* size of buffer/count returned */ 48 58 bulkstat_one_pf formatter, /* func that'd fill a single buf */ 49 - void *private_data, /* private data for formatter */ 50 59 size_t statstruct_size,/* sizeof struct that we're filling */ 51 60 char __user *ubuffer,/* buffer with inode stats */ 52 - int flags, /* flag to control access method */ 53 61 int *done); /* 1 if there are more stats to get */ 54 62 55 63 int ··· 70 82 void __user *buffer, 71 83 int ubsize, 72 84 bulkstat_one_fmt_pf formatter, 73 - xfs_daddr_t bno, 74 85 int *ubused, 75 - void *dibuff, 76 86 int *stat); 77 87 78 88 int ··· 79 93 xfs_ino_t ino, 80 94 void __user *buffer, 81 95 int ubsize, 82 - void *private_data, 83 - xfs_daddr_t bno, 84 96 int *ubused, 85 - void *dibuff, 86 97 int *stat); 87 98 88 99 typedef int (*inumbers_fmt_pf)(
+1 -1
fs/xfs/xfs_log_recover.c
··· 3198 3198 int error; 3199 3199 3200 3200 ino = XFS_AGINO_TO_INO(mp, agno, agino); 3201 - error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0); 3201 + error = xfs_iget(mp, NULL, ino, 0, 0, &ip); 3202 3202 if (error) 3203 3203 goto fail; 3204 3204
+1 -1
fs/xfs/xfs_mount.c
··· 1300 1300 * Get and sanity-check the root inode. 1301 1301 * Save the pointer to it in the mount structure. 1302 1302 */ 1303 - error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0); 1303 + error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip); 1304 1304 if (error) { 1305 1305 cmn_err(CE_WARN, "XFS: failed to read root inode"); 1306 1306 goto out_log_dealloc;
+2 -2
fs/xfs/xfs_rtalloc.c
··· 2277 2277 sbp = &mp->m_sb; 2278 2278 if (sbp->sb_rbmino == NULLFSINO) 2279 2279 return 0; 2280 - error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip, 0); 2280 + error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip); 2281 2281 if (error) 2282 2282 return error; 2283 2283 ASSERT(mp->m_rbmip != NULL); 2284 2284 ASSERT(sbp->sb_rsumino != NULLFSINO); 2285 - error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip, 0); 2285 + error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); 2286 2286 if (error) { 2287 2287 IRELE(mp->m_rbmip); 2288 2288 return error;
+1 -1
fs/xfs/xfs_trans_inode.c
··· 62 62 { 63 63 int error; 64 64 65 - error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp, 0); 65 + error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp); 66 66 if (!error && tp) 67 67 xfs_trans_ijoin(tp, *ipp, lock_flags); 68 68 return error;
+1 -1
fs/xfs/xfs_vnodeops.c
··· 1269 1269 if (error) 1270 1270 goto out; 1271 1271 1272 - error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp, 0); 1272 + error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp); 1273 1273 if (error) 1274 1274 goto out_free_name; 1275 1275