We cannot proceed to free the blocks of the file until the dependencies
have been cleaned up by deallocte_dependencies(). Once that is done, it is safe to post the request to free the blocks. A similar change is also needed for the freefile case.
This commit is contained in:
parent
5025e9d4ec
commit
10767f840b
|
@ -52,7 +52,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* from: @(#)ffs_softdep.c 9.46 (McKusick) 1/9/00
|
* from: @(#)ffs_softdep.c 9.48 (McKusick) 1/10/00
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1657,19 +1657,7 @@ softdep_setup_freeblocks(ip, length)
|
||||||
merge_inode_lists(inodedep);
|
merge_inode_lists(inodedep);
|
||||||
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
|
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
|
||||||
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
||||||
/*
|
FREE_LOCK(&lk);
|
||||||
* Add the freeblks structure to the list of operations that
|
|
||||||
* must await the zero'ed inode being written to disk. If we
|
|
||||||
* still have a bitmap dependency, then the inode has never been
|
|
||||||
* written to disk, so we can process the freeblks immediately.
|
|
||||||
*/
|
|
||||||
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
|
||||||
FREE_LOCK(&lk);
|
|
||||||
handle_workitem_freeblocks(freeblks);
|
|
||||||
} else {
|
|
||||||
WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
|
|
||||||
FREE_LOCK(&lk);
|
|
||||||
}
|
|
||||||
bdwrite(bp);
|
bdwrite(bp);
|
||||||
/*
|
/*
|
||||||
* We must wait for any I/O in progress to finish so that
|
* We must wait for any I/O in progress to finish so that
|
||||||
|
@ -1690,11 +1678,22 @@ softdep_setup_freeblocks(ip, length)
|
||||||
ACQUIRE_LOCK(&lk);
|
ACQUIRE_LOCK(&lk);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Try freeing the inodedep in case that was the last dependency.
|
* Add the freeblks structure to the list of operations that
|
||||||
|
* must await the zero'ed inode being written to disk. If we
|
||||||
|
* still have a bitmap dependency, then the inode has never been
|
||||||
|
* written to disk, so we can process the freeblks immediately.
|
||||||
|
* If the inodedep does not exist, then the zero'ed inode has
|
||||||
|
* been written and we can also proceed.
|
||||||
*/
|
*/
|
||||||
if ((inodedep_lookup(fs, ip->i_number, 0, &inodedep)) != 0)
|
if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) == 0 ||
|
||||||
(void) free_inodedep(inodedep);
|
free_inodedep(inodedep) ||
|
||||||
FREE_LOCK(&lk);
|
(inodedep->id_state & DEPCOMPLETE) == 0) {
|
||||||
|
FREE_LOCK(&lk);
|
||||||
|
handle_workitem_freeblocks(freeblks);
|
||||||
|
} else {
|
||||||
|
WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
|
||||||
|
FREE_LOCK(&lk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1877,7 +1876,7 @@ softdep_freefile(pvp, ino, mode)
|
||||||
* written, it has been rolled back to its zero'ed state, so we
|
* written, it has been rolled back to its zero'ed state, so we
|
||||||
* are ensured that a zero inode is what is on the disk. For short
|
* are ensured that a zero inode is what is on the disk. For short
|
||||||
* lived files, this change will usually result in removing all the
|
* lived files, this change will usually result in removing all the
|
||||||
* depedencies from the inode so that it can be freed immediately.
|
* dependencies from the inode so that it can be freed immediately.
|
||||||
*/
|
*/
|
||||||
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
||||||
inodedep->id_state |= ALLCOMPLETE;
|
inodedep->id_state |= ALLCOMPLETE;
|
||||||
|
@ -2568,6 +2567,7 @@ handle_workitem_remove(dirrem)
|
||||||
struct inodedep *inodedep;
|
struct inodedep *inodedep;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
|
ino_t oldinum;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp)) != 0) {
|
if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp)) != 0) {
|
||||||
|
@ -2577,7 +2577,7 @@ handle_workitem_remove(dirrem)
|
||||||
ip = VTOI(vp);
|
ip = VTOI(vp);
|
||||||
ACQUIRE_LOCK(&lk);
|
ACQUIRE_LOCK(&lk);
|
||||||
if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0)
|
if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0)
|
||||||
panic("handle_workitem_remove: lost inodedep 1");
|
panic("handle_workitem_remove: lost inodedep");
|
||||||
/*
|
/*
|
||||||
* Normal file deletion.
|
* Normal file deletion.
|
||||||
*/
|
*/
|
||||||
|
@ -2620,6 +2620,7 @@ handle_workitem_remove(dirrem)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
* If there is no inode dependency then we can free immediately.
|
||||||
* If we still have a bitmap dependency, then the inode has never
|
* If we still have a bitmap dependency, then the inode has never
|
||||||
* been written to disk. Drop the dependency as it is no longer
|
* been written to disk. Drop the dependency as it is no longer
|
||||||
* necessary since the inode is being deallocated. We set the
|
* necessary since the inode is being deallocated. We set the
|
||||||
|
@ -2628,28 +2629,30 @@ handle_workitem_remove(dirrem)
|
||||||
* written, it has been rolled back to its zero'ed state, so we
|
* written, it has been rolled back to its zero'ed state, so we
|
||||||
* are ensured that a zero inode is what is on the disk. For short
|
* are ensured that a zero inode is what is on the disk. For short
|
||||||
* lived files, this change will usually result in removing all the
|
* lived files, this change will usually result in removing all the
|
||||||
* depedencies from the inode so that it can be freed immediately.
|
* dependencies from the inode so that it can be freed immediately.
|
||||||
*/
|
*/
|
||||||
ACQUIRE_LOCK(&lk);
|
ACQUIRE_LOCK(&lk);
|
||||||
if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0)
|
dirrem->dm_state = 0;
|
||||||
panic("handle_workitem_remove: lost inodedep 2");
|
oldinum = dirrem->dm_oldinum;
|
||||||
|
dirrem->dm_oldinum = dirrem->dm_dirinum;
|
||||||
|
if ((inodedep_lookup(ip->i_fs, oldinum, 0, &inodedep)) == 0)
|
||||||
|
goto out;
|
||||||
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
||||||
inodedep->id_state |= ALLCOMPLETE;
|
inodedep->id_state |= ALLCOMPLETE;
|
||||||
LIST_REMOVE(inodedep, id_deps);
|
LIST_REMOVE(inodedep, id_deps);
|
||||||
inodedep->id_buf = NULL;
|
inodedep->id_buf = NULL;
|
||||||
WORKLIST_REMOVE(&inodedep->id_list);
|
WORKLIST_REMOVE(&inodedep->id_list);
|
||||||
}
|
}
|
||||||
dirrem->dm_state = 0;
|
|
||||||
dirrem->dm_oldinum = dirrem->dm_dirinum;
|
|
||||||
if (free_inodedep(inodedep) == 0) {
|
if (free_inodedep(inodedep) == 0) {
|
||||||
WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
|
WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
|
||||||
FREE_LOCK(&lk);
|
FREE_LOCK(&lk);
|
||||||
vput(vp);
|
vput(vp);
|
||||||
} else {
|
return;
|
||||||
FREE_LOCK(&lk);
|
|
||||||
vput(vp);
|
|
||||||
handle_workitem_remove(dirrem);
|
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
FREE_LOCK(&lk);
|
||||||
|
vput(vp);
|
||||||
|
handle_workitem_remove(dirrem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* from: @(#)ffs_softdep.c 9.46 (McKusick) 1/9/00
|
* from: @(#)ffs_softdep.c 9.48 (McKusick) 1/10/00
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1657,19 +1657,7 @@ softdep_setup_freeblocks(ip, length)
|
||||||
merge_inode_lists(inodedep);
|
merge_inode_lists(inodedep);
|
||||||
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
|
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
|
||||||
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
free_allocdirect(&inodedep->id_inoupdt, adp, 1);
|
||||||
/*
|
FREE_LOCK(&lk);
|
||||||
* Add the freeblks structure to the list of operations that
|
|
||||||
* must await the zero'ed inode being written to disk. If we
|
|
||||||
* still have a bitmap dependency, then the inode has never been
|
|
||||||
* written to disk, so we can process the freeblks immediately.
|
|
||||||
*/
|
|
||||||
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
|
||||||
FREE_LOCK(&lk);
|
|
||||||
handle_workitem_freeblocks(freeblks);
|
|
||||||
} else {
|
|
||||||
WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
|
|
||||||
FREE_LOCK(&lk);
|
|
||||||
}
|
|
||||||
bdwrite(bp);
|
bdwrite(bp);
|
||||||
/*
|
/*
|
||||||
* We must wait for any I/O in progress to finish so that
|
* We must wait for any I/O in progress to finish so that
|
||||||
|
@ -1690,11 +1678,22 @@ softdep_setup_freeblocks(ip, length)
|
||||||
ACQUIRE_LOCK(&lk);
|
ACQUIRE_LOCK(&lk);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Try freeing the inodedep in case that was the last dependency.
|
* Add the freeblks structure to the list of operations that
|
||||||
|
* must await the zero'ed inode being written to disk. If we
|
||||||
|
* still have a bitmap dependency, then the inode has never been
|
||||||
|
* written to disk, so we can process the freeblks immediately.
|
||||||
|
* If the inodedep does not exist, then the zero'ed inode has
|
||||||
|
* been written and we can also proceed.
|
||||||
*/
|
*/
|
||||||
if ((inodedep_lookup(fs, ip->i_number, 0, &inodedep)) != 0)
|
if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) == 0 ||
|
||||||
(void) free_inodedep(inodedep);
|
free_inodedep(inodedep) ||
|
||||||
FREE_LOCK(&lk);
|
(inodedep->id_state & DEPCOMPLETE) == 0) {
|
||||||
|
FREE_LOCK(&lk);
|
||||||
|
handle_workitem_freeblocks(freeblks);
|
||||||
|
} else {
|
||||||
|
WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
|
||||||
|
FREE_LOCK(&lk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1877,7 +1876,7 @@ softdep_freefile(pvp, ino, mode)
|
||||||
* written, it has been rolled back to its zero'ed state, so we
|
* written, it has been rolled back to its zero'ed state, so we
|
||||||
* are ensured that a zero inode is what is on the disk. For short
|
* are ensured that a zero inode is what is on the disk. For short
|
||||||
* lived files, this change will usually result in removing all the
|
* lived files, this change will usually result in removing all the
|
||||||
* depedencies from the inode so that it can be freed immediately.
|
* dependencies from the inode so that it can be freed immediately.
|
||||||
*/
|
*/
|
||||||
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
||||||
inodedep->id_state |= ALLCOMPLETE;
|
inodedep->id_state |= ALLCOMPLETE;
|
||||||
|
@ -2568,6 +2567,7 @@ handle_workitem_remove(dirrem)
|
||||||
struct inodedep *inodedep;
|
struct inodedep *inodedep;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
|
ino_t oldinum;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp)) != 0) {
|
if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp)) != 0) {
|
||||||
|
@ -2577,7 +2577,7 @@ handle_workitem_remove(dirrem)
|
||||||
ip = VTOI(vp);
|
ip = VTOI(vp);
|
||||||
ACQUIRE_LOCK(&lk);
|
ACQUIRE_LOCK(&lk);
|
||||||
if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0)
|
if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0)
|
||||||
panic("handle_workitem_remove: lost inodedep 1");
|
panic("handle_workitem_remove: lost inodedep");
|
||||||
/*
|
/*
|
||||||
* Normal file deletion.
|
* Normal file deletion.
|
||||||
*/
|
*/
|
||||||
|
@ -2620,6 +2620,7 @@ handle_workitem_remove(dirrem)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
* If there is no inode dependency then we can free immediately.
|
||||||
* If we still have a bitmap dependency, then the inode has never
|
* If we still have a bitmap dependency, then the inode has never
|
||||||
* been written to disk. Drop the dependency as it is no longer
|
* been written to disk. Drop the dependency as it is no longer
|
||||||
* necessary since the inode is being deallocated. We set the
|
* necessary since the inode is being deallocated. We set the
|
||||||
|
@ -2628,28 +2629,30 @@ handle_workitem_remove(dirrem)
|
||||||
* written, it has been rolled back to its zero'ed state, so we
|
* written, it has been rolled back to its zero'ed state, so we
|
||||||
* are ensured that a zero inode is what is on the disk. For short
|
* are ensured that a zero inode is what is on the disk. For short
|
||||||
* lived files, this change will usually result in removing all the
|
* lived files, this change will usually result in removing all the
|
||||||
* depedencies from the inode so that it can be freed immediately.
|
* dependencies from the inode so that it can be freed immediately.
|
||||||
*/
|
*/
|
||||||
ACQUIRE_LOCK(&lk);
|
ACQUIRE_LOCK(&lk);
|
||||||
if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0)
|
dirrem->dm_state = 0;
|
||||||
panic("handle_workitem_remove: lost inodedep 2");
|
oldinum = dirrem->dm_oldinum;
|
||||||
|
dirrem->dm_oldinum = dirrem->dm_dirinum;
|
||||||
|
if ((inodedep_lookup(ip->i_fs, oldinum, 0, &inodedep)) == 0)
|
||||||
|
goto out;
|
||||||
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
if ((inodedep->id_state & DEPCOMPLETE) == 0) {
|
||||||
inodedep->id_state |= ALLCOMPLETE;
|
inodedep->id_state |= ALLCOMPLETE;
|
||||||
LIST_REMOVE(inodedep, id_deps);
|
LIST_REMOVE(inodedep, id_deps);
|
||||||
inodedep->id_buf = NULL;
|
inodedep->id_buf = NULL;
|
||||||
WORKLIST_REMOVE(&inodedep->id_list);
|
WORKLIST_REMOVE(&inodedep->id_list);
|
||||||
}
|
}
|
||||||
dirrem->dm_state = 0;
|
|
||||||
dirrem->dm_oldinum = dirrem->dm_dirinum;
|
|
||||||
if (free_inodedep(inodedep) == 0) {
|
if (free_inodedep(inodedep) == 0) {
|
||||||
WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
|
WORKLIST_INSERT(&inodedep->id_inowait, &dirrem->dm_list);
|
||||||
FREE_LOCK(&lk);
|
FREE_LOCK(&lk);
|
||||||
vput(vp);
|
vput(vp);
|
||||||
} else {
|
return;
|
||||||
FREE_LOCK(&lk);
|
|
||||||
vput(vp);
|
|
||||||
handle_workitem_remove(dirrem);
|
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
FREE_LOCK(&lk);
|
||||||
|
vput(vp);
|
||||||
|
handle_workitem_remove(dirrem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue