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.
This commit is contained in:
parent
a3748f1cc7
commit
cffa290130
|
@ -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 @@ lfs_fsync(v)
|
|||
* 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 @@ lfs_fsync(v)
|
|||
(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 @@ lfs_symlink(v)
|
|||
} */ *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 @@ lfs_mknod(v)
|
|||
} */ *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 @@ lfs_create(v)
|
|||
} */ *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 @@ lfs_whiteout(v)
|
|||
} */ *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 @@ lfs_mkdir(v)
|
|||
} */ *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 @@ lfs_remove(v)
|
|||
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 @@ lfs_rmdir(v)
|
|||
} */ *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 @@ lfs_link(v)
|
|||
} */ *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 @@ lfs_rename(v)
|
|||
} */ *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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue