aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/dir.c34
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/inode.c11
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);