Source-Changes-HG archive

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

[src/trunk]: src/sys/ufs/lfs Since dirop vnodes can't be flushed, they hold a...



details:   https://anonhg.NetBSD.org/src/rev/cbdf0f1c26a2
branches:  trunk
changeset: 467554:cbdf0f1c26a2
user:      perseant <perseant%NetBSD.org@localhost>
date:      Thu Mar 25 22:33:03 1999 +0000

description:
Since dirop vnodes can't be flushed, they hold a reference until their
dirop is completely written to disk.  This means that ordinary calls to
ufs vnops which would ordinarily call VOP_INACTIVE through vrele/vput,
don't.  This patch detects that condition after such vnops have been
run, and calls VOP_INACTIVE if it would ordinarily have been called by
the ufs call.

diffstat:

 sys/ufs/lfs/lfs_vnops.c |  109 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 75 insertions(+), 34 deletions(-)

diffs (219 lines):

diff -r c2f674fb52e5 -r cbdf0f1c26a2 sys/ufs/lfs/lfs_vnops.c
--- a/sys/ufs/lfs/lfs_vnops.c   Thu Mar 25 22:26:52 1999 +0000
+++ b/sys/ufs/lfs/lfs_vnops.c   Thu Mar 25 22:33:03 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_vnops.c,v 1.23 1999/03/25 21:39:19 perseant Exp $  */
+/*     $NetBSD: lfs_vnops.c,v 1.24 1999/03/25 22:33:03 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -288,25 +288,40 @@
  * We do this by setting lfs_dirvcount to the number of marked vnodes; it
  * is decremented during segment write, when VDIROP is taken off.
  */
-#define        SET_DIROP(fs) {                                                 \
-       while ((fs)->lfs_writer || (fs)->lfs_dirvcount>LFS_MAXDIROP) {  \
-               if((fs)->lfs_writer)                                    \
-                       tsleep(&(fs)->lfs_dirops, PRIBIO + 1, "lfs_dirop", 0);\
-               if((fs)->lfs_dirvcount > LFS_MAXDIROP) {                \
-                       printf("(dirvcount=%d)\n",(fs)->lfs_dirvcount); \
-                       tsleep(&(fs)->lfs_dirvcount, PRIBIO + 1, "lfs_maxdirop", 0);\
-               }                                                       \
-       }                                                               \
-       ++(fs)->lfs_dirops;                                             \
-       (fs)->lfs_doifile = 1;                                          \
+#define        SET_DIROP(fs) lfs_set_dirop(fs)
+static int lfs_set_dirop __P((struct lfs *));
+
+static int lfs_set_dirop(fs)
+       struct lfs *fs;
+{
+       int error;
+
+       while (fs->lfs_writer || fs->lfs_dirvcount>LFS_MAXDIROP) {
+               if(fs->lfs_writer)
+                       tsleep(&fs->lfs_dirops, PRIBIO + 1, "lfs_dirop", 0);
+               if(fs->lfs_dirvcount > LFS_MAXDIROP) {          
+#ifdef DEBUG_LFS
+                       printf("(dirvcount=%d)\n",fs->lfs_dirvcount); 
+#endif
+                       if((error=tsleep(&fs->lfs_dirvcount, PCATCH|PUSER, "lfs_maxdirop", 0))!=0)
+                               return error;
+               }                                                       
+       }                                                               
+       ++fs->lfs_dirops;                                               
+       fs->lfs_doifile = 1;                                            
+
+       return 0;
 }
 
-#define        SET_ENDOP(fs) {                                                 \
+#define        SET_ENDOP(fs,str) {                                             \
        --(fs)->lfs_dirops;                                             \
        if (!(fs)->lfs_dirops) {                                        \
                wakeup(&(fs)->lfs_writer);                              \
-               if ((fs)->lfs_dirvcount > LFS_MAXDIROP)                 \
-                       lfs_flush((fs),0);                              \
+               if ((fs)->lfs_dirvcount > LFS_MAXDIROP) {               \
+                       ++(fs)->lfs_writer;                             \
+                       lfs_flush((fs),0);                              \
+                       --(fs)->lfs_writer;                             \
+               }                                                       \
        }                                                               \
 }
 
@@ -318,6 +333,16 @@
         (dvp)->v_flag |= VDIROP;                                       \
 } while(0)
 
+#define MAYBE_INACTIVE(fs,vp) do {                                      \
+        if((vp) && ((vp)->v_flag & VDIROP) && (vp)->v_usecount == 1     \
+           && VTOI(vp) && VTOI(vp)->i_ffs_nlink == 0)                   \
+        {                                                               \
+               if (VOP_LOCK((vp), LK_EXCLUSIVE) == 0) {                \
+                        VOP_INACTIVE((vp),curproc);                     \
+               }                                                       \
+        }                                                               \
+} while(0)
+
 int
 lfs_symlink(v)
        void *v;
@@ -331,10 +356,12 @@
        } */ *ap = v;
        int ret;
 
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        ret = ufs_symlink(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,*(ap->a_vpp)); /* XXX KS */
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"symilnk");
        return (ret);
 }
 
@@ -350,10 +377,12 @@
                } */ *ap = v;
        int ret;
 
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        ret = ufs_mknod(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,*(ap->a_vpp)); /* XXX KS */
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"mknod");
        return (ret);
 }
 
@@ -369,10 +398,12 @@
        } */ *ap = v;
        int ret;
 
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        ret = ufs_create(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,*(ap->a_vpp)); /* XXX KS */
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"create");
        return (ret);
 }
 
@@ -387,10 +418,11 @@
        } */ *ap = v;
        int ret;
 
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        ret = ufs_whiteout(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"whiteout");
        return (ret);
 }
 
@@ -406,10 +438,12 @@
        } */ *ap = v;
        int ret;
 
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        ret = ufs_mkdir(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,*(ap->a_vpp)); /* XXX KS */
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"mkdir");
        return (ret);
 }
 
@@ -423,12 +457,13 @@
                struct componentname *a_cnp;
        } */ *ap = v;
        int ret;
-
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        MARK_VNODE(ap->a_vp);
        ret = ufs_remove(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,ap->a_vp);
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"remove");
        return (ret);
 }
 
@@ -444,11 +479,13 @@
        } */ *ap = v;
        int ret;
 
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        MARK_VNODE(ap->a_vp);
        ret = ufs_rmdir(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,ap->a_vp);
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"rmdir");
        return (ret);
 }
 
@@ -463,10 +500,11 @@
        } */ *ap = v;
        int ret;
 
-       SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_dvp);
        ret = ufs_link(ap);
-       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
+       SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,"link");
        return (ret);
 }
 
@@ -484,11 +522,14 @@
        } */ *ap = v;
        int ret;
        
-       SET_DIROP(VTOI(ap->a_fdvp)->i_lfs);
+       if((ret=SET_DIROP(VTOI(ap->a_fdvp)->i_lfs))!=0)
+               return ret;
        MARK_VNODE(ap->a_fdvp);
        MARK_VNODE(ap->a_tdvp);
        ret = ufs_rename(ap);
-       SET_ENDOP(VTOI(ap->a_fdvp)->i_lfs);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,ap->a_fvp);
+       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,ap->a_tvp);
+       SET_ENDOP(VTOI(ap->a_fdvp)->i_lfs,"rename");
        return (ret);
 }
 



Home | Main Index | Thread Index | Old Index