On Thu, 2008-07-17 at 20:35 +0200, Vegard Nossum wrote:
> Hi,
> 
> I got this on latest -git with an intentionally corrupted filesystem image:
> 
> BUG at fs/jfs/namei.c:512 assert(ip->i_nlink)

This assert shouldn't be here.  It would be better to handle this with
jfs_error(), which will mark the superblock dirty, and take appropriate
action.

> Full log at http://folk.uio.no/vegardno/linux/log-1216318656.txt, but
> I think the preceding messages are just left-overs from previous
> mount/remount attempts. I can test patches.

How about this one?  So far, compile tested only.

JFS: The kernel shouldn't trap when deleting a file with nlink == 0.

Signed-off-by: Dave Kleikamp <[EMAIL PROTECTED]>

diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 2aba823..10340be 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -508,33 +508,35 @@ static int jfs_unlink(struct inode *dip, struct dentry 
*dentry)
                IWRITE_UNLOCK(ip);
                goto out1;
        }
-
-       ASSERT(ip->i_nlink);
-
        ip->i_ctime = dip->i_ctime = dip->i_mtime = CURRENT_TIME;
        mark_inode_dirty(dip);
 
-       /* update target's inode */
-       inode_dec_link_count(ip);
+       if (ip->i_nlink == 0)
+               jfs_error(dip->i_sb, "jfs_unlink: i_nlink already zero");
+       else {
+               /* update target's inode */
+               inode_dec_link_count(ip);
 
-       /*
-        *      commit zero link count object
-        */
-       if (ip->i_nlink == 0) {
-               assert(!test_cflag(COMMIT_Nolink, ip));
-               /* free block resources */
-               if ((new_size = commitZeroLink(tid, ip)) < 0) {
-                       txAbort(tid, 1);        /* Marks FS Dirty */
-                       txEnd(tid);
-                       mutex_unlock(&JFS_IP(ip)->commit_mutex);
-                       mutex_unlock(&JFS_IP(dip)->commit_mutex);
-                       IWRITE_UNLOCK(ip);
-                       rc = new_size;
-                       goto out1;
+               /*
+                *      commit zero link count object
+                */
+               if (ip->i_nlink == 0) {
+                       assert(!test_cflag(COMMIT_Nolink, ip));
+                       /* free block resources */
+                       new_size = commitZeroLink(tid, ip);
+                       if (new_size < 0) {
+                               txAbort(tid, 1);        /* Marks FS Dirty */
+                               txEnd(tid);
+                               mutex_unlock(&JFS_IP(ip)->commit_mutex);
+                               mutex_unlock(&JFS_IP(dip)->commit_mutex);
+                               IWRITE_UNLOCK(ip);
+                               rc = new_size;
+                               goto out1;
+                       }
+                       tblk = tid_to_tblock(tid);
+                       tblk->xflag |= COMMIT_DELETE;
+                       tblk->u.ip = ip;
                }
-               tblk = tid_to_tblock(tid);
-               tblk->xflag |= COMMIT_DELETE;
-               tblk->u.ip = ip;
        }
 
        /*

-- 
David Kleikamp
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Jfs-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jfs-discussion

Reply via email to