Deleted Added
full compact
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 ---