aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-11-17 12:27:44 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-11-30 10:36:20 -0500
commit5e7d65cd9d3819512b059f4260de0119b985454c (patch)
treef6e09c9eff9dfa4197cc6da8d153f314737026db /fs
parentdcd2479959c79d44f5dd77e71672e70f1f8b1f06 (diff)
[GFS2] Make sentinel dirents compatible with gfs1
When deleting directory entries, we set the inum.no_addr to zero in a dirent when its the first dirent in a block and thus cannot be merged into the previous dirent as is the usual case. In gfs1, inum.no_formal_ino was used instead. This patch changes gfs2 to set both inum.no_addr and inum.no_formal_ino to zero. It also changes the test from just looking at inum.no_addr to look at both inum.no_addr and inum.no_formal_ino and a sentinel is now considered to be a dirent in which _either_ (or both) of them is set to zero. This resolves Red Hat bugzillas: #215809, #211465 Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/dir.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index a2923fb91bba..0fdcb7713cd9 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -340,10 +340,15 @@ fail:
340 return (copied) ? copied : error; 340 return (copied) ? copied : error;
341} 341}
342 342
343static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent)
344{
345 return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0;
346}
347
343static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, 348static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent,
344 const struct qstr *name, int ret) 349 const struct qstr *name, int ret)
345{ 350{
346 if (dent->de_inum.no_addr != 0 && 351 if (!gfs2_dirent_sentinel(dent) &&
347 be32_to_cpu(dent->de_hash) == name->hash && 352 be32_to_cpu(dent->de_hash) == name->hash &&
348 be16_to_cpu(dent->de_name_len) == name->len && 353 be16_to_cpu(dent->de_name_len) == name->len &&
349 memcmp(dent+1, name->name, name->len) == 0) 354 memcmp(dent+1, name->name, name->len) == 0)
@@ -388,7 +393,7 @@ static int gfs2_dirent_find_space(const struct gfs2_dirent *dent,
388 unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); 393 unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
389 unsigned totlen = be16_to_cpu(dent->de_rec_len); 394 unsigned totlen = be16_to_cpu(dent->de_rec_len);
390 395
391 if (!dent->de_inum.no_addr) 396 if (gfs2_dirent_sentinel(dent))
392 actual = GFS2_DIRENT_SIZE(0); 397 actual = GFS2_DIRENT_SIZE(0);
393 if (totlen - actual >= required) 398 if (totlen - actual >= required)
394 return 1; 399 return 1;
@@ -405,7 +410,7 @@ static int gfs2_dirent_gather(const struct gfs2_dirent *dent,
405 void *opaque) 410 void *opaque)
406{ 411{
407 struct dirent_gather *g = opaque; 412 struct dirent_gather *g = opaque;
408 if (dent->de_inum.no_addr) { 413 if (!gfs2_dirent_sentinel(dent)) {
409 g->pdent[g->offset++] = dent; 414 g->pdent[g->offset++] = dent;
410 } 415 }
411 return 0; 416 return 0;
@@ -433,10 +438,10 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset,
433 if (unlikely(offset + size > len)) 438 if (unlikely(offset + size > len))
434 goto error; 439 goto error;
435 msg = "zero inode number"; 440 msg = "zero inode number";
436 if (unlikely(!first && !dent->de_inum.no_addr)) 441 if (unlikely(!first && gfs2_dirent_sentinel(dent)))
437 goto error; 442 goto error;
438 msg = "name length is greater than space in dirent"; 443 msg = "name length is greater than space in dirent";
439 if (dent->de_inum.no_addr && 444 if (!gfs2_dirent_sentinel(dent) &&
440 unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) > 445 unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) >
441 size)) 446 size))
442 goto error; 447 goto error;
@@ -598,7 +603,7 @@ static int dirent_next(struct gfs2_inode *dip, struct buffer_head *bh,
598 return ret; 603 return ret;
599 604
600 /* Only the first dent could ever have de_inum.no_addr == 0 */ 605 /* Only the first dent could ever have de_inum.no_addr == 0 */
601 if (!tmp->de_inum.no_addr) { 606 if (gfs2_dirent_sentinel(tmp)) {
602 gfs2_consist_inode(dip); 607 gfs2_consist_inode(dip);
603 return -EIO; 608 return -EIO;
604 } 609 }
@@ -621,7 +626,7 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh,
621{ 626{
622 u16 cur_rec_len, prev_rec_len; 627 u16 cur_rec_len, prev_rec_len;
623 628
624 if (!cur->de_inum.no_addr) { 629 if (gfs2_dirent_sentinel(cur)) {
625 gfs2_consist_inode(dip); 630 gfs2_consist_inode(dip);
626 return; 631 return;
627 } 632 }
@@ -633,7 +638,8 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh,
633 out the inode number and return. */ 638 out the inode number and return. */
634 639
635 if (!prev) { 640 if (!prev) {
636 cur->de_inum.no_addr = 0; /* No endianess worries */ 641 cur->de_inum.no_addr = 0;
642 cur->de_inum.no_formal_ino = 0;
637 return; 643 return;
638 } 644 }
639 645
@@ -664,7 +670,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode,
664 struct gfs2_dirent *ndent; 670 struct gfs2_dirent *ndent;
665 unsigned offset = 0, totlen; 671 unsigned offset = 0, totlen;
666 672
667 if (dent->de_inum.no_addr) 673 if (!gfs2_dirent_sentinel(dent))
668 offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); 674 offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
669 totlen = be16_to_cpu(dent->de_rec_len); 675 totlen = be16_to_cpu(dent->de_rec_len);
670 BUG_ON(offset + name->len > totlen); 676 BUG_ON(offset + name->len > totlen);
@@ -1002,7 +1008,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
1002 if (dirent_next(dip, obh, &next)) 1008 if (dirent_next(dip, obh, &next))
1003 next = NULL; 1009 next = NULL;
1004 1010
1005 if (dent->de_inum.no_addr && 1011 if (!gfs2_dirent_sentinel(dent) &&
1006 be32_to_cpu(dent->de_hash) < divider) { 1012 be32_to_cpu(dent->de_hash) < divider) {
1007 struct qstr str; 1013 struct qstr str;
1008 str.name = (char*)(dent+1); 1014 str.name = (char*)(dent+1);