softdep.h (92462) | softdep.h (98542) |
---|---|
1/* 2 * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved. 3 * 4 * The soft updates code is derived from the appendix of a University 5 * of Michigan technical report (Gregory R. Ganger and Yale N. Patt, 6 * "Soft Updates: A Solution to the Metadata Update Problem in File 7 * Systems", CSE-TR-254-95, August 1995). 8 * --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)softdep.h 9.7 (McKusick) 6/21/00 | 1/* 2 * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved. 3 * 4 * The soft updates code is derived from the appendix of a University 5 * of Michigan technical report (Gregory R. Ganger and Yale N. Patt, 6 * "Soft Updates: A Solution to the Metadata Update Problem in File 7 * Systems", CSE-TR-254-95, August 1995). 8 * --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)softdep.h 9.7 (McKusick) 6/21/00 |
39 * $FreeBSD: head/sys/ufs/ffs/softdep.h 92462 2002-03-17 01:25:47Z mckusick $ | 39 * $FreeBSD: head/sys/ufs/ffs/softdep.h 98542 2002-06-21 06:18:05Z mckusick $ |
40 */ 41 42#include <sys/queue.h> 43 44/* 45 * Allocation dependencies are handled with undo/redo on the in-memory 46 * copy of the data. A particular data dependency is eliminated when 47 * it is ALLCOMPLETE: that is ATTACHED, DEPCOMPLETE, and COMPLETE. --- 33 unchanged lines hidden (view full) --- 81 * reference count decrement. The GOINGAWAY flag indicates that the 82 * data structure is frozen from further change until its dependencies 83 * have been completed and its resources freed after which it will be 84 * discarded. The IOSTARTED flag prevents multiple calls to the I/O 85 * start routine from doing multiple rollbacks. The SPACECOUNTED flag 86 * says that the files space has been accounted to the pending free 87 * space count. The NEWBLOCK flag marks pagedep structures that have 88 * just been allocated, so must be claimed by the inode before all | 40 */ 41 42#include <sys/queue.h> 43 44/* 45 * Allocation dependencies are handled with undo/redo on the in-memory 46 * copy of the data. A particular data dependency is eliminated when 47 * it is ALLCOMPLETE: that is ATTACHED, DEPCOMPLETE, and COMPLETE. --- 33 unchanged lines hidden (view full) --- 81 * reference count decrement. The GOINGAWAY flag indicates that the 82 * data structure is frozen from further change until its dependencies 83 * have been completed and its resources freed after which it will be 84 * discarded. The IOSTARTED flag prevents multiple calls to the I/O 85 * start routine from doing multiple rollbacks. The SPACECOUNTED flag 86 * says that the files space has been accounted to the pending free 87 * space count. The NEWBLOCK flag marks pagedep structures that have 88 * just been allocated, so must be claimed by the inode before all |
89 * dependencies are complete. The ONWORKLIST flag shows whether the 90 * structure is currently linked onto a worklist. | 89 * dependencies are complete. The INPROGRESS flag marks worklist 90 * structures that are still on the worklist, but are being considered 91 * for action by some process. The UFS1FMT flag indicates that the 92 * inode being processed is a ufs1 format. The ONWORKLIST flag shows 93 * whether the structure is currently linked onto a worklist. |
91 */ 92#define ATTACHED 0x0001 93#define UNDONE 0x0002 94#define COMPLETE 0x0004 95#define DEPCOMPLETE 0x0008 96#define MKDIR_PARENT 0x0010 /* diradd & mkdir only */ 97#define MKDIR_BODY 0x0020 /* diradd & mkdir only */ 98#define RMDIR 0x0040 /* dirrem only */ 99#define DIRCHG 0x0080 /* diradd & dirrem only */ 100#define GOINGAWAY 0x0100 /* indirdep only */ 101#define IOSTARTED 0x0200 /* inodedep & pagedep only */ 102#define SPACECOUNTED 0x0400 /* inodedep only */ 103#define NEWBLOCK 0x0800 /* pagedep only */ 104#define INPROGRESS 0x1000 /* dirrem, freeblks, freefrag, freefile only */ | 94 */ 95#define ATTACHED 0x0001 96#define UNDONE 0x0002 97#define COMPLETE 0x0004 98#define DEPCOMPLETE 0x0008 99#define MKDIR_PARENT 0x0010 /* diradd & mkdir only */ 100#define MKDIR_BODY 0x0020 /* diradd & mkdir only */ 101#define RMDIR 0x0040 /* dirrem only */ 102#define DIRCHG 0x0080 /* diradd & dirrem only */ 103#define GOINGAWAY 0x0100 /* indirdep only */ 104#define IOSTARTED 0x0200 /* inodedep & pagedep only */ 105#define SPACECOUNTED 0x0400 /* inodedep only */ 106#define NEWBLOCK 0x0800 /* pagedep only */ 107#define INPROGRESS 0x1000 /* dirrem, freeblks, freefrag, freefile only */ |
108#define UFS1FMT 0x2000 /* indirdep only */ |
|
105#define ONWORKLIST 0x8000 106 107#define ALLCOMPLETE (ATTACHED | COMPLETE | DEPCOMPLETE) 108 109/* 110 * The workitem queue. 111 * 112 * It is sometimes useful and/or necessary to clean up certain dependencies --- 59 unchanged lines hidden (view full) --- 172 * being created, several lists are maintained hashed on bits of the 173 * offset of the entry into the directory page to keep the lists from 174 * getting too long. Once a new directory entry has been cleared to 175 * be written, it is moved to the pd_pendinghd list. After the new 176 * entry has been written to disk it is removed from the pd_pendinghd 177 * list, any removed operations are done, and the dependency structure 178 * is freed. 179 */ | 109#define ONWORKLIST 0x8000 110 111#define ALLCOMPLETE (ATTACHED | COMPLETE | DEPCOMPLETE) 112 113/* 114 * The workitem queue. 115 * 116 * It is sometimes useful and/or necessary to clean up certain dependencies --- 59 unchanged lines hidden (view full) --- 176 * being created, several lists are maintained hashed on bits of the 177 * offset of the entry into the directory page to keep the lists from 178 * getting too long. Once a new directory entry has been cleared to 179 * be written, it is moved to the pd_pendinghd list. After the new 180 * entry has been written to disk it is removed from the pd_pendinghd 181 * list, any removed operations are done, and the dependency structure 182 * is freed. 183 */ |
180#define DAHASHSZ 6 | 184#define DAHASHSZ 5 |
181#define DIRADDHASH(offset) (((offset) >> 2) % DAHASHSZ) 182struct pagedep { 183 struct worklist pd_list; /* page buffer */ 184# define pd_state pd_list.wk_state /* check for multiple I/O starts */ 185 LIST_ENTRY(pagedep) pd_hash; /* hashed lookup */ 186 struct mount *pd_mnt; /* associated mount point */ 187 ino_t pd_ino; /* associated file */ 188 ufs_lbn_t pd_lbn; /* block within file */ --- 51 unchanged lines hidden (view full) --- 240 */ 241struct inodedep { 242 struct worklist id_list; /* buffer holding inode block */ 243# define id_state id_list.wk_state /* inode dependency state */ 244 LIST_ENTRY(inodedep) id_hash; /* hashed lookup */ 245 struct fs *id_fs; /* associated filesystem */ 246 ino_t id_ino; /* dependent inode */ 247 nlink_t id_nlinkdelta; /* saved effective link count */ | 185#define DIRADDHASH(offset) (((offset) >> 2) % DAHASHSZ) 186struct pagedep { 187 struct worklist pd_list; /* page buffer */ 188# define pd_state pd_list.wk_state /* check for multiple I/O starts */ 189 LIST_ENTRY(pagedep) pd_hash; /* hashed lookup */ 190 struct mount *pd_mnt; /* associated mount point */ 191 ino_t pd_ino; /* associated file */ 192 ufs_lbn_t pd_lbn; /* block within file */ --- 51 unchanged lines hidden (view full) --- 244 */ 245struct inodedep { 246 struct worklist id_list; /* buffer holding inode block */ 247# define id_state id_list.wk_state /* inode dependency state */ 248 LIST_ENTRY(inodedep) id_hash; /* hashed lookup */ 249 struct fs *id_fs; /* associated filesystem */ 250 ino_t id_ino; /* dependent inode */ 251 nlink_t id_nlinkdelta; /* saved effective link count */ |
248 struct dinode *id_savedino; /* saved dinode contents */ | |
249 LIST_ENTRY(inodedep) id_deps; /* bmsafemap's list of inodedep's */ 250 struct buf *id_buf; /* related bmsafemap (if pending) */ 251 off_t id_savedsize; /* file size saved during rollback */ 252 struct workhead id_pendinghd; /* entries awaiting directory write */ 253 struct workhead id_bufwait; /* operations after inode written */ 254 struct workhead id_inowait; /* operations waiting inode update */ 255 struct allocdirectlst id_inoupdt; /* updates before inode written */ 256 struct allocdirectlst id_newinoupdt; /* updates when inode written */ | 252 LIST_ENTRY(inodedep) id_deps; /* bmsafemap's list of inodedep's */ 253 struct buf *id_buf; /* related bmsafemap (if pending) */ 254 off_t id_savedsize; /* file size saved during rollback */ 255 struct workhead id_pendinghd; /* entries awaiting directory write */ 256 struct workhead id_bufwait; /* operations after inode written */ 257 struct workhead id_inowait; /* operations waiting inode update */ 258 struct allocdirectlst id_inoupdt; /* updates before inode written */ 259 struct allocdirectlst id_newinoupdt; /* updates when inode written */ |
260 union { 261 struct ufs1_dinode *idu_savedino1; /* saved ufs1_dinode contents */ 262 struct ufs2_dinode *idu_savedino2; /* saved ufs2_dinode contents */ 263 } id_un; |
|
257}; | 264}; |
265#define id_savedino1 id_un.idu_savedino1 266#define id_savedino2 id_un.idu_savedino2 |
|
258 259/* 260 * A "newblk" structure is attached to a bmsafemap structure when a block 261 * or fragment is allocated from a cylinder group. Its state is set to 262 * DEPCOMPLETE when its cylinder group map is written. It is consumed by 263 * an associated allocdirect or allocindir allocation which will attach 264 * themselves to the bmsafemap structure if the newblk's DEPCOMPLETE flag 265 * is not set (i.e., its cylinder group map has not been written). 266 */ 267struct newblk { 268 LIST_ENTRY(newblk) nb_hash; /* hashed lookup */ 269 struct fs *nb_fs; /* associated filesystem */ | 267 268/* 269 * A "newblk" structure is attached to a bmsafemap structure when a block 270 * or fragment is allocated from a cylinder group. Its state is set to 271 * DEPCOMPLETE when its cylinder group map is written. It is consumed by 272 * an associated allocdirect or allocindir allocation which will attach 273 * themselves to the bmsafemap structure if the newblk's DEPCOMPLETE flag 274 * is not set (i.e., its cylinder group map has not been written). 275 */ 276struct newblk { 277 LIST_ENTRY(newblk) nb_hash; /* hashed lookup */ 278 struct fs *nb_fs; /* associated filesystem */ |
270 ufs_daddr_t nb_newblkno; /* allocated block number */ | |
271 int nb_state; /* state of bitmap dependency */ | 279 int nb_state; /* state of bitmap dependency */ |
280 ufs2_daddr_t nb_newblkno; /* allocated block number */ |
|
272 LIST_ENTRY(newblk) nb_deps; /* bmsafemap's list of newblk's */ 273 struct bmsafemap *nb_bmsafemap; /* associated bmsafemap */ 274}; 275 276/* 277 * A "bmsafemap" structure maintains a list of dependency structures 278 * that depend on the update of a particular cylinder group map. 279 * It has lists for newblks, allocdirects, allocindirs, and inodedeps. --- 39 unchanged lines hidden (view full) --- 319 * fully committed and can be deleted from their pagedep->id_pendinghd 320 * and inodedep->id_pendinghd lists. 321 */ 322struct allocdirect { 323 struct worklist ad_list; /* buffer holding block */ 324# define ad_state ad_list.wk_state /* block pointer state */ 325 TAILQ_ENTRY(allocdirect) ad_next; /* inodedep's list of allocdirect's */ 326 ufs_lbn_t ad_lbn; /* block within file */ | 281 LIST_ENTRY(newblk) nb_deps; /* bmsafemap's list of newblk's */ 282 struct bmsafemap *nb_bmsafemap; /* associated bmsafemap */ 283}; 284 285/* 286 * A "bmsafemap" structure maintains a list of dependency structures 287 * that depend on the update of a particular cylinder group map. 288 * It has lists for newblks, allocdirects, allocindirs, and inodedeps. --- 39 unchanged lines hidden (view full) --- 328 * fully committed and can be deleted from their pagedep->id_pendinghd 329 * and inodedep->id_pendinghd lists. 330 */ 331struct allocdirect { 332 struct worklist ad_list; /* buffer holding block */ 333# define ad_state ad_list.wk_state /* block pointer state */ 334 TAILQ_ENTRY(allocdirect) ad_next; /* inodedep's list of allocdirect's */ 335 ufs_lbn_t ad_lbn; /* block within file */ |
327 ufs_daddr_t ad_newblkno; /* new value of block pointer */ 328 ufs_daddr_t ad_oldblkno; /* old value of block pointer */ | 336 ufs2_daddr_t ad_newblkno; /* new value of block pointer */ 337 ufs2_daddr_t ad_oldblkno; /* old value of block pointer */ |
329 long ad_newsize; /* size of new block */ 330 long ad_oldsize; /* size of old block */ 331 LIST_ENTRY(allocdirect) ad_deps; /* bmsafemap's list of allocdirect's */ 332 struct buf *ad_buf; /* cylgrp buffer (if pending) */ 333 struct inodedep *ad_inodedep; /* associated inodedep */ 334 struct freefrag *ad_freefrag; /* fragment to be freed (if any) */ 335 struct workhead ad_newdirblk; /* dir block to notify when written */ 336}; --- 37 unchanged lines hidden (view full) --- 374 * the indirect block that claims the block; the "allocindir" dependency 375 * can then be freed as it is no longer applicable. 376 */ 377struct allocindir { 378 struct worklist ai_list; /* buffer holding indirect block */ 379# define ai_state ai_list.wk_state /* indirect block pointer state */ 380 LIST_ENTRY(allocindir) ai_next; /* indirdep's list of allocindir's */ 381 int ai_offset; /* pointer offset in indirect block */ | 338 long ad_newsize; /* size of new block */ 339 long ad_oldsize; /* size of old block */ 340 LIST_ENTRY(allocdirect) ad_deps; /* bmsafemap's list of allocdirect's */ 341 struct buf *ad_buf; /* cylgrp buffer (if pending) */ 342 struct inodedep *ad_inodedep; /* associated inodedep */ 343 struct freefrag *ad_freefrag; /* fragment to be freed (if any) */ 344 struct workhead ad_newdirblk; /* dir block to notify when written */ 345}; --- 37 unchanged lines hidden (view full) --- 383 * the indirect block that claims the block; the "allocindir" dependency 384 * can then be freed as it is no longer applicable. 385 */ 386struct allocindir { 387 struct worklist ai_list; /* buffer holding indirect block */ 388# define ai_state ai_list.wk_state /* indirect block pointer state */ 389 LIST_ENTRY(allocindir) ai_next; /* indirdep's list of allocindir's */ 390 int ai_offset; /* pointer offset in indirect block */ |
382 ufs_daddr_t ai_newblkno; /* new block pointer value */ 383 ufs_daddr_t ai_oldblkno; /* old block pointer value */ | 391 ufs2_daddr_t ai_newblkno; /* new block pointer value */ 392 ufs2_daddr_t ai_oldblkno; /* old block pointer value */ |
384 struct freefrag *ai_freefrag; /* block to be freed when complete */ 385 struct indirdep *ai_indirdep; /* address of associated indirdep */ 386 LIST_ENTRY(allocindir) ai_deps; /* bmsafemap's list of allocindir's */ 387 struct buf *ai_buf; /* cylgrp buffer (if pending) */ 388}; 389 390/* 391 * A "freefrag" structure is attached to an "inodedep" when a previously 392 * allocated fragment is replaced with a larger fragment, rather than extended. 393 * The "freefrag" structure is constructed and attached when the replacement 394 * block is first allocated. It is processed after the inode claiming the 395 * bigger block that replaces it has been written to disk. Note that the 396 * ff_state field is is used to store the uid, so may lose data. However, 397 * the uid is used only in printing an error message, so is not critical. 398 * Keeping it in a short keeps the data structure down to 32 bytes. 399 */ 400struct freefrag { 401 struct worklist ff_list; /* id_inowait or delayed worklist */ 402# define ff_state ff_list.wk_state /* owning user; should be uid_t */ | 393 struct freefrag *ai_freefrag; /* block to be freed when complete */ 394 struct indirdep *ai_indirdep; /* address of associated indirdep */ 395 LIST_ENTRY(allocindir) ai_deps; /* bmsafemap's list of allocindir's */ 396 struct buf *ai_buf; /* cylgrp buffer (if pending) */ 397}; 398 399/* 400 * A "freefrag" structure is attached to an "inodedep" when a previously 401 * allocated fragment is replaced with a larger fragment, rather than extended. 402 * The "freefrag" structure is constructed and attached when the replacement 403 * block is first allocated. It is processed after the inode claiming the 404 * bigger block that replaces it has been written to disk. Note that the 405 * ff_state field is is used to store the uid, so may lose data. However, 406 * the uid is used only in printing an error message, so is not critical. 407 * Keeping it in a short keeps the data structure down to 32 bytes. 408 */ 409struct freefrag { 410 struct worklist ff_list; /* id_inowait or delayed worklist */ 411# define ff_state ff_list.wk_state /* owning user; should be uid_t */ |
403 struct vnode *ff_devvp; /* filesystem device vnode */ | |
404 struct mount *ff_mnt; /* associated mount point */ | 412 struct mount *ff_mnt; /* associated mount point */ |
405 ufs_daddr_t ff_blkno; /* fragment physical block number */ | 413 ufs2_daddr_t ff_blkno; /* fragment physical block number */ |
406 long ff_fragsize; /* size of fragment being deleted */ 407 ino_t ff_inum; /* owning inode number */ 408}; 409 410/* 411 * A "freeblks" structure is attached to an "inodedep" when the 412 * corresponding file's length is reduced to zero. It records all 413 * the information needed to free the blocks of a file after its 414 * zero'ed inode has been written to disk. 415 */ 416struct freeblks { 417 struct worklist fb_list; /* id_inowait or delayed worklist */ 418 ino_t fb_previousinum; /* inode of previous owner of blocks */ | 414 long ff_fragsize; /* size of fragment being deleted */ 415 ino_t ff_inum; /* owning inode number */ 416}; 417 418/* 419 * A "freeblks" structure is attached to an "inodedep" when the 420 * corresponding file's length is reduced to zero. It records all 421 * the information needed to free the blocks of a file after its 422 * zero'ed inode has been written to disk. 423 */ 424struct freeblks { 425 struct worklist fb_list; /* id_inowait or delayed worklist */ 426 ino_t fb_previousinum; /* inode of previous owner of blocks */ |
427 uid_t fb_uid; /* uid of previous owner of blocks */ |
|
419 struct vnode *fb_devvp; /* filesystem device vnode */ 420 struct mount *fb_mnt; /* associated mount point */ 421 off_t fb_oldsize; /* previous file size */ 422 off_t fb_newsize; /* new file size */ | 428 struct vnode *fb_devvp; /* filesystem device vnode */ 429 struct mount *fb_mnt; /* associated mount point */ 430 off_t fb_oldsize; /* previous file size */ 431 off_t fb_newsize; /* new file size */ |
423 int fb_chkcnt; /* used to check cnt of blks released */ 424 uid_t fb_uid; /* uid of previous owner of blocks */ 425 ufs_daddr_t fb_dblks[NDADDR]; /* direct blk ptrs to deallocate */ 426 ufs_daddr_t fb_iblks[NIADDR]; /* indirect blk ptrs to deallocate */ | 432 ufs2_daddr_t fb_chkcnt; /* used to check cnt of blks released */ 433 ufs2_daddr_t fb_dblks[NDADDR]; /* direct blk ptrs to deallocate */ 434 ufs2_daddr_t fb_iblks[NIADDR]; /* indirect blk ptrs to deallocate */ |
427}; 428 429/* 430 * A "freefile" structure is attached to an inode when its 431 * link count is reduced to zero. It marks the inode as free in 432 * the cylinder group map after the zero'ed inode has been written 433 * to disk and any associated blocks and fragments have been freed. 434 */ --- 140 unchanged lines hidden --- | 435}; 436 437/* 438 * A "freefile" structure is attached to an inode when its 439 * link count is reduced to zero. It marks the inode as free in 440 * the cylinder group map after the zero'ed inode has been written 441 * to disk and any associated blocks and fragments have been freed. 442 */ --- 140 unchanged lines hidden --- |