aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r--fs/ocfs2/dir.c109
1 files changed, 73 insertions, 36 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 9cce563fd627..026e6eb85187 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -82,6 +82,49 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
82 struct ocfs2_alloc_context *meta_ac, 82 struct ocfs2_alloc_context *meta_ac,
83 struct buffer_head **new_bh); 83 struct buffer_head **new_bh);
84 84
85static struct buffer_head *ocfs2_bread(struct inode *inode,
86 int block, int *err, int reada)
87{
88 struct buffer_head *bh = NULL;
89 int tmperr;
90 u64 p_blkno;
91 int readflags = 0;
92
93 if (reada)
94 readflags |= OCFS2_BH_READAHEAD;
95
96 if (((u64)block << inode->i_sb->s_blocksize_bits) >=
97 i_size_read(inode)) {
98 BUG_ON(!reada);
99 return NULL;
100 }
101
102 down_read(&OCFS2_I(inode)->ip_alloc_sem);
103 tmperr = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL,
104 NULL);
105 up_read(&OCFS2_I(inode)->ip_alloc_sem);
106 if (tmperr < 0) {
107 mlog_errno(tmperr);
108 goto fail;
109 }
110
111 tmperr = ocfs2_read_blocks(inode, p_blkno, 1, &bh, readflags);
112 if (tmperr < 0)
113 goto fail;
114
115 tmperr = 0;
116
117 *err = 0;
118 return bh;
119
120fail:
121 brelse(bh);
122 bh = NULL;
123
124 *err = -EIO;
125 return NULL;
126}
127
85/* 128/*
86 * bh passed here can be an inode block or a dir data block, depending 129 * bh passed here can be an inode block or a dir data block, depending
87 * on the inode inline data flag. 130 * on the inode inline data flag.
@@ -188,8 +231,7 @@ static struct buffer_head *ocfs2_find_entry_id(const char *name,
188 struct ocfs2_dinode *di; 231 struct ocfs2_dinode *di;
189 struct ocfs2_inline_data *data; 232 struct ocfs2_inline_data *data;
190 233
191 ret = ocfs2_read_block(OCFS2_SB(dir->i_sb), OCFS2_I(dir)->ip_blkno, 234 ret = ocfs2_read_block(dir, OCFS2_I(dir)->ip_blkno, &di_bh);
192 &di_bh, OCFS2_BH_CACHED, dir);
193 if (ret) { 235 if (ret) {
194 mlog_errno(ret); 236 mlog_errno(ret);
195 goto out; 237 goto out;
@@ -260,14 +302,13 @@ restart:
260 } 302 }
261 if ((bh = bh_use[ra_ptr++]) == NULL) 303 if ((bh = bh_use[ra_ptr++]) == NULL)
262 goto next; 304 goto next;
263 wait_on_buffer(bh); 305 if (ocfs2_read_block(dir, block, &bh)) {
264 if (!buffer_uptodate(bh)) { 306 /* read error, skip block & hope for the best.
265 /* read error, skip block & hope for the best */ 307 * ocfs2_read_block() has released the bh. */
266 ocfs2_error(dir->i_sb, "reading directory %llu, " 308 ocfs2_error(dir->i_sb, "reading directory %llu, "
267 "offset %lu\n", 309 "offset %lu\n",
268 (unsigned long long)OCFS2_I(dir)->ip_blkno, 310 (unsigned long long)OCFS2_I(dir)->ip_blkno,
269 block); 311 block);
270 brelse(bh);
271 goto next; 312 goto next;
272 } 313 }
273 i = ocfs2_search_dirblock(bh, dir, name, namelen, 314 i = ocfs2_search_dirblock(bh, dir, name, namelen,
@@ -417,8 +458,7 @@ static inline int ocfs2_delete_entry_id(handle_t *handle,
417 struct ocfs2_dinode *di; 458 struct ocfs2_dinode *di;
418 struct ocfs2_inline_data *data; 459 struct ocfs2_inline_data *data;
419 460
420 ret = ocfs2_read_block(OCFS2_SB(dir->i_sb), OCFS2_I(dir)->ip_blkno, 461 ret = ocfs2_read_block(dir, OCFS2_I(dir)->ip_blkno, &di_bh);
421 &di_bh, OCFS2_BH_CACHED, dir);
422 if (ret) { 462 if (ret) {
423 mlog_errno(ret); 463 mlog_errno(ret);
424 goto out; 464 goto out;
@@ -596,8 +636,7 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
596 struct ocfs2_inline_data *data; 636 struct ocfs2_inline_data *data;
597 struct ocfs2_dir_entry *de; 637 struct ocfs2_dir_entry *de;
598 638
599 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), OCFS2_I(inode)->ip_blkno, 639 ret = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, &di_bh);
600 &di_bh, OCFS2_BH_CACHED, inode);
601 if (ret) { 640 if (ret) {
602 mlog(ML_ERROR, "Unable to read inode block for dir %llu\n", 641 mlog(ML_ERROR, "Unable to read inode block for dir %llu\n",
603 (unsigned long long)OCFS2_I(inode)->ip_blkno); 642 (unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -716,8 +755,7 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
716 for (i = ra_sectors >> (sb->s_blocksize_bits - 9); 755 for (i = ra_sectors >> (sb->s_blocksize_bits - 9);
717 i > 0; i--) { 756 i > 0; i--) {
718 tmp = ocfs2_bread(inode, ++blk, &err, 1); 757 tmp = ocfs2_bread(inode, ++blk, &err, 1);
719 if (tmp) 758 brelse(tmp);
720 brelse(tmp);
721 } 759 }
722 last_ra_blk = blk; 760 last_ra_blk = blk;
723 ra_sectors = 8; 761 ra_sectors = 8;
@@ -899,10 +937,8 @@ int ocfs2_find_files_on_disk(const char *name,
899leave: 937leave:
900 if (status < 0) { 938 if (status < 0) {
901 *dirent = NULL; 939 *dirent = NULL;
902 if (*dirent_bh) { 940 brelse(*dirent_bh);
903 brelse(*dirent_bh); 941 *dirent_bh = NULL;
904 *dirent_bh = NULL;
905 }
906 } 942 }
907 943
908 mlog_exit(status); 944 mlog_exit(status);
@@ -951,8 +987,7 @@ int ocfs2_check_dir_for_entry(struct inode *dir,
951 987
952 ret = 0; 988 ret = 0;
953bail: 989bail:
954 if (dirent_bh) 990 brelse(dirent_bh);
955 brelse(dirent_bh);
956 991
957 mlog_exit(ret); 992 mlog_exit(ret);
958 return ret; 993 return ret;
@@ -1127,8 +1162,7 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
1127 1162
1128 status = 0; 1163 status = 0;
1129bail: 1164bail:
1130 if (new_bh) 1165 brelse(new_bh);
1131 brelse(new_bh);
1132 1166
1133 mlog_exit(status); 1167 mlog_exit(status);
1134 return status; 1168 return status;
@@ -1192,6 +1226,9 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
1192 struct buffer_head *dirdata_bh = NULL; 1226 struct buffer_head *dirdata_bh = NULL;
1193 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; 1227 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
1194 handle_t *handle; 1228 handle_t *handle;
1229 struct ocfs2_extent_tree et;
1230
1231 ocfs2_init_dinode_extent_tree(&et, dir, di_bh);
1195 1232
1196 alloc = ocfs2_clusters_for_bytes(sb, bytes); 1233 alloc = ocfs2_clusters_for_bytes(sb, bytes);
1197 1234
@@ -1305,8 +1342,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
1305 * This should never fail as our extent list is empty and all 1342 * This should never fail as our extent list is empty and all
1306 * related blocks have been journaled already. 1343 * related blocks have been journaled already.
1307 */ 1344 */
1308 ret = ocfs2_insert_extent(osb, handle, dir, di_bh, 0, blkno, len, 0, 1345 ret = ocfs2_insert_extent(osb, handle, dir, &et, 0, blkno, len,
1309 NULL); 1346 0, NULL);
1310 if (ret) { 1347 if (ret) {
1311 mlog_errno(ret); 1348 mlog_errno(ret);
1312 goto out_commit; 1349 goto out_commit;
@@ -1337,8 +1374,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
1337 } 1374 }
1338 blkno = ocfs2_clusters_to_blocks(dir->i_sb, bit_off); 1375 blkno = ocfs2_clusters_to_blocks(dir->i_sb, bit_off);
1339 1376
1340 ret = ocfs2_insert_extent(osb, handle, dir, di_bh, 1, blkno, 1377 ret = ocfs2_insert_extent(osb, handle, dir, &et, 1,
1341 len, 0, NULL); 1378 blkno, len, 0, NULL);
1342 if (ret) { 1379 if (ret) {
1343 mlog_errno(ret); 1380 mlog_errno(ret);
1344 goto out_commit; 1381 goto out_commit;
@@ -1383,9 +1420,9 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
1383 if (extend) { 1420 if (extend) {
1384 u32 offset = OCFS2_I(dir)->ip_clusters; 1421 u32 offset = OCFS2_I(dir)->ip_clusters;
1385 1422
1386 status = ocfs2_do_extend_allocation(OCFS2_SB(sb), dir, &offset, 1423 status = ocfs2_add_inode_data(OCFS2_SB(sb), dir, &offset,
1387 1, 0, parent_fe_bh, handle, 1424 1, 0, parent_fe_bh, handle,
1388 data_ac, meta_ac, NULL); 1425 data_ac, meta_ac, NULL);
1389 BUG_ON(status == -EAGAIN); 1426 BUG_ON(status == -EAGAIN);
1390 if (status < 0) { 1427 if (status < 0) {
1391 mlog_errno(status); 1428 mlog_errno(status);
@@ -1430,12 +1467,14 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1430 int credits, num_free_extents, drop_alloc_sem = 0; 1467 int credits, num_free_extents, drop_alloc_sem = 0;
1431 loff_t dir_i_size; 1468 loff_t dir_i_size;
1432 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; 1469 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
1470 struct ocfs2_extent_list *el = &fe->id2.i_list;
1433 struct ocfs2_alloc_context *data_ac = NULL; 1471 struct ocfs2_alloc_context *data_ac = NULL;
1434 struct ocfs2_alloc_context *meta_ac = NULL; 1472 struct ocfs2_alloc_context *meta_ac = NULL;
1435 handle_t *handle = NULL; 1473 handle_t *handle = NULL;
1436 struct buffer_head *new_bh = NULL; 1474 struct buffer_head *new_bh = NULL;
1437 struct ocfs2_dir_entry * de; 1475 struct ocfs2_dir_entry * de;
1438 struct super_block *sb = osb->sb; 1476 struct super_block *sb = osb->sb;
1477 struct ocfs2_extent_tree et;
1439 1478
1440 mlog_entry_void(); 1479 mlog_entry_void();
1441 1480
@@ -1479,7 +1518,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1479 spin_lock(&OCFS2_I(dir)->ip_lock); 1518 spin_lock(&OCFS2_I(dir)->ip_lock);
1480 if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { 1519 if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) {
1481 spin_unlock(&OCFS2_I(dir)->ip_lock); 1520 spin_unlock(&OCFS2_I(dir)->ip_lock);
1482 num_free_extents = ocfs2_num_free_extents(osb, dir, fe); 1521 ocfs2_init_dinode_extent_tree(&et, dir, parent_fe_bh);
1522 num_free_extents = ocfs2_num_free_extents(osb, dir, &et);
1483 if (num_free_extents < 0) { 1523 if (num_free_extents < 0) {
1484 status = num_free_extents; 1524 status = num_free_extents;
1485 mlog_errno(status); 1525 mlog_errno(status);
@@ -1487,7 +1527,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1487 } 1527 }
1488 1528
1489 if (!num_free_extents) { 1529 if (!num_free_extents) {
1490 status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac); 1530 status = ocfs2_reserve_new_metadata(osb, el, &meta_ac);
1491 if (status < 0) { 1531 if (status < 0) {
1492 if (status != -ENOSPC) 1532 if (status != -ENOSPC)
1493 mlog_errno(status); 1533 mlog_errno(status);
@@ -1502,7 +1542,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
1502 goto bail; 1542 goto bail;
1503 } 1543 }
1504 1544
1505 credits = ocfs2_calc_extend_credits(sb, fe, 1); 1545 credits = ocfs2_calc_extend_credits(sb, el, 1);
1506 } else { 1546 } else {
1507 spin_unlock(&OCFS2_I(dir)->ip_lock); 1547 spin_unlock(&OCFS2_I(dir)->ip_lock);
1508 credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; 1548 credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS;
@@ -1568,8 +1608,7 @@ bail:
1568 if (meta_ac) 1608 if (meta_ac)
1569 ocfs2_free_alloc_context(meta_ac); 1609 ocfs2_free_alloc_context(meta_ac);
1570 1610
1571 if (new_bh) 1611 brelse(new_bh);
1572 brelse(new_bh);
1573 1612
1574 mlog_exit(status); 1613 mlog_exit(status);
1575 return status; 1614 return status;
@@ -1696,8 +1735,7 @@ static int ocfs2_find_dir_space_el(struct inode *dir, const char *name,
1696 1735
1697 status = 0; 1736 status = 0;
1698bail: 1737bail:
1699 if (bh) 1738 brelse(bh);
1700 brelse(bh);
1701 1739
1702 mlog_exit(status); 1740 mlog_exit(status);
1703 return status; 1741 return status;
@@ -1756,7 +1794,6 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
1756 *ret_de_bh = bh; 1794 *ret_de_bh = bh;
1757 bh = NULL; 1795 bh = NULL;
1758out: 1796out:
1759 if (bh) 1797 brelse(bh);
1760 brelse(bh);
1761 return ret; 1798 return ret;
1762} 1799}