diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/dir.c | 34 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 2 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 11 |
3 files changed, 25 insertions, 22 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 78c236fb34ec..081daa96a9d9 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -757,7 +757,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode, | |||
757 | 757 | ||
758 | if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { | 758 | if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { |
759 | struct gfs2_leaf *leaf; | 759 | struct gfs2_leaf *leaf; |
760 | unsigned hsize = 1 << ip->i_di.di_depth; | 760 | unsigned hsize = 1 << ip->i_depth; |
761 | unsigned index; | 761 | unsigned index; |
762 | u64 ln; | 762 | u64 ln; |
763 | if (hsize * sizeof(u64) != ip->i_di.di_size) { | 763 | if (hsize * sizeof(u64) != ip->i_di.di_size) { |
@@ -765,7 +765,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode, | |||
765 | return ERR_PTR(-EIO); | 765 | return ERR_PTR(-EIO); |
766 | } | 766 | } |
767 | 767 | ||
768 | index = name->hash >> (32 - ip->i_di.di_depth); | 768 | index = name->hash >> (32 - ip->i_depth); |
769 | error = get_first_leaf(ip, index, &bh); | 769 | error = get_first_leaf(ip, index, &bh); |
770 | if (error) | 770 | if (error) |
771 | return ERR_PTR(error); | 771 | return ERR_PTR(error); |
@@ -910,7 +910,7 @@ static int dir_make_exhash(struct inode *inode) | |||
910 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; | 910 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; |
911 | 911 | ||
912 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; | 912 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; |
913 | dip->i_di.di_depth = y; | 913 | dip->i_depth = y; |
914 | 914 | ||
915 | gfs2_dinode_out(dip, dibh->b_data); | 915 | gfs2_dinode_out(dip, dibh->b_data); |
916 | 916 | ||
@@ -941,7 +941,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
941 | int x, moved = 0; | 941 | int x, moved = 0; |
942 | int error; | 942 | int error; |
943 | 943 | ||
944 | index = name->hash >> (32 - dip->i_di.di_depth); | 944 | index = name->hash >> (32 - dip->i_depth); |
945 | error = get_leaf_nr(dip, index, &leaf_no); | 945 | error = get_leaf_nr(dip, index, &leaf_no); |
946 | if (error) | 946 | if (error) |
947 | return error; | 947 | return error; |
@@ -952,7 +952,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
952 | return error; | 952 | return error; |
953 | 953 | ||
954 | oleaf = (struct gfs2_leaf *)obh->b_data; | 954 | oleaf = (struct gfs2_leaf *)obh->b_data; |
955 | if (dip->i_di.di_depth == be16_to_cpu(oleaf->lf_depth)) { | 955 | if (dip->i_depth == be16_to_cpu(oleaf->lf_depth)) { |
956 | brelse(obh); | 956 | brelse(obh); |
957 | return 1; /* can't split */ | 957 | return 1; /* can't split */ |
958 | } | 958 | } |
@@ -967,10 +967,10 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
967 | bn = nbh->b_blocknr; | 967 | bn = nbh->b_blocknr; |
968 | 968 | ||
969 | /* Compute the start and len of leaf pointers in the hash table. */ | 969 | /* Compute the start and len of leaf pointers in the hash table. */ |
970 | len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth)); | 970 | len = 1 << (dip->i_depth - be16_to_cpu(oleaf->lf_depth)); |
971 | half_len = len >> 1; | 971 | half_len = len >> 1; |
972 | if (!half_len) { | 972 | if (!half_len) { |
973 | printk(KERN_WARNING "di_depth %u lf_depth %u index %u\n", dip->i_di.di_depth, be16_to_cpu(oleaf->lf_depth), index); | 973 | printk(KERN_WARNING "i_depth %u lf_depth %u index %u\n", dip->i_depth, be16_to_cpu(oleaf->lf_depth), index); |
974 | gfs2_consist_inode(dip); | 974 | gfs2_consist_inode(dip); |
975 | error = -EIO; | 975 | error = -EIO; |
976 | goto fail_brelse; | 976 | goto fail_brelse; |
@@ -997,7 +997,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
997 | kfree(lp); | 997 | kfree(lp); |
998 | 998 | ||
999 | /* Compute the divider */ | 999 | /* Compute the divider */ |
1000 | divider = (start + half_len) << (32 - dip->i_di.di_depth); | 1000 | divider = (start + half_len) << (32 - dip->i_depth); |
1001 | 1001 | ||
1002 | /* Copy the entries */ | 1002 | /* Copy the entries */ |
1003 | dirent_first(dip, obh, &dent); | 1003 | dirent_first(dip, obh, &dent); |
@@ -1082,7 +1082,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1082 | int x; | 1082 | int x; |
1083 | int error = 0; | 1083 | int error = 0; |
1084 | 1084 | ||
1085 | hsize = 1 << dip->i_di.di_depth; | 1085 | hsize = 1 << dip->i_depth; |
1086 | if (hsize * sizeof(u64) != dip->i_di.di_size) { | 1086 | if (hsize * sizeof(u64) != dip->i_di.di_size) { |
1087 | gfs2_consist_inode(dip); | 1087 | gfs2_consist_inode(dip); |
1088 | return -EIO; | 1088 | return -EIO; |
@@ -1125,7 +1125,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1125 | 1125 | ||
1126 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1126 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1127 | if (!gfs2_assert_withdraw(sdp, !error)) { | 1127 | if (!gfs2_assert_withdraw(sdp, !error)) { |
1128 | dip->i_di.di_depth++; | 1128 | dip->i_depth++; |
1129 | gfs2_dinode_out(dip, dibh->b_data); | 1129 | gfs2_dinode_out(dip, dibh->b_data); |
1130 | brelse(dibh); | 1130 | brelse(dibh); |
1131 | } | 1131 | } |
@@ -1370,14 +1370,14 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1370 | int error = 0; | 1370 | int error = 0; |
1371 | unsigned depth = 0; | 1371 | unsigned depth = 0; |
1372 | 1372 | ||
1373 | hsize = 1 << dip->i_di.di_depth; | 1373 | hsize = 1 << dip->i_depth; |
1374 | if (hsize * sizeof(u64) != dip->i_di.di_size) { | 1374 | if (hsize * sizeof(u64) != dip->i_di.di_size) { |
1375 | gfs2_consist_inode(dip); | 1375 | gfs2_consist_inode(dip); |
1376 | return -EIO; | 1376 | return -EIO; |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | hash = gfs2_dir_offset2hash(*offset); | 1379 | hash = gfs2_dir_offset2hash(*offset); |
1380 | index = hash >> (32 - dip->i_di.di_depth); | 1380 | index = hash >> (32 - dip->i_depth); |
1381 | 1381 | ||
1382 | lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); | 1382 | lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); |
1383 | if (!lp) | 1383 | if (!lp) |
@@ -1405,7 +1405,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1405 | if (error) | 1405 | if (error) |
1406 | break; | 1406 | break; |
1407 | 1407 | ||
1408 | len = 1 << (dip->i_di.di_depth - depth); | 1408 | len = 1 << (dip->i_depth - depth); |
1409 | index = (index & ~(len - 1)) + len; | 1409 | index = (index & ~(len - 1)) + len; |
1410 | } | 1410 | } |
1411 | 1411 | ||
@@ -1549,7 +1549,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1549 | u32 index; | 1549 | u32 index; |
1550 | u64 bn; | 1550 | u64 bn; |
1551 | 1551 | ||
1552 | index = name->hash >> (32 - ip->i_di.di_depth); | 1552 | index = name->hash >> (32 - ip->i_depth); |
1553 | error = get_first_leaf(ip, index, &obh); | 1553 | error = get_first_leaf(ip, index, &obh); |
1554 | if (error) | 1554 | if (error) |
1555 | return error; | 1555 | return error; |
@@ -1641,7 +1641,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1641 | continue; | 1641 | continue; |
1642 | if (error < 0) | 1642 | if (error < 0) |
1643 | break; | 1643 | break; |
1644 | if (ip->i_di.di_depth < GFS2_DIR_MAX_DEPTH) { | 1644 | if (ip->i_depth < GFS2_DIR_MAX_DEPTH) { |
1645 | error = dir_double_exhash(ip); | 1645 | error = dir_double_exhash(ip); |
1646 | if (error) | 1646 | if (error) |
1647 | break; | 1647 | break; |
@@ -1785,7 +1785,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1785 | u64 leaf_no; | 1785 | u64 leaf_no; |
1786 | int error = 0; | 1786 | int error = 0; |
1787 | 1787 | ||
1788 | hsize = 1 << dip->i_di.di_depth; | 1788 | hsize = 1 << dip->i_depth; |
1789 | if (hsize * sizeof(u64) != dip->i_di.di_size) { | 1789 | if (hsize * sizeof(u64) != dip->i_di.di_size) { |
1790 | gfs2_consist_inode(dip); | 1790 | gfs2_consist_inode(dip); |
1791 | return -EIO; | 1791 | return -EIO; |
@@ -1817,7 +1817,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1817 | if (error) | 1817 | if (error) |
1818 | goto out; | 1818 | goto out; |
1819 | leaf = (struct gfs2_leaf *)bh->b_data; | 1819 | leaf = (struct gfs2_leaf *)bh->b_data; |
1820 | len = 1 << (dip->i_di.di_depth - be16_to_cpu(leaf->lf_depth)); | 1820 | len = 1 << (dip->i_depth - be16_to_cpu(leaf->lf_depth)); |
1821 | brelse(bh); | 1821 | brelse(bh); |
1822 | 1822 | ||
1823 | error = lc(dip, index, len, leaf_no, data); | 1823 | error = lc(dip, index, len, leaf_no, data); |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index e9c58dc76869..9dfdde3612a4 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -246,7 +246,6 @@ struct gfs2_dinode_host { | |||
246 | u64 di_generation; /* generation number for NFS */ | 246 | u64 di_generation; /* generation number for NFS */ |
247 | u32 di_flags; /* GFS2_DIF_... */ | 247 | u32 di_flags; /* GFS2_DIF_... */ |
248 | /* These only apply to directories */ | 248 | /* These only apply to directories */ |
249 | u16 di_depth; /* Number of bits in the table */ | ||
250 | u32 di_entries; /* The number of entries in the directory */ | 249 | u32 di_entries; /* The number of entries in the directory */ |
251 | u64 di_eattr; /* extended attribute block number */ | 250 | u64 di_eattr; /* extended attribute block number */ |
252 | }; | 251 | }; |
@@ -267,6 +266,7 @@ struct gfs2_inode { | |||
267 | 266 | ||
268 | struct rw_semaphore i_rw_mutex; | 267 | struct rw_semaphore i_rw_mutex; |
269 | u8 i_height; | 268 | u8 i_height; |
269 | u8 i_depth; | ||
270 | }; | 270 | }; |
271 | 271 | ||
272 | /* | 272 | /* |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index db5961a9aa59..65fdfee9ca9b 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -248,7 +248,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
248 | { | 248 | { |
249 | struct gfs2_dinode_host *di = &ip->i_di; | 249 | struct gfs2_dinode_host *di = &ip->i_di; |
250 | const struct gfs2_dinode *str = buf; | 250 | const struct gfs2_dinode *str = buf; |
251 | u16 height; | 251 | u16 height, depth; |
252 | 252 | ||
253 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) | 253 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) |
254 | goto corrupt; | 254 | goto corrupt; |
@@ -293,7 +293,10 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
293 | goto corrupt; | 293 | goto corrupt; |
294 | ip->i_height = (u8)height; | 294 | ip->i_height = (u8)height; |
295 | 295 | ||
296 | di->di_depth = be16_to_cpu(str->di_depth); | 296 | depth = be16_to_cpu(str->di_depth); |
297 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) | ||
298 | goto corrupt; | ||
299 | ip->i_depth = (u8)depth; | ||
297 | di->di_entries = be32_to_cpu(str->di_entries); | 300 | di->di_entries = be32_to_cpu(str->di_entries); |
298 | 301 | ||
299 | di->di_eattr = be64_to_cpu(str->di_eattr); | 302 | di->di_eattr = be64_to_cpu(str->di_eattr); |
@@ -1410,7 +1413,7 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | |||
1410 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | 1413 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && |
1411 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | 1414 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? |
1412 | GFS2_FORMAT_DE : 0); | 1415 | GFS2_FORMAT_DE : 0); |
1413 | str->di_depth = cpu_to_be16(di->di_depth); | 1416 | str->di_depth = cpu_to_be16(ip->i_depth); |
1414 | str->di_entries = cpu_to_be32(di->di_entries); | 1417 | str->di_entries = cpu_to_be32(di->di_entries); |
1415 | 1418 | ||
1416 | str->di_eattr = cpu_to_be64(di->di_eattr); | 1419 | str->di_eattr = cpu_to_be64(di->di_eattr); |
@@ -1436,7 +1439,7 @@ void gfs2_dinode_print(const struct gfs2_inode *ip) | |||
1436 | (unsigned long long)di->di_goal_data); | 1439 | (unsigned long long)di->di_goal_data); |
1437 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); | 1440 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); |
1438 | printk(KERN_INFO " i_height = %u\n", ip->i_height); | 1441 | printk(KERN_INFO " i_height = %u\n", ip->i_height); |
1439 | printk(KERN_INFO " di_depth = %u\n", di->di_depth); | 1442 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); |
1440 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); | 1443 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); |
1441 | printk(KERN_INFO " di_eattr = %llu\n", | 1444 | printk(KERN_INFO " di_eattr = %llu\n", |
1442 | (unsigned long long)di->di_eattr); | 1445 | (unsigned long long)di->di_eattr); |