aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/dir.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-03-29 19:02:15 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-03-29 19:02:15 -0500
commite90deff5336ac500c65f873484c326cfa8a9d379 (patch)
tree7a9b0325148e72542b36fb8dd3dfc749ae1cf696 /fs/gfs2/dir.c
parentd0dc80dbafb5c10ad2084831a61bbf945484a139 (diff)
[GFS2] Fix bug in directory expansion code
We didn't properly check that leaf splitting was allowed. We do now. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r--fs/gfs2/dir.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index ba3438553f33..9f17e7d05af1 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -940,10 +940,15 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
940 /* Get the old leaf block */ 940 /* Get the old leaf block */
941 error = get_leaf(dip, leaf_no, &obh); 941 error = get_leaf(dip, leaf_no, &obh);
942 if (error) 942 if (error)
943 goto fail; 943 return error;
944 944
945 gfs2_trans_add_bh(dip->i_gl, obh, 1);
946 oleaf = (struct gfs2_leaf *)obh->b_data; 945 oleaf = (struct gfs2_leaf *)obh->b_data;
946 if (dip->i_di.di_depth == be16_to_cpu(oleaf->lf_depth)) {
947 brelse(obh);
948 return 1; /* can't split */
949 }
950
951 gfs2_trans_add_bh(dip->i_gl, obh, 1);
947 952
948 nleaf = new_leaf(inode, &nbh, be16_to_cpu(oleaf->lf_depth) + 1); 953 nleaf = new_leaf(inode, &nbh, be16_to_cpu(oleaf->lf_depth) + 1);
949 if (!nleaf) { 954 if (!nleaf) {
@@ -956,6 +961,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
956 len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth)); 961 len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth));
957 half_len = len >> 1; 962 half_len = len >> 1;
958 if (!half_len) { 963 if (!half_len) {
964 printk(KERN_WARNING "di_depth %u lf_depth %u index %u\n", dip->i_di.di_depth, be16_to_cpu(oleaf->lf_depth), index);
959 gfs2_consist_inode(dip); 965 gfs2_consist_inode(dip);
960 error = -EIO; 966 error = -EIO;
961 goto fail_brelse; 967 goto fail_brelse;
@@ -1038,13 +1044,11 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
1038 1044
1039 return error; 1045 return error;
1040 1046
1041 fail_lpfree: 1047fail_lpfree:
1042 kfree(lp); 1048 kfree(lp);
1043 1049
1044 fail_brelse: 1050fail_brelse:
1045 brelse(obh); 1051 brelse(obh);
1046
1047 fail:
1048 brelse(nbh); 1052 brelse(nbh);
1049 return error; 1053 return error;
1050} 1054}
@@ -1570,16 +1574,17 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1570 error = dir_split_leaf(inode, name); 1574 error = dir_split_leaf(inode, name);
1571 if (error == 0) 1575 if (error == 0)
1572 continue; 1576 continue;
1573 if (error != -ENOSPC) 1577 if (error < 0)
1574 break; 1578 break;
1575 if (ip->i_di.di_depth < GFS2_DIR_MAX_DEPTH) { 1579 if (ip->i_di.di_depth < GFS2_DIR_MAX_DEPTH) {
1576 error = dir_double_exhash(ip); 1580 error = dir_double_exhash(ip);
1577 if (error) 1581 if (error)
1578 break; 1582 break;
1579 error = dir_split_leaf(inode, name); 1583 error = dir_split_leaf(inode, name);
1580 if (error) 1584 if (error < 0)
1581 break; 1585 break;
1582 continue; 1586 if (error == 0)
1587 continue;
1583 } 1588 }
1584 error = dir_new_leaf(inode, name); 1589 error = dir_new_leaf(inode, name);
1585 if (!error) 1590 if (!error)