diff options
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 82 |
1 files changed, 39 insertions, 43 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index b631c9043460..0cb4c1557f20 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -1125,13 +1125,14 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1125 | if (IS_ERR(hc)) | 1125 | if (IS_ERR(hc)) |
1126 | return PTR_ERR(hc); | 1126 | return PTR_ERR(hc); |
1127 | 1127 | ||
1128 | h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS | __GFP_NOWARN); | 1128 | hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS | __GFP_NOWARN); |
1129 | if (hc2 == NULL) | 1129 | if (hc2 == NULL) |
1130 | hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS, PAGE_KERNEL); | 1130 | hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS, PAGE_KERNEL); |
1131 | 1131 | ||
1132 | if (!hc2) | 1132 | if (!hc2) |
1133 | return -ENOMEM; | 1133 | return -ENOMEM; |
1134 | 1134 | ||
1135 | h = hc2; | ||
1135 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1136 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1136 | if (error) | 1137 | if (error) |
1137 | goto out_kfree; | 1138 | goto out_kfree; |
@@ -1212,9 +1213,7 @@ static int compare_dents(const void *a, const void *b) | |||
1212 | /** | 1213 | /** |
1213 | * do_filldir_main - read out directory entries | 1214 | * do_filldir_main - read out directory entries |
1214 | * @dip: The GFS2 inode | 1215 | * @dip: The GFS2 inode |
1215 | * @offset: The offset in the file to read from | 1216 | * @ctx: what to feed the entries to |
1216 | * @opaque: opaque data to pass to filldir | ||
1217 | * @filldir: The function to pass entries to | ||
1218 | * @darr: an array of struct gfs2_dirent pointers to read | 1217 | * @darr: an array of struct gfs2_dirent pointers to read |
1219 | * @entries: the number of entries in darr | 1218 | * @entries: the number of entries in darr |
1220 | * @copied: pointer to int that's non-zero if a entry has been copied out | 1219 | * @copied: pointer to int that's non-zero if a entry has been copied out |
@@ -1224,11 +1223,10 @@ static int compare_dents(const void *a, const void *b) | |||
1224 | * the possibility that they will fall into different readdir buffers or | 1223 | * the possibility that they will fall into different readdir buffers or |
1225 | * that someone will want to seek to that location. | 1224 | * that someone will want to seek to that location. |
1226 | * | 1225 | * |
1227 | * Returns: errno, >0 on exception from filldir | 1226 | * Returns: errno, >0 if the actor tells you to stop |
1228 | */ | 1227 | */ |
1229 | 1228 | ||
1230 | static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | 1229 | static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx, |
1231 | void *opaque, filldir_t filldir, | ||
1232 | const struct gfs2_dirent **darr, u32 entries, | 1230 | const struct gfs2_dirent **darr, u32 entries, |
1233 | int *copied) | 1231 | int *copied) |
1234 | { | 1232 | { |
@@ -1236,7 +1234,6 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1236 | u64 off, off_next; | 1234 | u64 off, off_next; |
1237 | unsigned int x, y; | 1235 | unsigned int x, y; |
1238 | int run = 0; | 1236 | int run = 0; |
1239 | int error = 0; | ||
1240 | 1237 | ||
1241 | sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL); | 1238 | sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL); |
1242 | 1239 | ||
@@ -1253,9 +1250,9 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1253 | off_next = be32_to_cpu(dent_next->de_hash); | 1250 | off_next = be32_to_cpu(dent_next->de_hash); |
1254 | off_next = gfs2_disk_hash2offset(off_next); | 1251 | off_next = gfs2_disk_hash2offset(off_next); |
1255 | 1252 | ||
1256 | if (off < *offset) | 1253 | if (off < ctx->pos) |
1257 | continue; | 1254 | continue; |
1258 | *offset = off; | 1255 | ctx->pos = off; |
1259 | 1256 | ||
1260 | if (off_next == off) { | 1257 | if (off_next == off) { |
1261 | if (*copied && !run) | 1258 | if (*copied && !run) |
@@ -1264,26 +1261,25 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1264 | } else | 1261 | } else |
1265 | run = 0; | 1262 | run = 0; |
1266 | } else { | 1263 | } else { |
1267 | if (off < *offset) | 1264 | if (off < ctx->pos) |
1268 | continue; | 1265 | continue; |
1269 | *offset = off; | 1266 | ctx->pos = off; |
1270 | } | 1267 | } |
1271 | 1268 | ||
1272 | error = filldir(opaque, (const char *)(dent + 1), | 1269 | if (!dir_emit(ctx, (const char *)(dent + 1), |
1273 | be16_to_cpu(dent->de_name_len), | 1270 | be16_to_cpu(dent->de_name_len), |
1274 | off, be64_to_cpu(dent->de_inum.no_addr), | 1271 | be64_to_cpu(dent->de_inum.no_addr), |
1275 | be16_to_cpu(dent->de_type)); | 1272 | be16_to_cpu(dent->de_type))) |
1276 | if (error) | ||
1277 | return 1; | 1273 | return 1; |
1278 | 1274 | ||
1279 | *copied = 1; | 1275 | *copied = 1; |
1280 | } | 1276 | } |
1281 | 1277 | ||
1282 | /* Increment the *offset by one, so the next time we come into the | 1278 | /* Increment the ctx->pos by one, so the next time we come into the |
1283 | do_filldir fxn, we get the next entry instead of the last one in the | 1279 | do_filldir fxn, we get the next entry instead of the last one in the |
1284 | current leaf */ | 1280 | current leaf */ |
1285 | 1281 | ||
1286 | (*offset)++; | 1282 | ctx->pos++; |
1287 | 1283 | ||
1288 | return 0; | 1284 | return 0; |
1289 | } | 1285 | } |
@@ -1307,8 +1303,8 @@ static void gfs2_free_sort_buffer(void *ptr) | |||
1307 | kfree(ptr); | 1303 | kfree(ptr); |
1308 | } | 1304 | } |
1309 | 1305 | ||
1310 | static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | 1306 | static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, |
1311 | filldir_t filldir, int *copied, unsigned *depth, | 1307 | int *copied, unsigned *depth, |
1312 | u64 leaf_no) | 1308 | u64 leaf_no) |
1313 | { | 1309 | { |
1314 | struct gfs2_inode *ip = GFS2_I(inode); | 1310 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -1386,8 +1382,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | |||
1386 | } while(lfn); | 1382 | } while(lfn); |
1387 | 1383 | ||
1388 | BUG_ON(entries2 != entries); | 1384 | BUG_ON(entries2 != entries); |
1389 | error = do_filldir_main(ip, offset, opaque, filldir, darr, | 1385 | error = do_filldir_main(ip, ctx, darr, entries, copied); |
1390 | entries, copied); | ||
1391 | out_free: | 1386 | out_free: |
1392 | for(i = 0; i < leaf; i++) | 1387 | for(i = 0; i < leaf; i++) |
1393 | brelse(larr[i]); | 1388 | brelse(larr[i]); |
@@ -1446,15 +1441,13 @@ static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index, | |||
1446 | /** | 1441 | /** |
1447 | * dir_e_read - Reads the entries from a directory into a filldir buffer | 1442 | * dir_e_read - Reads the entries from a directory into a filldir buffer |
1448 | * @dip: dinode pointer | 1443 | * @dip: dinode pointer |
1449 | * @offset: the hash of the last entry read shifted to the right once | 1444 | * @ctx: actor to feed the entries to |
1450 | * @opaque: buffer for the filldir function to fill | ||
1451 | * @filldir: points to the filldir function to use | ||
1452 | * | 1445 | * |
1453 | * Returns: errno | 1446 | * Returns: errno |
1454 | */ | 1447 | */ |
1455 | 1448 | ||
1456 | static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | 1449 | static int dir_e_read(struct inode *inode, struct dir_context *ctx, |
1457 | filldir_t filldir, struct file_ra_state *f_ra) | 1450 | struct file_ra_state *f_ra) |
1458 | { | 1451 | { |
1459 | struct gfs2_inode *dip = GFS2_I(inode); | 1452 | struct gfs2_inode *dip = GFS2_I(inode); |
1460 | u32 hsize, len = 0; | 1453 | u32 hsize, len = 0; |
@@ -1465,7 +1458,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1465 | unsigned depth = 0; | 1458 | unsigned depth = 0; |
1466 | 1459 | ||
1467 | hsize = 1 << dip->i_depth; | 1460 | hsize = 1 << dip->i_depth; |
1468 | hash = gfs2_dir_offset2hash(*offset); | 1461 | hash = gfs2_dir_offset2hash(ctx->pos); |
1469 | index = hash >> (32 - dip->i_depth); | 1462 | index = hash >> (32 - dip->i_depth); |
1470 | 1463 | ||
1471 | if (dip->i_hash_cache == NULL) | 1464 | if (dip->i_hash_cache == NULL) |
@@ -1477,7 +1470,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1477 | gfs2_dir_readahead(inode, hsize, index, f_ra); | 1470 | gfs2_dir_readahead(inode, hsize, index, f_ra); |
1478 | 1471 | ||
1479 | while (index < hsize) { | 1472 | while (index < hsize) { |
1480 | error = gfs2_dir_read_leaf(inode, offset, opaque, filldir, | 1473 | error = gfs2_dir_read_leaf(inode, ctx, |
1481 | &copied, &depth, | 1474 | &copied, &depth, |
1482 | be64_to_cpu(lp[index])); | 1475 | be64_to_cpu(lp[index])); |
1483 | if (error) | 1476 | if (error) |
@@ -1492,8 +1485,8 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1492 | return error; | 1485 | return error; |
1493 | } | 1486 | } |
1494 | 1487 | ||
1495 | int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | 1488 | int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, |
1496 | filldir_t filldir, struct file_ra_state *f_ra) | 1489 | struct file_ra_state *f_ra) |
1497 | { | 1490 | { |
1498 | struct gfs2_inode *dip = GFS2_I(inode); | 1491 | struct gfs2_inode *dip = GFS2_I(inode); |
1499 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1492 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -1507,7 +1500,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | |||
1507 | return 0; | 1500 | return 0; |
1508 | 1501 | ||
1509 | if (dip->i_diskflags & GFS2_DIF_EXHASH) | 1502 | if (dip->i_diskflags & GFS2_DIF_EXHASH) |
1510 | return dir_e_read(inode, offset, opaque, filldir, f_ra); | 1503 | return dir_e_read(inode, ctx, f_ra); |
1511 | 1504 | ||
1512 | if (!gfs2_is_stuffed(dip)) { | 1505 | if (!gfs2_is_stuffed(dip)) { |
1513 | gfs2_consist_inode(dip); | 1506 | gfs2_consist_inode(dip); |
@@ -1539,7 +1532,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | |||
1539 | error = -EIO; | 1532 | error = -EIO; |
1540 | goto out; | 1533 | goto out; |
1541 | } | 1534 | } |
1542 | error = do_filldir_main(dip, offset, opaque, filldir, darr, | 1535 | error = do_filldir_main(dip, ctx, darr, |
1543 | dip->i_entries, &copied); | 1536 | dip->i_entries, &copied); |
1544 | out: | 1537 | out: |
1545 | kfree(darr); | 1538 | kfree(darr); |
@@ -1555,9 +1548,9 @@ out: | |||
1555 | 1548 | ||
1556 | /** | 1549 | /** |
1557 | * gfs2_dir_search - Search a directory | 1550 | * gfs2_dir_search - Search a directory |
1558 | * @dip: The GFS2 inode | 1551 | * @dip: The GFS2 dir inode |
1559 | * @filename: | 1552 | * @name: The name we are looking up |
1560 | * @inode: | 1553 | * @fail_on_exist: Fail if the name exists rather than looking it up |
1561 | * | 1554 | * |
1562 | * This routine searches a directory for a file or another directory. | 1555 | * This routine searches a directory for a file or another directory. |
1563 | * Assumes a glock is held on dip. | 1556 | * Assumes a glock is held on dip. |
@@ -1565,22 +1558,25 @@ out: | |||
1565 | * Returns: errno | 1558 | * Returns: errno |
1566 | */ | 1559 | */ |
1567 | 1560 | ||
1568 | struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) | 1561 | struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name, |
1562 | bool fail_on_exist) | ||
1569 | { | 1563 | { |
1570 | struct buffer_head *bh; | 1564 | struct buffer_head *bh; |
1571 | struct gfs2_dirent *dent; | 1565 | struct gfs2_dirent *dent; |
1572 | struct inode *inode; | 1566 | u64 addr, formal_ino; |
1567 | u16 dtype; | ||
1573 | 1568 | ||
1574 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); | 1569 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); |
1575 | if (dent) { | 1570 | if (dent) { |
1576 | if (IS_ERR(dent)) | 1571 | if (IS_ERR(dent)) |
1577 | return ERR_CAST(dent); | 1572 | return ERR_CAST(dent); |
1578 | inode = gfs2_inode_lookup(dir->i_sb, | 1573 | dtype = be16_to_cpu(dent->de_type); |
1579 | be16_to_cpu(dent->de_type), | 1574 | addr = be64_to_cpu(dent->de_inum.no_addr); |
1580 | be64_to_cpu(dent->de_inum.no_addr), | 1575 | formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino); |
1581 | be64_to_cpu(dent->de_inum.no_formal_ino), 0); | ||
1582 | brelse(bh); | 1576 | brelse(bh); |
1583 | return inode; | 1577 | if (fail_on_exist) |
1578 | return ERR_PTR(-EEXIST); | ||
1579 | return gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0); | ||
1584 | } | 1580 | } |
1585 | return ERR_PTR(-ENOENT); | 1581 | return ERR_PTR(-ENOENT); |
1586 | } | 1582 | } |