tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

extended attributes and WAPBL interlock



Hi

When using extended attributes and WAPBL, a process may sleep forever 
in the kernel because of a locking protocol issue.

Here is the relevant part of the backtrace:
  wapbl_begin
  ffs_write
  VOP_WRITE
  ufs_extattr_rm
  ufs_extattr_vnode_inactive
  ufs_inactive
  VOP_INACTIVE

And this is wrong since ufs_inactive() already called UFS_WAPBL_BEGIN()
before calling ufs_extattr_vnode_inactive(). The lock is already set.

A straightforward fix would be to alter the order of UFS_WAPBL_BEGIN()
and ufs_extattr_vnode_inactive(), like in the patch below.

That does not seems sane by the way, as I get console warnings:
ufs_extattr_get (/export/wd1a): inode gen inconsistency (1398991653, 1398991652)
ufs_extattr_get (/export/wd1a): inode gen inconsistency (1398991653, 1398991652)

I have no idea what is means. Any advice on how to handle this?


--- src/sys/ufs/ufs/ufs_inode.c.orig    2011-05-13 10:12:19.000000000 +0200
+++ src/sys/ufs/ufs/ufs_inode.c 2011-05-13 10:12:44.000000000 +0200
@@ -101,18 +101,18 @@
        if (ip->i_ffs_effnlink == 0 && DOINGSOFTDEP(vp))
                softdep_releasefile(ip);
 
        if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+#ifdef UFS_EXTATTR
+               ufs_extattr_vnode_inactive(vp, curlwp);
+#endif
                error = UFS_WAPBL_BEGIN(vp->v_mount);
                if (error)
                        goto out;
                logged = 1;
 #ifdef QUOTA
                (void)chkiq(ip, -1, NOCRED, 0);
 #endif
-#ifdef UFS_EXTATTR
-               ufs_extattr_vnode_inactive(vp, curlwp);
-#endif
                if (ip->i_size != 0) {
                        /*
                         * When journaling, only truncate one indirect block
                         * at a time


-- 
Emmanuel Dreyfus
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index