mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 07:31:11 +00:00
Delay freeing disk space for file system blocks until all dirty buffers
are safely released. This fixes softdep problems on truncation (deletion) of files with dirty buffers. Reviewed by: jeff@, mckusick@, ps@, tegge@ Tested by: glebius@, ps@ MFC after: 3 weeks
This commit is contained in:
parent
4442c32be7
commit
ed8938e082
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=148608
|
@ -2045,6 +2045,7 @@ softdep_setup_freeblocks(ip, length, flags)
|
|||
MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
|
||||
M_FREEBLKS, M_SOFTDEP_FLAGS|M_ZERO);
|
||||
freeblks->fb_list.wk_type = D_FREEBLKS;
|
||||
freeblks->fb_state = ATTACHED;
|
||||
freeblks->fb_uid = ip->i_uid;
|
||||
freeblks->fb_previousinum = ip->i_number;
|
||||
freeblks->fb_devvp = ip->i_devvp;
|
||||
|
@ -2180,6 +2181,20 @@ softdep_setup_freeblocks(ip, length, flags)
|
|||
ACQUIRE_LOCK(&lk);
|
||||
if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) != 0)
|
||||
(void) free_inodedep(inodedep);
|
||||
|
||||
if(delay) {
|
||||
freeblks->fb_state |= DEPCOMPLETE;
|
||||
/*
|
||||
* If the inode with zeroed block pointers is now on disk
|
||||
* we can start freeing blocks. Add freeblks to the worklist
|
||||
* instead of calling handle_workitem_freeblocks directly as
|
||||
* it is more likely that additional IO is needed to complete
|
||||
* the request here than in the !delay case.
|
||||
*/
|
||||
if ((freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE)
|
||||
add_to_worklist(&freeblks->fb_list);
|
||||
}
|
||||
|
||||
FREE_LOCK(&lk);
|
||||
/*
|
||||
* If the inode has never been written to disk (delay == 0),
|
||||
|
@ -4425,6 +4440,10 @@ handle_written_inodeblock(inodedep, bp)
|
|||
continue;
|
||||
|
||||
case D_FREEBLKS:
|
||||
wk->wk_state |= COMPLETE;
|
||||
if ((wk->wk_state & ALLCOMPLETE) != ALLCOMPLETE)
|
||||
continue;
|
||||
/* -- fall through -- */
|
||||
case D_FREEFRAG:
|
||||
case D_DIRREM:
|
||||
add_to_worklist(wk);
|
||||
|
|
|
@ -429,6 +429,7 @@ struct freefrag {
|
|||
*/
|
||||
struct freeblks {
|
||||
struct worklist fb_list; /* id_inowait or delayed worklist */
|
||||
# define fb_state fb_list.wk_state /* inode and dirty block state */
|
||||
ino_t fb_previousinum; /* inode of previous owner of blocks */
|
||||
uid_t fb_uid; /* uid of previous owner of blocks */
|
||||
struct vnode *fb_devvp; /* filesystem device vnode */
|
||||
|
|
Loading…
Reference in a new issue