Deleted Added
full compact
softdep.h (50480) softdep.h (60833)
1/*
2 * Copyright 1998 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 *

--- 39 unchanged lines hidden (view full) ---

48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 * @(#)softdep.h 9.6 (McKusick) 2/25/99
1/*
2 * Copyright 1998 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 *

--- 39 unchanged lines hidden (view full) ---

48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 * @(#)softdep.h 9.6 (McKusick) 2/25/99
56 * $FreeBSD: head/sys/ufs/ffs/softdep.h 50480 1999-08-28 02:16:32Z peter $
56 * $FreeBSD: head/sys/ufs/ffs/softdep.h 60833 2000-05-23 20:41:01Z jake $
57 */
58
59#include <sys/queue.h>
60
61/*
62 * Allocation dependencies are handled with undo/redo on the in-memory
63 * copy of the data. A particular data dependency is eliminated when
64 * it is ALLCOMPLETE: that is ATTACHED, DEPCOMPLETE, and COMPLETE.

--- 58 unchanged lines hidden (view full) ---

123 * in the background rather than during execution of an application process
124 * or interrupt service routine. To realize this, we append dependency
125 * structures corresponding to such tasks to a "workitem" queue. In a soft
126 * updates implementation, most pending workitems should not wait for more
127 * than a couple of seconds, so the filesystem syncer process awakens once
128 * per second to process the items on the queue.
129 */
130
57 */
58
59#include <sys/queue.h>
60
61/*
62 * Allocation dependencies are handled with undo/redo on the in-memory
63 * copy of the data. A particular data dependency is eliminated when
64 * it is ALLCOMPLETE: that is ATTACHED, DEPCOMPLETE, and COMPLETE.

--- 58 unchanged lines hidden (view full) ---

123 * in the background rather than during execution of an application process
124 * or interrupt service routine. To realize this, we append dependency
125 * structures corresponding to such tasks to a "workitem" queue. In a soft
126 * updates implementation, most pending workitems should not wait for more
127 * than a couple of seconds, so the filesystem syncer process awakens once
128 * per second to process the items on the queue.
129 */
130
131/* LIST_HEAD(workhead, worklist); -- declared in buf.h */
131/* LIST_HEAD(workhead, struct worklist); -- declared in buf.h */
132
133/*
134 * Each request can be linked onto a work queue through its worklist structure.
135 * To avoid the need for a pointer to the structure itself, this structure
136 * MUST be declared FIRST in each type in which it appears! If more than one
137 * worklist is needed in the structure, then a wk_data field must be added
138 * and the macros below changed to use it.
139 */
140struct worklist {
132
133/*
134 * Each request can be linked onto a work queue through its worklist structure.
135 * To avoid the need for a pointer to the structure itself, this structure
136 * MUST be declared FIRST in each type in which it appears! If more than one
137 * worklist is needed in the structure, then a wk_data field must be added
138 * and the macros below changed to use it.
139 */
140struct worklist {
141 LIST_ENTRY(worklist) wk_list; /* list of work requests */
141 LIST_ENTRY(struct worklist) wk_list; /* list of work requests */
142 unsigned short wk_type; /* type of request */
143 unsigned short wk_state; /* state flags */
144};
145#define WK_DATA(wk) ((void *)(wk))
146#define WK_PAGEDEP(wk) ((struct pagedep *)(wk))
147#define WK_INODEDEP(wk) ((struct inodedep *)(wk))
148#define WK_NEWBLK(wk) ((struct newblk *)(wk))
149#define WK_BMSAFEMAP(wk) ((struct bmsafemap *)(wk))

--- 5 unchanged lines hidden (view full) ---

155#define WK_FREEFILE(wk) ((struct freefile *)(wk))
156#define WK_DIRADD(wk) ((struct diradd *)(wk))
157#define WK_MKDIR(wk) ((struct mkdir *)(wk))
158#define WK_DIRREM(wk) ((struct dirrem *)(wk))
159
160/*
161 * Various types of lists
162 */
142 unsigned short wk_type; /* type of request */
143 unsigned short wk_state; /* state flags */
144};
145#define WK_DATA(wk) ((void *)(wk))
146#define WK_PAGEDEP(wk) ((struct pagedep *)(wk))
147#define WK_INODEDEP(wk) ((struct inodedep *)(wk))
148#define WK_NEWBLK(wk) ((struct newblk *)(wk))
149#define WK_BMSAFEMAP(wk) ((struct bmsafemap *)(wk))

--- 5 unchanged lines hidden (view full) ---

155#define WK_FREEFILE(wk) ((struct freefile *)(wk))
156#define WK_DIRADD(wk) ((struct diradd *)(wk))
157#define WK_MKDIR(wk) ((struct mkdir *)(wk))
158#define WK_DIRREM(wk) ((struct dirrem *)(wk))
159
160/*
161 * Various types of lists
162 */
163LIST_HEAD(dirremhd, dirrem);
164LIST_HEAD(diraddhd, diradd);
165LIST_HEAD(newblkhd, newblk);
166LIST_HEAD(inodedephd, inodedep);
167LIST_HEAD(allocindirhd, allocindir);
168LIST_HEAD(allocdirecthd, allocdirect);
169TAILQ_HEAD(allocdirectlst, allocdirect);
163LIST_HEAD(dirremhd, struct dirrem);
164LIST_HEAD(diraddhd, struct diradd);
165LIST_HEAD(newblkhd, struct newblk);
166LIST_HEAD(inodedephd, struct inodedep);
167LIST_HEAD(allocindirhd, struct allocindir);
168LIST_HEAD(allocdirecthd, struct allocdirect);
169TAILQ_HEAD(allocdirectlst, struct allocdirect);
170
171/*
172 * The "pagedep" structure tracks the various dependencies related to
173 * a particular directory page. If a directory page has any dependencies,
174 * it will have a pagedep linked to its associated buffer. The
175 * pd_dirremhd list holds the list of dirrem requests which decrement
176 * inode reference counts. These requests are processed after the
177 * directory page with the corresponding zero'ed entries has been

--- 8 unchanged lines hidden (view full) ---

186 * list, any removed operations are done, and the dependency structure
187 * is freed.
188 */
189#define DAHASHSZ 6
190#define DIRADDHASH(offset) (((offset) >> 2) % DAHASHSZ)
191struct pagedep {
192 struct worklist pd_list; /* page buffer */
193# define pd_state pd_list.wk_state /* check for multiple I/O starts */
170
171/*
172 * The "pagedep" structure tracks the various dependencies related to
173 * a particular directory page. If a directory page has any dependencies,
174 * it will have a pagedep linked to its associated buffer. The
175 * pd_dirremhd list holds the list of dirrem requests which decrement
176 * inode reference counts. These requests are processed after the
177 * directory page with the corresponding zero'ed entries has been

--- 8 unchanged lines hidden (view full) ---

186 * list, any removed operations are done, and the dependency structure
187 * is freed.
188 */
189#define DAHASHSZ 6
190#define DIRADDHASH(offset) (((offset) >> 2) % DAHASHSZ)
191struct pagedep {
192 struct worklist pd_list; /* page buffer */
193# define pd_state pd_list.wk_state /* check for multiple I/O starts */
194 LIST_ENTRY(pagedep) pd_hash; /* hashed lookup */
194 LIST_ENTRY(struct pagedep) pd_hash; /* hashed lookup */
195 struct mount *pd_mnt; /* associated mount point */
196 ino_t pd_ino; /* associated file */
197 ufs_lbn_t pd_lbn; /* block within file */
198 struct dirremhd pd_dirremhd; /* dirrem's waiting for page */
199 struct diraddhd pd_diraddhd[DAHASHSZ]; /* diradd dir entry updates */
200 struct diraddhd pd_pendinghd; /* directory entries awaiting write */
201};
202

--- 42 unchanged lines hidden (view full) ---

245 * the directory block containing the name has been written to disk.
246 * The purpose of keeping the entries on the id_pendinghd list is so that
247 * the softdep_fsync function can find and push the inode's directory
248 * name(s) as part of the fsync operation for that file.
249 */
250struct inodedep {
251 struct worklist id_list; /* buffer holding inode block */
252# define id_state id_list.wk_state /* inode dependency state */
195 struct mount *pd_mnt; /* associated mount point */
196 ino_t pd_ino; /* associated file */
197 ufs_lbn_t pd_lbn; /* block within file */
198 struct dirremhd pd_dirremhd; /* dirrem's waiting for page */
199 struct diraddhd pd_diraddhd[DAHASHSZ]; /* diradd dir entry updates */
200 struct diraddhd pd_pendinghd; /* directory entries awaiting write */
201};
202

--- 42 unchanged lines hidden (view full) ---

245 * the directory block containing the name has been written to disk.
246 * The purpose of keeping the entries on the id_pendinghd list is so that
247 * the softdep_fsync function can find and push the inode's directory
248 * name(s) as part of the fsync operation for that file.
249 */
250struct inodedep {
251 struct worklist id_list; /* buffer holding inode block */
252# define id_state id_list.wk_state /* inode dependency state */
253 LIST_ENTRY(inodedep) id_hash; /* hashed lookup */
253 LIST_ENTRY(struct inodedep) id_hash; /* hashed lookup */
254 struct fs *id_fs; /* associated filesystem */
255 ino_t id_ino; /* dependent inode */
256 nlink_t id_nlinkdelta; /* saved effective link count */
257 struct dinode *id_savedino; /* saved dinode contents */
254 struct fs *id_fs; /* associated filesystem */
255 ino_t id_ino; /* dependent inode */
256 nlink_t id_nlinkdelta; /* saved effective link count */
257 struct dinode *id_savedino; /* saved dinode contents */
258 LIST_ENTRY(inodedep) id_deps; /* bmsafemap's list of inodedep's */
258 LIST_ENTRY(struct inodedep) id_deps; /* bmsafemap's list of inodedep's */
259 struct buf *id_buf; /* related bmsafemap (if pending) */
260 off_t id_savedsize; /* file size saved during rollback */
261 struct workhead id_pendinghd; /* entries awaiting directory write */
262 struct workhead id_bufwait; /* operations after inode written */
263 struct workhead id_inowait; /* operations waiting inode update */
264 struct allocdirectlst id_inoupdt; /* updates before inode written */
265 struct allocdirectlst id_newinoupdt; /* updates when inode written */
266};
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 {
259 struct buf *id_buf; /* related bmsafemap (if pending) */
260 off_t id_savedsize; /* file size saved during rollback */
261 struct workhead id_pendinghd; /* entries awaiting directory write */
262 struct workhead id_bufwait; /* operations after inode written */
263 struct workhead id_inowait; /* operations waiting inode update */
264 struct allocdirectlst id_inoupdt; /* updates before inode written */
265 struct allocdirectlst id_newinoupdt; /* updates when inode written */
266};
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 */
277 LIST_ENTRY(struct newblk) nb_hash; /* hashed lookup */
278 struct fs *nb_fs; /* associated filesystem */
279 ufs_daddr_t nb_newblkno; /* allocated block number */
280 int nb_state; /* state of bitmap dependency */
278 struct fs *nb_fs; /* associated filesystem */
279 ufs_daddr_t nb_newblkno; /* allocated block number */
280 int nb_state; /* state of bitmap dependency */
281 LIST_ENTRY(newblk) nb_deps; /* bmsafemap's list of newblk's */
281 LIST_ENTRY(struct 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.
289 * It is attached to the buffer of a cylinder group block when any of

--- 26 unchanged lines hidden (view full) ---

316 * be freed once the inode claiming the new block is written to disk.
317 * This ad_fragfree request is attached to the id_inowait list of the
318 * associated inodedep (pointed to by ad_inodedep) for processing after
319 * the inode is written.
320 */
321struct allocdirect {
322 struct worklist ad_list; /* buffer holding block */
323# define ad_state ad_list.wk_state /* block pointer state */
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.
289 * It is attached to the buffer of a cylinder group block when any of

--- 26 unchanged lines hidden (view full) ---

316 * be freed once the inode claiming the new block is written to disk.
317 * This ad_fragfree request is attached to the id_inowait list of the
318 * associated inodedep (pointed to by ad_inodedep) for processing after
319 * the inode is written.
320 */
321struct allocdirect {
322 struct worklist ad_list; /* buffer holding block */
323# define ad_state ad_list.wk_state /* block pointer state */
324 TAILQ_ENTRY(allocdirect) ad_next; /* inodedep's list of allocdirect's */
324 TAILQ_ENTRY(struct allocdirect) ad_next; /* inodedep's list of allocdirect's */
325 ufs_lbn_t ad_lbn; /* block within file */
326 ufs_daddr_t ad_newblkno; /* new value of block pointer */
327 ufs_daddr_t ad_oldblkno; /* old value of block pointer */
328 long ad_newsize; /* size of new block */
329 long ad_oldsize; /* size of old block */
325 ufs_lbn_t ad_lbn; /* block within file */
326 ufs_daddr_t ad_newblkno; /* new value of block pointer */
327 ufs_daddr_t ad_oldblkno; /* old value of block pointer */
328 long ad_newsize; /* size of new block */
329 long ad_oldsize; /* size of old block */
330 LIST_ENTRY(allocdirect) ad_deps; /* bmsafemap's list of allocdirect's */
330 LIST_ENTRY(struct allocdirect) ad_deps; /* bmsafemap's list of allocdirect's */
331 struct buf *ad_buf; /* cylgrp buffer (if pending) */
332 struct inodedep *ad_inodedep; /* associated inodedep */
333 struct freefrag *ad_freefrag; /* fragment to be freed (if any) */
334};
335
336/*
337 * A single "indirdep" structure manages all allocation dependencies for
338 * pointers in an indirect block. The up-to-date state of the indirect

--- 31 unchanged lines hidden (view full) ---

370 * is written, the COMPLETE flag is set. Once both the cylinder group map
371 * and the data itself have been written, it is safe to write the entry in
372 * the indirect block that claims the block; the "allocindir" dependency
373 * can then be freed as it is no longer applicable.
374 */
375struct allocindir {
376 struct worklist ai_list; /* buffer holding indirect block */
377# define ai_state ai_list.wk_state /* indirect block pointer state */
331 struct buf *ad_buf; /* cylgrp buffer (if pending) */
332 struct inodedep *ad_inodedep; /* associated inodedep */
333 struct freefrag *ad_freefrag; /* fragment to be freed (if any) */
334};
335
336/*
337 * A single "indirdep" structure manages all allocation dependencies for
338 * pointers in an indirect block. The up-to-date state of the indirect

--- 31 unchanged lines hidden (view full) ---

370 * is written, the COMPLETE flag is set. Once both the cylinder group map
371 * and the data itself have been written, it is safe to write the entry in
372 * the indirect block that claims the block; the "allocindir" dependency
373 * can then be freed as it is no longer applicable.
374 */
375struct allocindir {
376 struct worklist ai_list; /* buffer holding indirect block */
377# define ai_state ai_list.wk_state /* indirect block pointer state */
378 LIST_ENTRY(allocindir) ai_next; /* indirdep's list of allocindir's */
378 LIST_ENTRY(struct allocindir) ai_next; /* indirdep's list of allocindir's */
379 int ai_offset; /* pointer offset in indirect block */
380 ufs_daddr_t ai_newblkno; /* new block pointer value */
381 ufs_daddr_t ai_oldblkno; /* old block pointer value */
382 struct freefrag *ai_freefrag; /* block to be freed when complete */
383 struct indirdep *ai_indirdep; /* address of associated indirdep */
379 int ai_offset; /* pointer offset in indirect block */
380 ufs_daddr_t ai_newblkno; /* new block pointer value */
381 ufs_daddr_t ai_oldblkno; /* old block pointer value */
382 struct freefrag *ai_freefrag; /* block to be freed when complete */
383 struct indirdep *ai_indirdep; /* address of associated indirdep */
384 LIST_ENTRY(allocindir) ai_deps; /* bmsafemap's list of allocindir's */
384 LIST_ENTRY(struct allocindir) ai_deps; /* bmsafemap's list of allocindir's */
385 struct buf *ai_buf; /* cylgrp buffer (if pending) */
386};
387
388/*
389 * A "freefrag" structure is attached to an "inodedep" when a previously
390 * allocated fragment is replaced with a larger fragment, rather than extended.
391 * The "freefrag" structure is constructed and attached when the replacement
392 * block is first allocated. It is processed after the inode claiming the

--- 80 unchanged lines hidden (view full) ---

473 * in the associated dirrem entry. If the DIRCHG flag is set, the
474 * da_previous entry is valid; if not set the da_pagedep entry is valid.
475 * The DIRCHG flag never changes; it is set when the structure is created
476 * if appropriate and is never cleared.
477 */
478struct diradd {
479 struct worklist da_list; /* id_inowait or id_pendinghd list */
480# define da_state da_list.wk_state /* state of the new directory entry */
385 struct buf *ai_buf; /* cylgrp buffer (if pending) */
386};
387
388/*
389 * A "freefrag" structure is attached to an "inodedep" when a previously
390 * allocated fragment is replaced with a larger fragment, rather than extended.
391 * The "freefrag" structure is constructed and attached when the replacement
392 * block is first allocated. It is processed after the inode claiming the

--- 80 unchanged lines hidden (view full) ---

473 * in the associated dirrem entry. If the DIRCHG flag is set, the
474 * da_previous entry is valid; if not set the da_pagedep entry is valid.
475 * The DIRCHG flag never changes; it is set when the structure is created
476 * if appropriate and is never cleared.
477 */
478struct diradd {
479 struct worklist da_list; /* id_inowait or id_pendinghd list */
480# define da_state da_list.wk_state /* state of the new directory entry */
481 LIST_ENTRY(diradd) da_pdlist; /* pagedep holding directory block */
481 LIST_ENTRY(struct diradd) da_pdlist; /* pagedep holding directory block */
482 doff_t da_offset; /* offset of new dir entry in dir blk */
483 ino_t da_newinum; /* inode number for the new dir entry */
484 union {
485 struct dirrem *dau_previous; /* entry being replaced in dir change */
486 struct pagedep *dau_pagedep; /* pagedep dependency for addition */
487 } da_un;
488};
489#define da_previous da_un.dau_previous

--- 23 unchanged lines hidden (view full) ---

513 * the associated mkdir's. However, this would increase the size of the diradd
514 * structure from 32 to 64-bits to speed a very infrequent operation.
515 */
516struct mkdir {
517 struct worklist md_list; /* id_inowait or buffer holding dir */
518# define md_state md_list.wk_state /* type: MKDIR_PARENT or MKDIR_BODY */
519 struct diradd *md_diradd; /* associated diradd */
520 struct buf *md_buf; /* MKDIR_BODY: buffer holding dir */
482 doff_t da_offset; /* offset of new dir entry in dir blk */
483 ino_t da_newinum; /* inode number for the new dir entry */
484 union {
485 struct dirrem *dau_previous; /* entry being replaced in dir change */
486 struct pagedep *dau_pagedep; /* pagedep dependency for addition */
487 } da_un;
488};
489#define da_previous da_un.dau_previous

--- 23 unchanged lines hidden (view full) ---

513 * the associated mkdir's. However, this would increase the size of the diradd
514 * structure from 32 to 64-bits to speed a very infrequent operation.
515 */
516struct mkdir {
517 struct worklist md_list; /* id_inowait or buffer holding dir */
518# define md_state md_list.wk_state /* type: MKDIR_PARENT or MKDIR_BODY */
519 struct diradd *md_diradd; /* associated diradd */
520 struct buf *md_buf; /* MKDIR_BODY: buffer holding dir */
521 LIST_ENTRY(mkdir) md_mkdirs; /* list of all mkdirs */
521 LIST_ENTRY(struct mkdir) md_mkdirs; /* list of all mkdirs */
522};
522};
523LIST_HEAD(mkdirlist, mkdir) mkdirlisthd;
523LIST_HEAD(mkdirlist, struct mkdir) mkdirlisthd;
524
525/*
526 * A "dirrem" structure describes an operation to decrement the link
527 * count on an inode. The dirrem structure is attached to the pg_dirremhd
528 * list of the pagedep for the directory page that contains the entry.
529 * It is processed after the directory page with the deleted entry has
530 * been written to disk.
531 *
532 * The overlaying of dm_pagedep and dm_dirinum is done to keep the
533 * structure down to 32 bytes in size on a 32-bit machine. It works
534 * because they are never used concurrently.
535 */
536struct dirrem {
537 struct worklist dm_list; /* delayed worklist */
538# define dm_state dm_list.wk_state /* state of the old directory entry */
524
525/*
526 * A "dirrem" structure describes an operation to decrement the link
527 * count on an inode. The dirrem structure is attached to the pg_dirremhd
528 * list of the pagedep for the directory page that contains the entry.
529 * It is processed after the directory page with the deleted entry has
530 * been written to disk.
531 *
532 * The overlaying of dm_pagedep and dm_dirinum is done to keep the
533 * structure down to 32 bytes in size on a 32-bit machine. It works
534 * because they are never used concurrently.
535 */
536struct dirrem {
537 struct worklist dm_list; /* delayed worklist */
538# define dm_state dm_list.wk_state /* state of the old directory entry */
539 LIST_ENTRY(dirrem) dm_next; /* pagedep's list of dirrem's */
539 LIST_ENTRY(struct dirrem) dm_next; /* pagedep's list of dirrem's */
540 struct mount *dm_mnt; /* associated mount point */
541 ino_t dm_oldinum; /* inum of the removed dir entry */
542 union {
543 struct pagedep *dmu_pagedep; /* pagedep dependency for remove */
544 ino_t dmu_dirinum; /* parent inode number (for rmdir) */
545 } dm_un;
546};
547#define dm_pagedep dm_un.dmu_pagedep
548#define dm_dirinum dm_un.dmu_dirinum
540 struct mount *dm_mnt; /* associated mount point */
541 ino_t dm_oldinum; /* inum of the removed dir entry */
542 union {
543 struct pagedep *dmu_pagedep; /* pagedep dependency for remove */
544 ino_t dmu_dirinum; /* parent inode number (for rmdir) */
545 } dm_un;
546};
547#define dm_pagedep dm_un.dmu_pagedep
548#define dm_dirinum dm_un.dmu_dirinum