diff options
author | Christoph Hellwig <hch@lst.de> | 2008-11-27 22:23:41 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-11-30 19:38:03 -0500 |
commit | 94e1b69d1abd108d306e926c3012ec89e481c0da (patch) | |
tree | d7fb02a0c855729831dcddbef6afcb518d3ed870 /fs | |
parent | a1941895034cda2bffa23ba845607c82138ccf52 (diff) |
[XFS] merge xfs_imap into xfs_dilocate
xfs_imap is the only caller of xfs_dilocate and doesn't add any significant
value. Merge the two functions and document the various cases we have for
inode cluster lookup in the new xfs_imap.
Also remove the unused im_agblkno and im_ioffset fields from struct xfs_imap
while we're at it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_ialloc.c | 129 | ||||
-rw-r--r-- | fs/xfs/xfs_ialloc.h | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_imap.h | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 60 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 2 |
5 files changed, 88 insertions, 120 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 0ce56d6a4922..348ac30174c5 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "xfs_rtalloc.h" | 40 | #include "xfs_rtalloc.h" |
41 | #include "xfs_error.h" | 41 | #include "xfs_error.h" |
42 | #include "xfs_bmap.h" | 42 | #include "xfs_bmap.h" |
43 | #include "xfs_imap.h" | ||
43 | 44 | ||
44 | 45 | ||
45 | /* | 46 | /* |
@@ -1196,36 +1197,28 @@ error0: | |||
1196 | } | 1197 | } |
1197 | 1198 | ||
1198 | /* | 1199 | /* |
1199 | * Return the location of the inode in bno/off, for mapping it into a buffer. | 1200 | * Return the location of the inode in imap, for mapping it into a buffer. |
1200 | */ | 1201 | */ |
1201 | /*ARGSUSED*/ | ||
1202 | int | 1202 | int |
1203 | xfs_dilocate( | 1203 | xfs_imap( |
1204 | xfs_mount_t *mp, /* file system mount structure */ | 1204 | xfs_mount_t *mp, /* file system mount structure */ |
1205 | xfs_trans_t *tp, /* transaction pointer */ | 1205 | xfs_trans_t *tp, /* transaction pointer */ |
1206 | xfs_ino_t ino, /* inode to locate */ | 1206 | xfs_ino_t ino, /* inode to locate */ |
1207 | xfs_fsblock_t *bno, /* output: block containing inode */ | 1207 | struct xfs_imap *imap, /* location map structure */ |
1208 | int *len, /* output: num blocks in inode cluster */ | 1208 | uint flags) /* flags for inode btree lookup */ |
1209 | int *off, /* output: index in block of inode */ | ||
1210 | uint flags) /* flags concerning inode lookup */ | ||
1211 | { | 1209 | { |
1212 | xfs_agblock_t agbno; /* block number of inode in the alloc group */ | 1210 | xfs_agblock_t agbno; /* block number of inode in the alloc group */ |
1213 | xfs_buf_t *agbp; /* agi buffer */ | ||
1214 | xfs_agino_t agino; /* inode number within alloc group */ | 1211 | xfs_agino_t agino; /* inode number within alloc group */ |
1215 | xfs_agnumber_t agno; /* allocation group number */ | 1212 | xfs_agnumber_t agno; /* allocation group number */ |
1216 | int blks_per_cluster; /* num blocks per inode cluster */ | 1213 | int blks_per_cluster; /* num blocks per inode cluster */ |
1217 | xfs_agblock_t chunk_agbno; /* first block in inode chunk */ | 1214 | xfs_agblock_t chunk_agbno; /* first block in inode chunk */ |
1218 | xfs_agino_t chunk_agino; /* first agino in inode chunk */ | ||
1219 | __int32_t chunk_cnt; /* count of free inodes in chunk */ | ||
1220 | xfs_inofree_t chunk_free; /* mask of free inodes in chunk */ | ||
1221 | xfs_agblock_t cluster_agbno; /* first block in inode cluster */ | 1215 | xfs_agblock_t cluster_agbno; /* first block in inode cluster */ |
1222 | xfs_btree_cur_t *cur; /* inode btree cursor */ | ||
1223 | int error; /* error code */ | 1216 | int error; /* error code */ |
1224 | int i; /* temp state */ | ||
1225 | int offset; /* index of inode in its buffer */ | 1217 | int offset; /* index of inode in its buffer */ |
1226 | int offset_agbno; /* blks from chunk start to inode */ | 1218 | int offset_agbno; /* blks from chunk start to inode */ |
1227 | 1219 | ||
1228 | ASSERT(ino != NULLFSINO); | 1220 | ASSERT(ino != NULLFSINO); |
1221 | |||
1229 | /* | 1222 | /* |
1230 | * Split up the inode number into its parts. | 1223 | * Split up the inode number into its parts. |
1231 | */ | 1224 | */ |
@@ -1240,20 +1233,20 @@ xfs_dilocate( | |||
1240 | return XFS_ERROR(EINVAL); | 1233 | return XFS_ERROR(EINVAL); |
1241 | if (agno >= mp->m_sb.sb_agcount) { | 1234 | if (agno >= mp->m_sb.sb_agcount) { |
1242 | xfs_fs_cmn_err(CE_ALERT, mp, | 1235 | xfs_fs_cmn_err(CE_ALERT, mp, |
1243 | "xfs_dilocate: agno (%d) >= " | 1236 | "xfs_imap: agno (%d) >= " |
1244 | "mp->m_sb.sb_agcount (%d)", | 1237 | "mp->m_sb.sb_agcount (%d)", |
1245 | agno, mp->m_sb.sb_agcount); | 1238 | agno, mp->m_sb.sb_agcount); |
1246 | } | 1239 | } |
1247 | if (agbno >= mp->m_sb.sb_agblocks) { | 1240 | if (agbno >= mp->m_sb.sb_agblocks) { |
1248 | xfs_fs_cmn_err(CE_ALERT, mp, | 1241 | xfs_fs_cmn_err(CE_ALERT, mp, |
1249 | "xfs_dilocate: agbno (0x%llx) >= " | 1242 | "xfs_imap: agbno (0x%llx) >= " |
1250 | "mp->m_sb.sb_agblocks (0x%lx)", | 1243 | "mp->m_sb.sb_agblocks (0x%lx)", |
1251 | (unsigned long long) agbno, | 1244 | (unsigned long long) agbno, |
1252 | (unsigned long) mp->m_sb.sb_agblocks); | 1245 | (unsigned long) mp->m_sb.sb_agblocks); |
1253 | } | 1246 | } |
1254 | if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) { | 1247 | if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) { |
1255 | xfs_fs_cmn_err(CE_ALERT, mp, | 1248 | xfs_fs_cmn_err(CE_ALERT, mp, |
1256 | "xfs_dilocate: ino (0x%llx) != " | 1249 | "xfs_imap: ino (0x%llx) != " |
1257 | "XFS_AGINO_TO_INO(mp, agno, agino) " | 1250 | "XFS_AGINO_TO_INO(mp, agno, agino) " |
1258 | "(0x%llx)", | 1251 | "(0x%llx)", |
1259 | ino, XFS_AGINO_TO_INO(mp, agno, agino)); | 1252 | ino, XFS_AGINO_TO_INO(mp, agno, agino)); |
@@ -1262,63 +1255,89 @@ xfs_dilocate( | |||
1262 | #endif /* DEBUG */ | 1255 | #endif /* DEBUG */ |
1263 | return XFS_ERROR(EINVAL); | 1256 | return XFS_ERROR(EINVAL); |
1264 | } | 1257 | } |
1265 | if ((mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp))) { | 1258 | |
1259 | /* | ||
1260 | * If the inode cluster size is the same as the blocksize or | ||
1261 | * smaller we get to the buffer by simple arithmetics. | ||
1262 | */ | ||
1263 | if (XFS_INODE_CLUSTER_SIZE(mp) <= mp->m_sb.sb_blocksize) { | ||
1266 | offset = XFS_INO_TO_OFFSET(mp, ino); | 1264 | offset = XFS_INO_TO_OFFSET(mp, ino); |
1267 | ASSERT(offset < mp->m_sb.sb_inopblock); | 1265 | ASSERT(offset < mp->m_sb.sb_inopblock); |
1268 | *bno = XFS_AGB_TO_FSB(mp, agno, agbno); | 1266 | |
1269 | *off = offset; | 1267 | imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno); |
1270 | *len = 1; | 1268 | imap->im_len = XFS_FSB_TO_BB(mp, 1); |
1269 | imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog); | ||
1271 | return 0; | 1270 | return 0; |
1272 | } | 1271 | } |
1272 | |||
1273 | blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; | 1273 | blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; |
1274 | if (*bno != NULLFSBLOCK) { | 1274 | |
1275 | /* | ||
1276 | * If we get a block number passed from bulkstat we can use it to | ||
1277 | * find the buffer easily. | ||
1278 | */ | ||
1279 | if (imap->im_blkno) { | ||
1275 | offset = XFS_INO_TO_OFFSET(mp, ino); | 1280 | offset = XFS_INO_TO_OFFSET(mp, ino); |
1276 | ASSERT(offset < mp->m_sb.sb_inopblock); | 1281 | ASSERT(offset < mp->m_sb.sb_inopblock); |
1277 | cluster_agbno = XFS_FSB_TO_AGBNO(mp, *bno); | 1282 | |
1278 | *off = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) + | 1283 | cluster_agbno = XFS_DADDR_TO_AGBNO(mp, imap->im_blkno); |
1279 | offset; | 1284 | offset += (agbno - cluster_agbno) * mp->m_sb.sb_inopblock; |
1280 | *len = blks_per_cluster; | 1285 | |
1286 | imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); | ||
1287 | imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog); | ||
1281 | return 0; | 1288 | return 0; |
1282 | } | 1289 | } |
1290 | |||
1291 | /* | ||
1292 | * If the inode chunks are aligned then use simple maths to | ||
1293 | * find the location. Otherwise we have to do a btree | ||
1294 | * lookup to find the location. | ||
1295 | */ | ||
1283 | if (mp->m_inoalign_mask) { | 1296 | if (mp->m_inoalign_mask) { |
1284 | offset_agbno = agbno & mp->m_inoalign_mask; | 1297 | offset_agbno = agbno & mp->m_inoalign_mask; |
1285 | chunk_agbno = agbno - offset_agbno; | 1298 | chunk_agbno = agbno - offset_agbno; |
1286 | } else { | 1299 | } else { |
1300 | xfs_btree_cur_t *cur; /* inode btree cursor */ | ||
1301 | xfs_agino_t chunk_agino; /* first agino in inode chunk */ | ||
1302 | __int32_t chunk_cnt; /* count of free inodes in chunk */ | ||
1303 | xfs_inofree_t chunk_free; /* mask of free inodes in chunk */ | ||
1304 | xfs_buf_t *agbp; /* agi buffer */ | ||
1305 | int i; /* temp state */ | ||
1306 | |||
1287 | down_read(&mp->m_peraglock); | 1307 | down_read(&mp->m_peraglock); |
1288 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); | 1308 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); |
1289 | up_read(&mp->m_peraglock); | 1309 | up_read(&mp->m_peraglock); |
1290 | if (error) { | 1310 | if (error) { |
1291 | #ifdef DEBUG | 1311 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " |
1292 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: " | ||
1293 | "xfs_ialloc_read_agi() returned " | 1312 | "xfs_ialloc_read_agi() returned " |
1294 | "error %d, agno %d", | 1313 | "error %d, agno %d", |
1295 | error, agno); | 1314 | error, agno); |
1296 | #endif /* DEBUG */ | ||
1297 | return error; | 1315 | return error; |
1298 | } | 1316 | } |
1317 | |||
1299 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); | 1318 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); |
1300 | if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) { | 1319 | error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i); |
1301 | #ifdef DEBUG | 1320 | if (error) { |
1302 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: " | 1321 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " |
1303 | "xfs_inobt_lookup_le() failed"); | 1322 | "xfs_inobt_lookup_le() failed"); |
1304 | #endif /* DEBUG */ | ||
1305 | goto error0; | 1323 | goto error0; |
1306 | } | 1324 | } |
1307 | if ((error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt, | 1325 | |
1308 | &chunk_free, &i))) { | 1326 | error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt, |
1309 | #ifdef DEBUG | 1327 | &chunk_free, &i); |
1310 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: " | 1328 | if (error) { |
1329 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " | ||
1311 | "xfs_inobt_get_rec() failed"); | 1330 | "xfs_inobt_get_rec() failed"); |
1312 | #endif /* DEBUG */ | ||
1313 | goto error0; | 1331 | goto error0; |
1314 | } | 1332 | } |
1315 | if (i == 0) { | 1333 | if (i == 0) { |
1316 | #ifdef DEBUG | 1334 | #ifdef DEBUG |
1317 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: " | 1335 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " |
1318 | "xfs_inobt_get_rec() failed"); | 1336 | "xfs_inobt_get_rec() failed"); |
1319 | #endif /* DEBUG */ | 1337 | #endif /* DEBUG */ |
1320 | error = XFS_ERROR(EINVAL); | 1338 | error = XFS_ERROR(EINVAL); |
1321 | } | 1339 | } |
1340 | error0: | ||
1322 | xfs_trans_brelse(tp, agbp); | 1341 | xfs_trans_brelse(tp, agbp); |
1323 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); | 1342 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); |
1324 | if (error) | 1343 | if (error) |
@@ -1326,19 +1345,35 @@ xfs_dilocate( | |||
1326 | chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino); | 1345 | chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino); |
1327 | offset_agbno = agbno - chunk_agbno; | 1346 | offset_agbno = agbno - chunk_agbno; |
1328 | } | 1347 | } |
1348 | |||
1329 | ASSERT(agbno >= chunk_agbno); | 1349 | ASSERT(agbno >= chunk_agbno); |
1330 | cluster_agbno = chunk_agbno + | 1350 | cluster_agbno = chunk_agbno + |
1331 | ((offset_agbno / blks_per_cluster) * blks_per_cluster); | 1351 | ((offset_agbno / blks_per_cluster) * blks_per_cluster); |
1332 | offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) + | 1352 | offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) + |
1333 | XFS_INO_TO_OFFSET(mp, ino); | 1353 | XFS_INO_TO_OFFSET(mp, ino); |
1334 | *bno = XFS_AGB_TO_FSB(mp, agno, cluster_agbno); | 1354 | |
1335 | *off = offset; | 1355 | imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno); |
1336 | *len = blks_per_cluster; | 1356 | imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); |
1357 | imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog); | ||
1358 | |||
1359 | /* | ||
1360 | * If the inode number maps to a block outside the bounds | ||
1361 | * of the file system then return NULL rather than calling | ||
1362 | * read_buf and panicing when we get an error from the | ||
1363 | * driver. | ||
1364 | */ | ||
1365 | if ((imap->im_blkno + imap->im_len) > | ||
1366 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { | ||
1367 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " | ||
1368 | "(imap->im_blkno (0x%llx) + imap->im_len (0x%llx)) > " | ||
1369 | " XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) (0x%llx)", | ||
1370 | (unsigned long long) imap->im_blkno, | ||
1371 | (unsigned long long) imap->im_len, | ||
1372 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); | ||
1373 | return XFS_ERROR(EINVAL); | ||
1374 | } | ||
1375 | |||
1337 | return 0; | 1376 | return 0; |
1338 | error0: | ||
1339 | xfs_trans_brelse(tp, agbp); | ||
1340 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | ||
1341 | return error; | ||
1342 | } | 1377 | } |
1343 | 1378 | ||
1344 | /* | 1379 | /* |
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h index ccf554a6e0a1..50f558a4e0a8 100644 --- a/fs/xfs/xfs_ialloc.h +++ b/fs/xfs/xfs_ialloc.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | struct xfs_buf; | 21 | struct xfs_buf; |
22 | struct xfs_dinode; | 22 | struct xfs_dinode; |
23 | struct xfs_imap; | ||
23 | struct xfs_mount; | 24 | struct xfs_mount; |
24 | struct xfs_trans; | 25 | struct xfs_trans; |
25 | 26 | ||
@@ -104,17 +105,14 @@ xfs_difree( | |||
104 | xfs_ino_t *first_ino); /* first inode in deleted cluster */ | 105 | xfs_ino_t *first_ino); /* first inode in deleted cluster */ |
105 | 106 | ||
106 | /* | 107 | /* |
107 | * Return the location of the inode in bno/len/off, | 108 | * Return the location of the inode in imap, for mapping it into a buffer. |
108 | * for mapping it into a buffer. | ||
109 | */ | 109 | */ |
110 | int | 110 | int |
111 | xfs_dilocate( | 111 | xfs_imap( |
112 | struct xfs_mount *mp, /* file system mount structure */ | 112 | struct xfs_mount *mp, /* file system mount structure */ |
113 | struct xfs_trans *tp, /* transaction pointer */ | 113 | struct xfs_trans *tp, /* transaction pointer */ |
114 | xfs_ino_t ino, /* inode to locate */ | 114 | xfs_ino_t ino, /* inode to locate */ |
115 | xfs_fsblock_t *bno, /* output: block containing inode */ | 115 | struct xfs_imap *imap, /* location map structure */ |
116 | int *len, /* output: num blocks in cluster*/ | ||
117 | int *off, /* output: index in block of inode */ | ||
118 | uint flags); /* flags for inode btree lookup */ | 116 | uint flags); /* flags for inode btree lookup */ |
119 | 117 | ||
120 | /* | 118 | /* |
diff --git a/fs/xfs/xfs_imap.h b/fs/xfs/xfs_imap.h index f9ce62890ea5..08690005739e 100644 --- a/fs/xfs/xfs_imap.h +++ b/fs/xfs/xfs_imap.h | |||
@@ -25,14 +25,7 @@ | |||
25 | typedef struct xfs_imap { | 25 | typedef struct xfs_imap { |
26 | xfs_daddr_t im_blkno; /* starting BB of inode chunk */ | 26 | xfs_daddr_t im_blkno; /* starting BB of inode chunk */ |
27 | uint im_len; /* length in BBs of inode chunk */ | 27 | uint im_len; /* length in BBs of inode chunk */ |
28 | xfs_agblock_t im_agblkno; /* logical block of inode chunk in ag */ | ||
29 | ushort im_ioffset; /* inode offset in block in "inodes" */ | ||
30 | ushort im_boffset; /* inode offset in block in bytes */ | 28 | ushort im_boffset; /* inode offset in block in bytes */ |
31 | } xfs_imap_t; | 29 | } xfs_imap_t; |
32 | 30 | ||
33 | struct xfs_mount; | ||
34 | struct xfs_trans; | ||
35 | int xfs_imap(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | ||
36 | xfs_imap_t *, uint); | ||
37 | |||
38 | #endif /* __XFS_IMAP_H__ */ | 31 | #endif /* __XFS_IMAP_H__ */ |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 663ff9e517fd..bf528b725ae1 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -266,7 +266,7 @@ xfs_inotobp( | |||
266 | * in once, thus we can use the mapping information stored in the inode | 266 | * in once, thus we can use the mapping information stored in the inode |
267 | * rather than calling xfs_imap(). This allows us to avoid the overhead | 267 | * rather than calling xfs_imap(). This allows us to avoid the overhead |
268 | * of looking at the inode btree for small block file systems | 268 | * of looking at the inode btree for small block file systems |
269 | * (see xfs_dilocate()). | 269 | * (see xfs_imap()). |
270 | */ | 270 | */ |
271 | int | 271 | int |
272 | xfs_itobp( | 272 | xfs_itobp( |
@@ -2508,64 +2508,6 @@ xfs_idata_realloc( | |||
2508 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); | 2508 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); |
2509 | } | 2509 | } |
2510 | 2510 | ||
2511 | |||
2512 | |||
2513 | |||
2514 | /* | ||
2515 | * Map inode to disk block and offset. | ||
2516 | * | ||
2517 | * mp -- the mount point structure for the current file system | ||
2518 | * tp -- the current transaction | ||
2519 | * ino -- the inode number of the inode to be located | ||
2520 | * imap -- this structure is filled in with the information necessary | ||
2521 | * to retrieve the given inode from disk | ||
2522 | * flags -- flags to pass to xfs_dilocate indicating whether or not | ||
2523 | * lookups in the inode btree were OK or not | ||
2524 | */ | ||
2525 | int | ||
2526 | xfs_imap( | ||
2527 | xfs_mount_t *mp, | ||
2528 | xfs_trans_t *tp, | ||
2529 | xfs_ino_t ino, | ||
2530 | xfs_imap_t *imap, | ||
2531 | uint flags) | ||
2532 | { | ||
2533 | xfs_fsblock_t fsbno; | ||
2534 | int len; | ||
2535 | int off; | ||
2536 | int error; | ||
2537 | |||
2538 | fsbno = imap->im_blkno ? | ||
2539 | XFS_DADDR_TO_FSB(mp, imap->im_blkno) : NULLFSBLOCK; | ||
2540 | error = xfs_dilocate(mp, tp, ino, &fsbno, &len, &off, flags); | ||
2541 | if (error) | ||
2542 | return error; | ||
2543 | |||
2544 | imap->im_blkno = XFS_FSB_TO_DADDR(mp, fsbno); | ||
2545 | imap->im_len = XFS_FSB_TO_BB(mp, len); | ||
2546 | imap->im_agblkno = XFS_FSB_TO_AGBNO(mp, fsbno); | ||
2547 | imap->im_ioffset = (ushort)off; | ||
2548 | imap->im_boffset = (ushort)(off << mp->m_sb.sb_inodelog); | ||
2549 | |||
2550 | /* | ||
2551 | * If the inode number maps to a block outside the bounds | ||
2552 | * of the file system then return NULL rather than calling | ||
2553 | * read_buf and panicing when we get an error from the | ||
2554 | * driver. | ||
2555 | */ | ||
2556 | if ((imap->im_blkno + imap->im_len) > | ||
2557 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { | ||
2558 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " | ||
2559 | "(imap->im_blkno (0x%llx) + imap->im_len (0x%llx)) > " | ||
2560 | " XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) (0x%llx)", | ||
2561 | (unsigned long long) imap->im_blkno, | ||
2562 | (unsigned long long) imap->im_len, | ||
2563 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); | ||
2564 | return EINVAL; | ||
2565 | } | ||
2566 | return 0; | ||
2567 | } | ||
2568 | |||
2569 | void | 2511 | void |
2570 | xfs_idestroy_fork( | 2512 | xfs_idestroy_fork( |
2571 | xfs_inode_t *ip, | 2513 | xfs_inode_t *ip, |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index db1f68840727..0a9ad1c56a87 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -157,7 +157,7 @@ typedef struct xfs_icdinode { | |||
157 | #define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ | 157 | #define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ |
158 | 158 | ||
159 | /* | 159 | /* |
160 | * Flags for xfs_inotobp, xfs_imap() and xfs_dilocate(). | 160 | * Flags for xfs_inotobp and xfs_imap(). |
161 | */ | 161 | */ |
162 | #define XFS_IMAP_BULKSTAT 0x1 | 162 | #define XFS_IMAP_BULKSTAT 0x1 |
163 | 163 | ||