| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-2-Clause |
| 3 | * |
| 4 | * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved. |
| 5 | * |
| 6 | * The soft updates code is derived from the appendix of a University |
| 7 | * of Michigan technical report (Gregory R. Ganger and Yale N. Patt, |
| 8 | * "Soft Updates: A Solution to the Metadata Update Problem in File |
| 9 | * Systems", CSE-TR-254-95, August 1995). |
| 10 | * |
| 11 | * Further information about soft updates can be obtained from: |
| 12 | * |
| 13 | *	Marshall Kirk McKusick		http://www.mckusick.com/softdep/ |
| 14 | *	1614 Oxford Street		mckusick@mckusick.com |
| 15 | *	Berkeley, CA 94709-1608		+1-510-843-9542 |
| 16 | *	USA |
| 17 | * |
| 18 | * Redistribution and use in source and binary forms, with or without |
| 19 | * modification, are permitted provided that the following conditions |
| 20 | * are met: |
| 21 | * |
| 22 | * 1. Redistributions of source code must retain the above copyright |
| 23 | * notice, this list of conditions and the following disclaimer. |
| 24 | * 2. Redistributions in binary form must reproduce the above copyright |
| 25 | * notice, this list of conditions and the following disclaimer in the |
| 26 | * documentation and/or other materials provided with the distribution. |
| 27 | * |
| 28 | * THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND ANY |
| 29 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 30 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 31 | * DISCLAIMED. IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE FOR |
| 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 37 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 38 | * SUCH DAMAGE. |
| 39 | */ |
| 40 | |
| 41 | #include <sys/queue.h> |
| 42 | |
| 43 | /* |
| 44 | * Allocation dependencies are handled with undo/redo on the in-memory |
| 45 | * copy of the data. A particular data dependency is eliminated when |
| 46 | * it is ALLCOMPLETE: that is ATTACHED, DEPCOMPLETE, and COMPLETE. |
| 47 | * |
| 48 | * The ATTACHED flag means that the data is not currently being written |
| 49 | * to disk. |
| 50 | * |
| 51 | * The UNDONE flag means that the data has been rolled back to a safe |
| 52 | * state for writing to the disk. When the I/O completes, the data is |
| 53 | * restored to its current form and the state reverts to ATTACHED. |
| 54 | * The data must be locked throughout the rollback, I/O, and roll |
| 55 | * forward so that the rolled back information is never visible to |
| 56 | * user processes. |
| 57 | * |
| 58 | * The COMPLETE flag indicates that the item has been written. For example, |
| 59 | * a dependency that requires that an inode be written will be marked |
| 60 | * COMPLETE after the inode has been written to disk. |
| 61 | * |
| 62 | * The DEPCOMPLETE flag indicates the completion of any other |
| 63 | * dependencies such as the writing of a cylinder group map has been |
| 64 | * completed. A dependency structure may be freed only when both it |
| 65 | * and its dependencies have completed and any rollbacks that are in |
| 66 | * progress have finished as indicated by the set of ALLCOMPLETE flags |
| 67 | * all being set. |
| 68 | * |
| 69 | * The two MKDIR flags indicate additional dependencies that must be done |
| 70 | * when creating a new directory. MKDIR_BODY is cleared when the directory |
| 71 | * data block containing the "." and ".." entries has been written. |
| 72 | * MKDIR_PARENT is cleared when the parent inode with the increased link |
| 73 | * count for ".." has been written. When both MKDIR flags have been |
| 74 | * cleared, the DEPCOMPLETE flag is set to indicate that the directory |
| 75 | * dependencies have been completed. The writing of the directory inode |
| 76 | * itself sets the COMPLETE flag which then allows the directory entry for |
| 77 | * the new directory to be written to disk. The RMDIR flag marks a dirrem |
| 78 | * structure as representing the removal of a directory rather than a |
| 79 | * file. When the removal dependencies are completed, additional work needs |
| 80 | * to be done* (an additional decrement of the associated inode, and a |
| 81 | * decrement of the parent inode). |
| 82 | * |
| 83 | * The DIRCHG flag marks a diradd structure as representing the changing |
| 84 | * of an existing entry rather than the addition of a new one. When |
| 85 | * the update is complete the dirrem associated with the inode for |
| 86 | * the old name must be added to the worklist to do the necessary |
| 87 | * reference count decrement. |
| 88 | * |
| 89 | * The GOINGAWAY flag indicates that the data structure is frozen from |
| 90 | * further change until its dependencies have been completed and its |
| 91 | * resources freed after which it will be discarded. |
| 92 | * |
| 93 | * The IOSTARTED flag prevents multiple calls to the I/O start routine from |
| 94 | * doing multiple rollbacks. |
| 95 | * |
| 96 | * The NEWBLOCK flag marks pagedep structures that have just been allocated, |
| 97 | * so must be claimed by the inode before all dependencies are complete. |
| 98 | * |
| 99 | * The INPROGRESS flag marks worklist structures that are still on the |
| 100 | * worklist, but are being considered for action by some process. |
| 101 | * |
| 102 | * The UFS1FMT flag indicates that the inode being processed is a ufs1 format. |
| 103 | * |
| 104 | * The EXTDATA flag indicates that the allocdirect describes an |
| 105 | * extended-attributes dependency. |
| 106 | * |
| 107 | * The ONWORKLIST flag shows whether the structure is currently linked |
| 108 | * onto a worklist. |
| 109 | * |
| 110 | * The UNLINK* flags track the progress of updating the on-disk linked |
| 111 | * list of active but unlinked inodes. When an inode is first unlinked |
| 112 | * it is marked as UNLINKED. When its on-disk di_freelink has been |
| 113 | * written its UNLINKNEXT flags is set. When its predecessor in the |
| 114 | * list has its di_freelink pointing at us its UNLINKPREV is set. |
| 115 | * When the on-disk list can reach it from the superblock, its |
| 116 | * UNLINKONLIST flag is set. Once all of these flags are set, it |
| 117 | * is safe to let its last name be removed. |
| 118 | */ |
| 119 | #define	ATTACHED	0x000001 |
| 120 | #define	UNDONE		0x000002 |
| 121 | #define	COMPLETE	0x000004 |
| 122 | #define	DEPCOMPLETE	0x000008 |
| 123 | #define	MKDIR_PARENT	0x000010 /* diradd, mkdir, jaddref, jsegdep only */ |
| 124 | #define	MKDIR_BODY	0x000020 /* diradd, mkdir, jaddref only */ |
| 125 | #define	RMDIR		0x000040 /* dirrem only */ |
| 126 | #define	DIRCHG		0x000080 /* diradd, dirrem only */ |
| 127 | #define	GOINGAWAY	0x000100 /* indirdep, jremref only */ |
| 128 | #define	IOSTARTED	0x000200 /* inodedep, pagedep, bmsafemap only */ |
| 129 | #define	DELAYEDFREE	0x000400 /* allocindirect free delayed. */ |
| 130 | #define	NEWBLOCK	0x000800 /* pagedep, jaddref only */ |
| 131 | #define	INPROGRESS	0x001000 /* dirrem, freeblks, freefrag, freefile only */ |
| 132 | #define	UFS1FMT		0x002000 /* indirdep only */ |
| 133 | #define	EXTDATA		0x004000 /* allocdirect only */ |
| 134 | #define	ONWORKLIST	0x008000 |
| 135 | #define	IOWAITING	0x010000 /* Thread is waiting for IO to complete. */ |
| 136 | #define	ONDEPLIST	0x020000 /* Structure is on a dependency list. */ |
| 137 | #define	UNLINKED	0x040000 /* inodedep has been unlinked. */ |
| 138 | #define	UNLINKNEXT	0x080000 /* inodedep has valid di_freelink */ |
| 139 | #define	UNLINKPREV	0x100000 /* inodedep is pointed at in the unlink list */ |
| 140 | #define	UNLINKONLIST	0x200000 /* inodedep is in the unlinked list on disk */ |
| 141 | #define	UNLINKLINKS	(UNLINKNEXT | UNLINKPREV) |
| 142 | #define	WRITESUCCEEDED	0x400000 /* the disk write completed successfully */ |
| 143 | |
| 144 | #define	ALLCOMPLETE	(ATTACHED | COMPLETE | DEPCOMPLETE) |
| 145 | |
| 146 | #define PRINT_SOFTDEP_FLAGS "\20\27writesucceeded\26unlinkonlist" \ |
| 147 | 	"\25unlinkprev\24unlinknext\23unlinked\22ondeplist\21iowaiting" \ |
| 148 | 	"\20onworklist\17extdata\16ufs1fmt\15inprogress\14newblock" \ |
| 149 | 	"\13delayedfree\12iostarted\11goingaway\10dirchg\7rmdir\6mkdir_body" \ |
| 150 | 	"\5mkdir_parent\4depcomplete\3complete\2undone\1attached" |
| 151 | |
| 152 | /* |
| 153 | * Values for each of the soft dependency types. |
| 154 | */ |
| 155 | #define	D_UNUSED	0 |
| 156 | #define	D_FIRST		D_PAGEDEP |
| 157 | #define	D_PAGEDEP	1 |
| 158 | #define	D_INODEDEP	2 |
| 159 | #define	D_BMSAFEMAP	3 |
| 160 | #define	D_NEWBLK	4 |
| 161 | #define	D_ALLOCDIRECT	5 |
| 162 | #define	D_INDIRDEP	6 |
| 163 | #define	D_ALLOCINDIR	7 |
| 164 | #define	D_FREEFRAG	8 |
| 165 | #define	D_FREEBLKS	9 |
| 166 | #define	D_FREEFILE	10 |
| 167 | #define	D_DIRADD	11 |
| 168 | #define	D_MKDIR		12 |
| 169 | #define	D_DIRREM	13 |
| 170 | #define	D_NEWDIRBLK	14 |
| 171 | #define	D_FREEWORK	15 |
| 172 | #define	D_FREEDEP	16 |
| 173 | #define	D_JADDREF	17 |
| 174 | #define	D_JREMREF	18 |
| 175 | #define	D_JMVREF	19 |
| 176 | #define	D_JNEWBLK	20 |
| 177 | #define	D_JFREEBLK	21 |
| 178 | #define	D_JFREEFRAG	22 |
| 179 | #define	D_JSEG		23 |
| 180 | #define	D_JSEGDEP	24 |
| 181 | #define	D_SBDEP		25 |
| 182 | #define	D_JTRUNC	26 |
| 183 | #define	D_JFSYNC	27 |
| 184 | #define	D_SENTINEL	28 |
| 185 | #define	D_LAST		D_SENTINEL |
| 186 | |
| 187 | /* |
| 188 | * The workitem queue. |
| 189 | * |
| 190 | * It is sometimes useful and/or necessary to clean up certain dependencies |
| 191 | * in the background rather than during execution of an application process |
| 192 | * or interrupt service routine. To realize this, we append dependency |
| 193 | * structures corresponding to such tasks to a "workitem" queue. In a soft |
| 194 | * updates implementation, most pending workitems should not wait for more |
| 195 | * than a couple of seconds, so the filesystem syncer process awakens once |
| 196 | * per second to process the items on the queue. |
| 197 | */ |
| 198 | |
| 199 | /* LIST_HEAD(workhead, worklist);	-- declared in buf.h */ |
| 200 | |
| 201 | /* |
| 202 | * Each request can be linked onto a work queue through its worklist structure. |
| 203 | * To avoid the need for a pointer to the structure itself, this structure |
| 204 | * MUST be declared FIRST in each type in which it appears! If more than one |
| 205 | * worklist is needed in the structure, then a wk_data field must be added |
| 206 | * and the macros below changed to use it. |
| 207 | */ |
| 208 | struct worklist { |
| 209 | 	LIST_ENTRY(worklist)	wk_list;	/* list of work requests */ |
| 210 | 	struct mount		*wk_mp;		/* Mount we live in */ |
| 211 | 	unsigned int		wk_type:8,	/* type of request */ |
| 212 | 				wk_state:24;	/* state flags */ |
| 213 | 	LIST_ENTRY(worklist)	wk_all;		/* list of deps of this type */ |
| 214 | #ifdef INVARIANTS |
| 215 | 	const char		*wk_func;	/* func where added / removed */ |
| 216 | 	int			wk_line;	/* line where added / removed */ |
| 217 | #endif |
| 218 | }; |
| 219 | #define	WK_DATA(wk) ((void *)(wk)) |
| 220 | #define	WK_PAGEDEP(wk) ((struct pagedep *)(wk)) |
| 221 | #define	WK_INODEDEP(wk) ((struct inodedep *)(wk)) |
| 222 | #define	WK_BMSAFEMAP(wk) ((struct bmsafemap *)(wk)) |
| 223 | #define	WK_NEWBLK(wk) ((struct newblk *)(wk)) |
| 224 | #define	WK_ALLOCDIRECT(wk) ((struct allocdirect *)(wk)) |
| 225 | #define	WK_INDIRDEP(wk) ((struct indirdep *)(wk)) |
| 226 | #define	WK_ALLOCINDIR(wk) ((struct allocindir *)(wk)) |
| 227 | #define	WK_FREEFRAG(wk) ((struct freefrag *)(wk)) |
| 228 | #define	WK_FREEBLKS(wk) ((struct freeblks *)(wk)) |
| 229 | #define	WK_FREEWORK(wk) ((struct freework *)(wk)) |
| 230 | #define	WK_FREEFILE(wk) ((struct freefile *)(wk)) |
| 231 | #define	WK_DIRADD(wk) ((struct diradd *)(wk)) |
| 232 | #define	WK_MKDIR(wk) ((struct mkdir *)(wk)) |
| 233 | #define	WK_DIRREM(wk) ((struct dirrem *)(wk)) |
| 234 | #define	WK_NEWDIRBLK(wk) ((struct newdirblk *)(wk)) |
| 235 | #define	WK_JADDREF(wk) ((struct jaddref *)(wk)) |
| 236 | #define	WK_JREMREF(wk) ((struct jremref *)(wk)) |
| 237 | #define	WK_JMVREF(wk) ((struct jmvref *)(wk)) |
| 238 | #define	WK_JSEGDEP(wk) ((struct jsegdep *)(wk)) |
| 239 | #define	WK_JSEG(wk) ((struct jseg *)(wk)) |
| 240 | #define	WK_JNEWBLK(wk) ((struct jnewblk *)(wk)) |
| 241 | #define	WK_JFREEBLK(wk) ((struct jfreeblk *)(wk)) |
| 242 | #define	WK_FREEDEP(wk) ((struct freedep *)(wk)) |
| 243 | #define	WK_JFREEFRAG(wk) ((struct jfreefrag *)(wk)) |
| 244 | #define	WK_SBDEP(wk) ((struct sbdep *)(wk)) |
| 245 | #define	WK_JTRUNC(wk) ((struct jtrunc *)(wk)) |
| 246 | #define	WK_JFSYNC(wk) ((struct jfsync *)(wk)) |
| 247 | |
| 248 | /* |
| 249 | * Various types of lists |
| 250 | */ |
| 251 | LIST_HEAD(dirremhd, dirrem); |
| 252 | LIST_HEAD(diraddhd, diradd); |
| 253 | LIST_HEAD(newblkhd, newblk); |
| 254 | LIST_HEAD(inodedephd, inodedep); |
| 255 | LIST_HEAD(allocindirhd, allocindir); |
| 256 | LIST_HEAD(allocdirecthd, allocdirect); |
| 257 | TAILQ_HEAD(allocdirectlst, allocdirect); |
| 258 | LIST_HEAD(indirdephd, indirdep); |
| 259 | LIST_HEAD(jaddrefhd, jaddref); |
| 260 | LIST_HEAD(jremrefhd, jremref); |
| 261 | LIST_HEAD(jmvrefhd, jmvref); |
| 262 | LIST_HEAD(jnewblkhd, jnewblk); |
| 263 | LIST_HEAD(jblkdephd, jblkdep); |
| 264 | LIST_HEAD(freeworkhd, freework); |
| 265 | TAILQ_HEAD(freeworklst, freework); |
| 266 | TAILQ_HEAD(jseglst, jseg); |
| 267 | TAILQ_HEAD(inoreflst, inoref); |
| 268 | TAILQ_HEAD(freeblklst, freeblks); |
| 269 | |
| 270 | /* |
| 271 | * The "pagedep" structure tracks the various dependencies related to |
| 272 | * a particular directory page. If a directory page has any dependencies, |
| 273 | * it will have a pagedep linked to its associated buffer. The |
| 274 | * pd_dirremhd list holds the list of dirrem requests which decrement |
| 275 | * inode reference counts. These requests are processed after the |
| 276 | * directory page with the corresponding zero'ed entries has been |
| 277 | * written. The pd_diraddhd list maintains the list of diradd requests |
| 278 | * which cannot be committed until their corresponding inode has been |
| 279 | * written to disk. Because a directory may have many new entries |
| 280 | * being created, several lists are maintained hashed on bits of the |
| 281 | * offset of the entry into the directory page to keep the lists from |
| 282 | * getting too long. Once a new directory entry has been cleared to |
| 283 | * be written, it is moved to the pd_pendinghd list. After the new |
| 284 | * entry has been written to disk it is removed from the pd_pendinghd |
| 285 | * list, any removed operations are done, and the dependency structure |
| 286 | * is freed. |
| 287 | */ |
| 288 | #define	DAHASHSZ 5 |
| 289 | #define	DIRADDHASH(offset) (((offset) >> 2) % DAHASHSZ) |
| 290 | struct pagedep { |
| 291 | 	struct	worklist pd_list;	/* page buffer */ |
| 292 | #	define	pd_state pd_list.wk_state /* check for multiple I/O starts */ |
| 293 | 	LIST_ENTRY(pagedep) pd_hash;	/* hashed lookup */ |
| 294 | 	ino_t	pd_ino;			/* associated file */ |
| 295 | 	ufs_lbn_t pd_lbn;		/* block within file */ |
| 296 | 	struct	newdirblk *pd_newdirblk; /* associated newdirblk if NEWBLOCK */ |
| 297 | 	struct	dirremhd pd_dirremhd;	/* dirrem's waiting for page */ |
| 298 | 	struct	diraddhd pd_diraddhd[DAHASHSZ]; /* diradd dir entry updates */ |
| 299 | 	struct	diraddhd pd_pendinghd;	/* directory entries awaiting write */ |
| 300 | 	struct	jmvrefhd pd_jmvrefhd;	/* Dependent journal writes. */ |
| 301 | }; |
| 302 | |
| 303 | /* |
| 304 | * The "inodedep" structure tracks the set of dependencies associated |
| 305 | * with an inode. One task that it must manage is delayed operations |
| 306 | * (i.e., work requests that must be held until the inodedep's associated |
| 307 | * inode has been written to disk). Getting an inode from its incore |
| 308 | * state to the disk requires two steps to be taken by the filesystem |
| 309 | * in this order: first the inode must be copied to its disk buffer by |
| 310 | * the VOP_UPDATE operation; second the inode's buffer must be written |
| 311 | * to disk. To ensure that both operations have happened in the required |
| 312 | * order, the inodedep maintains two lists. Delayed operations are |
| 313 | * placed on the id_inowait list. When the VOP_UPDATE is done, all |
| 314 | * operations on the id_inowait list are moved to the id_bufwait list. |
| 315 | * When the buffer is written, the items on the id_bufwait list can be |
| 316 | * safely moved to the work queue to be processed. A second task of the |
| 317 | * inodedep structure is to track the status of block allocation within |
| 318 | * the inode. Each block that is allocated is represented by an |
| 319 | * "allocdirect" structure (see below). It is linked onto the id_newinoupdt |
| 320 | * list until both its contents and its allocation in the cylinder |
| 321 | * group map have been written to disk. Once these dependencies have been |
| 322 | * satisfied, it is removed from the id_newinoupdt list and any followup |
| 323 | * actions such as releasing the previous block or fragment are placed |
| 324 | * on the id_inowait list. When an inode is updated (a VOP_UPDATE is |
| 325 | * done), the "inodedep" structure is linked onto the buffer through |
| 326 | * its worklist. Thus, it will be notified when the buffer is about |
| 327 | * to be written and when it is done. At the update time, all the |
| 328 | * elements on the id_newinoupdt list are moved to the id_inoupdt list |
| 329 | * since those changes are now relevant to the copy of the inode in the |
| 330 | * buffer. Also at update time, the tasks on the id_inowait list are |
| 331 | * moved to the id_bufwait list so that they will be executed when |
| 332 | * the updated inode has been written to disk. When the buffer containing |
| 333 | * the inode is written to disk, any updates listed on the id_inoupdt |
| 334 | * list are rolled back as they are not yet safe. Following the write, |
| 335 | * the changes are once again rolled forward and any actions on the |
| 336 | * id_bufwait list are processed (since those actions are now safe). |
| 337 | * The entries on the id_inoupdt and id_newinoupdt lists must be kept |
| 338 | * sorted by logical block number to speed the calculation of the size |
| 339 | * of the rolled back inode (see explanation in initiate_write_inodeblock). |
| 340 | * When a directory entry is created, it is represented by a diradd. |
| 341 | * The diradd is added to the id_inowait list as it cannot be safely |
| 342 | * written to disk until the inode that it represents is on disk. After |
| 343 | * the inode is written, the id_bufwait list is processed and the diradd |
| 344 | * entries are moved to the id_pendinghd list where they remain until |
| 345 | * the directory block containing the name has been written to disk. |
| 346 | * The purpose of keeping the entries on the id_pendinghd list is so that |
| 347 | * the softdep_fsync function can find and push the inode's directory |
| 348 | * name(s) as part of the fsync operation for that file. |
| 349 | */ |
| 350 | struct inodedep { |
| 351 | 	struct	worklist id_list;	/* buffer holding inode block */ |
| 352 | #	define	id_state id_list.wk_state /* inode dependency state */ |
| 353 | 	LIST_ENTRY(inodedep) id_hash;	/* hashed lookup */ |
| 354 | 	TAILQ_ENTRY(inodedep) id_unlinked;	/* Unlinked but ref'd inodes */ |
| 355 | 	struct	fs *id_fs;		/* associated filesystem */ |
| 356 | 	ino_t	id_ino;			/* dependent inode */ |
| 357 | 	nlink_t	id_nlinkdelta;		/* saved effective link count */ |
| 358 | 	nlink_t	id_nlinkwrote;		/* i_nlink that we wrote to disk */ |
| 359 | 	nlink_t	id_savednlink;		/* Link saved during rollback */ |
| 360 | 	LIST_ENTRY(inodedep) id_deps;	/* bmsafemap's list of inodedep's */ |
| 361 | 	struct	bmsafemap *id_bmsafemap; /* related bmsafemap (if pending) */ |
| 362 | 	struct	diradd *id_mkdiradd;	/* diradd for a mkdir. */ |
| 363 | 	struct	inoreflst id_inoreflst;	/* Inode reference adjustments. */ |
| 364 | 	long	id_savedextsize;	/* ext size saved during rollback */ |
| 365 | 	off_t	id_savedsize;		/* file size saved during rollback */ |
| 366 | 	struct	dirremhd id_dirremhd;	/* Removals pending. */ |
| 367 | 	struct	workhead id_pendinghd;	/* entries awaiting directory write */ |
| 368 | 	struct	workhead id_bufwait;	/* operations after inode written */ |
| 369 | 	struct	workhead id_inowait;	/* operations waiting inode update */ |
| 370 | 	struct	allocdirectlst id_inoupdt; /* updates before inode written */ |
| 371 | 	struct	allocdirectlst id_newinoupdt; /* updates when inode written */ |
| 372 | 	struct	allocdirectlst id_extupdt; /* extdata updates pre-inode write */ |
| 373 | 	struct	allocdirectlst id_newextupdt; /* extdata updates at ino write */ |
| 374 | 	struct	freeblklst id_freeblklst; /* List of partial truncates. */ |
| 375 | 	union { |
| 376 | 	struct	ufs1_dinode *idu_savedino1; /* saved ufs1_dinode contents */ |
| 377 | 	struct	ufs2_dinode *idu_savedino2; /* saved ufs2_dinode contents */ |
| 378 | 	} id_un; |
| 379 | }; |
| 380 | #define	id_savedino1 id_un.idu_savedino1 |
| 381 | #define	id_savedino2 id_un.idu_savedino2 |
| 382 | |
| 383 | /* |
| 384 | * A "bmsafemap" structure maintains a list of dependency structures |
| 385 | * that depend on the update of a particular cylinder group map. |
| 386 | * It has lists for newblks, allocdirects, allocindirs, and inodedeps. |
| 387 | * It is attached to the buffer of a cylinder group block when any of |
| 388 | * these things are allocated from the cylinder group. It is freed |
| 389 | * after the cylinder group map is written and the state of its |
| 390 | * dependencies are updated with DEPCOMPLETE to indicate that it has |
| 391 | * been processed. |
| 392 | */ |
| 393 | struct bmsafemap { |
| 394 | 	struct	worklist sm_list;	/* cylgrp buffer */ |
| 395 | #	define	sm_state sm_list.wk_state |
| 396 | 	LIST_ENTRY(bmsafemap) sm_hash;	/* Hash links. */ |
| 397 | 	LIST_ENTRY(bmsafemap) sm_next;	/* Mount list. */ |
| 398 | 	int	sm_cg; |
| 399 | 	struct	buf *sm_buf;		/* associated buffer */ |
| 400 | 	struct	allocdirecthd sm_allocdirecthd; /* allocdirect deps */ |
| 401 | 	struct	allocdirecthd sm_allocdirectwr; /* writing allocdirect deps */ |
| 402 | 	struct	allocindirhd sm_allocindirhd; /* allocindir deps */ |
| 403 | 	struct	allocindirhd sm_allocindirwr; /* writing allocindir deps */ |
| 404 | 	struct	inodedephd sm_inodedephd; /* inodedep deps */ |
| 405 | 	struct	inodedephd sm_inodedepwr; /* writing inodedep deps */ |
| 406 | 	struct	newblkhd sm_newblkhd;	/* newblk deps */ |
| 407 | 	struct	newblkhd sm_newblkwr;	/* writing newblk deps */ |
| 408 | 	struct	jaddrefhd sm_jaddrefhd;	/* Pending inode allocations. */ |
| 409 | 	struct	jnewblkhd sm_jnewblkhd;	/* Pending block allocations. */ |
| 410 | 	struct	workhead sm_freehd;	/* Freedep deps. */ |
| 411 | 	struct	workhead sm_freewr;	/* Written freedeps. */ |
| 412 | }; |
| 413 | |
| 414 | /* |
| 415 | * A "newblk" structure is attached to a bmsafemap structure when a block |
| 416 | * or fragment is allocated from a cylinder group. Its state is set to |
| 417 | * DEPCOMPLETE when its cylinder group map is written. It is converted to |
| 418 | * an allocdirect or allocindir allocation once the allocator calls the |
| 419 | * appropriate setup function. It will initially be linked onto a bmsafemap |
| 420 | * list. Once converted it can be linked onto the lists described for |
| 421 | * allocdirect or allocindir as described below. |
| 422 | */ |
| 423 | struct newblk { |
| 424 | 	struct	worklist nb_list;	/* See comment above. */ |
| 425 | #	define	nb_state nb_list.wk_state |
| 426 | 	LIST_ENTRY(newblk) nb_hash;	/* Hashed lookup. */ |
| 427 | 	LIST_ENTRY(newblk) nb_deps;	/* Bmsafemap's list of newblks. */ |
| 428 | 	struct	jnewblk *nb_jnewblk;	/* New block journal entry. */ |
| 429 | 	struct	bmsafemap *nb_bmsafemap;/* Cylgrp dep (if pending). */ |
| 430 | 	struct	freefrag *nb_freefrag;	/* Fragment to be freed (if any). */ |
| 431 | 	struct	indirdephd nb_indirdeps; /* Children indirect blocks. */ |
| 432 | 	struct	workhead nb_newdirblk;	/* Dir block to notify when written. */ |
| 433 | 	struct	workhead nb_jwork;	/* Journal work pending. */ |
| 434 | 	ufs2_daddr_t	nb_newblkno;	/* New value of block pointer. */ |
| 435 | }; |
| 436 | |
| 437 | /* |
| 438 | * An "allocdirect" structure is attached to an "inodedep" when a new block |
| 439 | * or fragment is allocated and pointed to by the inode described by |
| 440 | * "inodedep". The worklist is linked to the buffer that holds the block. |
| 441 | * When the block is first allocated, it is linked to the bmsafemap |
| 442 | * structure associated with the buffer holding the cylinder group map |
| 443 | * from which it was allocated. When the cylinder group map is written |
| 444 | * to disk, ad_state has the DEPCOMPLETE flag set. When the block itself |
| 445 | * is written, the COMPLETE flag is set. Once both the cylinder group map |
| 446 | * and the data itself have been written, it is safe to write the inode |
| 447 | * that claims the block. If there was a previous fragment that had been |
| 448 | * allocated before the file was increased in size, the old fragment may |
| 449 | * be freed once the inode claiming the new block is written to disk. |
| 450 | * This ad_fragfree request is attached to the id_inowait list of the |
| 451 | * associated inodedep (pointed to by ad_inodedep) for processing after |
| 452 | * the inode is written. When a block is allocated to a directory, an |
| 453 | * fsync of a file whose name is within that block must ensure not only |
| 454 | * that the block containing the file name has been written, but also |
| 455 | * that the on-disk inode references that block. When a new directory |
| 456 | * block is created, we allocate a newdirblk structure which is linked |
| 457 | * to the associated allocdirect (on its ad_newdirblk list). When the |
| 458 | * allocdirect has been satisfied, the newdirblk structure is moved to |
| 459 | * the inodedep id_bufwait list of its directory to await the inode |
| 460 | * being written. When the inode is written, the directory entries are |
| 461 | * fully committed and can be deleted from their pagedep->id_pendinghd |
| 462 | * and inodedep->id_pendinghd lists. |
| 463 | */ |
| 464 | struct allocdirect { |
| 465 | 	struct	newblk ad_block;	/* Common block logic */ |
| 466 | #	define	ad_list ad_block.nb_list /* block pointer worklist */ |
| 467 | #	define	ad_state ad_list.wk_state /* block pointer state */ |
| 468 | 	TAILQ_ENTRY(allocdirect) ad_next; /* inodedep's list of allocdirect's */ |
| 469 | 	struct	inodedep *ad_inodedep;	/* associated inodedep */ |
| 470 | 	ufs2_daddr_t	ad_oldblkno;	/* old value of block pointer */ |
| 471 | 	int		ad_offset;	/* Pointer offset in parent. */ |
| 472 | 	long		ad_newsize;	/* size of new block */ |
| 473 | 	long		ad_oldsize;	/* size of old block */ |
| 474 | }; |
| 475 | #define	ad_newblkno	ad_block.nb_newblkno |
| 476 | #define	ad_freefrag	ad_block.nb_freefrag |
| 477 | #define	ad_newdirblk	ad_block.nb_newdirblk |
| 478 | |
| 479 | /* |
| 480 | * A single "indirdep" structure manages all allocation dependencies for |
| 481 | * pointers in an indirect block. The up-to-date state of the indirect |
| 482 | * block is stored in ir_savedata. The set of pointers that may be safely |
| 483 | * written to the disk is stored in ir_savebp. The state field is used |
| 484 | * only to track whether the buffer is currently being written (in which |
| 485 | * case it is not safe to update ir_savebp). Ir_deplisthd contains the |
| 486 | * list of allocindir structures, one for each block that needs to be |
| 487 | * written to disk. Once the block and its bitmap allocation have been |
| 488 | * written the safecopy can be updated to reflect the allocation and the |
| 489 | * allocindir structure freed. If ir_state indicates that an I/O on the |
| 490 | * indirect block is in progress when ir_savebp is to be updated, the |
| 491 | * update is deferred by placing the allocindir on the ir_donehd list. |
| 492 | * When the I/O on the indirect block completes, the entries on the |
| 493 | * ir_donehd list are processed by updating their corresponding ir_savebp |
| 494 | * pointers and then freeing the allocindir structure. |
| 495 | */ |
| 496 | struct indirdep { |
| 497 | 	struct	worklist ir_list;	/* buffer holding indirect block */ |
| 498 | #	define	ir_state ir_list.wk_state /* indirect block pointer state */ |
| 499 | 	LIST_ENTRY(indirdep) ir_next;	/* alloc{direct,indir} list */ |
| 500 | 	TAILQ_HEAD(, freework) ir_trunc;	/* List of truncations. */ |
| 501 | 	caddr_t	ir_saveddata;		/* buffer cache contents */ |
| 502 | 	struct	buf *ir_savebp;		/* buffer holding safe copy */ |
| 503 | 	struct	buf *ir_bp;		/* buffer holding live copy */ |
| 504 | 	struct	allocindirhd ir_completehd; /* waiting for indirdep complete */ |
| 505 | 	struct	allocindirhd ir_writehd; /* Waiting for the pointer write. */ |
| 506 | 	struct	allocindirhd ir_donehd;	/* done waiting to update safecopy */ |
| 507 | 	struct	allocindirhd ir_deplisthd; /* allocindir deps for this block */ |
| 508 | 	struct	freeblks *ir_freeblks;	/* Freeblks that frees this indir. */ |
| 509 | }; |
| 510 | |
| 511 | /* |
| 512 | * An "allocindir" structure is attached to an "indirdep" when a new block |
| 513 | * is allocated and pointed to by the indirect block described by the |
| 514 | * "indirdep". The worklist is linked to the buffer that holds the new block. |
| 515 | * When the block is first allocated, it is linked to the bmsafemap |
| 516 | * structure associated with the buffer holding the cylinder group map |
| 517 | * from which it was allocated. When the cylinder group map is written |
| 518 | * to disk, ai_state has the DEPCOMPLETE flag set. When the block itself |
| 519 | * is written, the COMPLETE flag is set. Once both the cylinder group map |
| 520 | * and the data itself have been written, it is safe to write the entry in |
| 521 | * the indirect block that claims the block; the "allocindir" dependency |
| 522 | * can then be freed as it is no longer applicable. |
| 523 | */ |
| 524 | struct allocindir { |
| 525 | 	struct	newblk ai_block;	/* Common block area */ |
| 526 | #	define	ai_state ai_block.nb_list.wk_state /* indirect pointer state */ |
| 527 | 	LIST_ENTRY(allocindir) ai_next;	/* indirdep's list of allocindir's */ |
| 528 | 	struct	indirdep *ai_indirdep;	/* address of associated indirdep */ |
| 529 | 	ufs2_daddr_t	ai_oldblkno;	/* old value of block pointer */ |
| 530 | 	ufs_lbn_t	ai_lbn;		/* Logical block number. */ |
| 531 | 	int		ai_offset;	/* Pointer offset in parent. */ |
| 532 | }; |
| 533 | #define	ai_newblkno	ai_block.nb_newblkno |
| 534 | #define	ai_freefrag	ai_block.nb_freefrag |
| 535 | #define	ai_newdirblk	ai_block.nb_newdirblk |
| 536 | |
| 537 | /* |
| 538 | * The allblk union is used to size the newblk structure on allocation so |
| 539 | * that it may be any one of three types. |
| 540 | */ |
| 541 | union allblk { |
| 542 | 	struct	allocindir ab_allocindir; |
| 543 | 	struct	allocdirect ab_allocdirect; |
| 544 | 	struct	newblk	ab_newblk; |
| 545 | }; |
| 546 | |
| 547 | /* |
| 548 | * A "freefrag" structure is attached to an "inodedep" when a previously |
| 549 | * allocated fragment is replaced with a larger fragment, rather than extended. |
| 550 | * The "freefrag" structure is constructed and attached when the replacement |
| 551 | * block is first allocated. It is processed after the inode claiming the |
| 552 | * bigger block that replaces it has been written to disk. |
| 553 | */ |
| 554 | struct freefrag { |
| 555 | 	struct	worklist ff_list;	/* id_inowait or delayed worklist */ |
| 556 | #	define	ff_state ff_list.wk_state |
| 557 | 	struct	worklist *ff_jdep;	/* Associated journal entry. */ |
| 558 | 	struct	workhead ff_jwork;	/* Journal work pending. */ |
| 559 | 	ufs2_daddr_t ff_blkno;		/* fragment physical block number */ |
| 560 | 	long	ff_fragsize;		/* size of fragment being deleted */ |
| 561 | 	ino_t	ff_inum;		/* owning inode number */ |
| 562 | 	__enum_uint8(vtype) ff_vtype;	/* owning inode's file type */ |
| 563 | 	int	ff_key;			/* trim key when deleted */ |
| 564 | }; |
| 565 | |
| 566 | /* |
| 567 | * A "freeblks" structure is attached to an "inodedep" when the |
| 568 | * corresponding file's length is reduced to zero. It records all |
| 569 | * the information needed to free the blocks of a file after its |
| 570 | * zero'ed inode has been written to disk. The actual work is done |
| 571 | * by child freework structures which are responsible for individual |
| 572 | * inode pointers while freeblks is responsible for retiring the |
| 573 | * entire operation when it is complete and holding common members. |
| 574 | */ |
| 575 | struct freeblks { |
| 576 | 	struct	worklist fb_list;	/* id_inowait or delayed worklist */ |
| 577 | #	define	fb_state fb_list.wk_state /* inode and dirty block state */ |
| 578 | 	TAILQ_ENTRY(freeblks) fb_next;	/* List of inode truncates. */ |
| 579 | 	struct	jblkdephd fb_jblkdephd;	/* Journal entries pending */ |
| 580 | 	struct	workhead fb_freeworkhd;	/* Work items pending */ |
| 581 | 	struct	workhead fb_jwork;	/* Journal work pending */ |
| 582 | 	struct	vnode *fb_devvp;	/* filesystem device vnode */ |
| 583 | #ifdef QUOTA |
| 584 | 	struct	dquot *fb_quota[MAXQUOTAS]; /* quotas to be adjusted */ |
| 585 | #endif |
| 586 | 	uint64_t fb_modrev;		/* Inode revision at start of trunc. */ |
| 587 | 	off_t	fb_len;			/* Length we're truncating to. */ |
| 588 | 	ufs2_daddr_t fb_chkcnt;		/* Blocks released. */ |
| 589 | 	ino_t	fb_inum;		/* inode owner of blocks */ |
| 590 | 	__enum_uint8(vtype) fb_vtype;	/* inode owner's file type */ |
| 591 | 	uid_t	fb_uid;			/* uid of previous owner of blocks */ |
| 592 | 	int	fb_ref;			/* Children outstanding. */ |
| 593 | 	int	fb_cgwait;		/* cg writes outstanding. */ |
| 594 | }; |
| 595 | |
| 596 | /* |
| 597 | * A "freework" structure handles the release of a tree of blocks or a single |
| 598 | * block. Each indirect block in a tree is allocated its own freework |
| 599 | * structure so that the indirect block may be freed only when all of its |
| 600 | * children are freed. In this way we enforce the rule that an allocated |
| 601 | * block must have a valid path to a root that is journaled. Each child |
| 602 | * block acquires a reference and when the ref hits zero the parent ref |
| 603 | * is decremented. If there is no parent the freeblks ref is decremented. |
| 604 | */ |
| 605 | struct freework { |
| 606 | 	struct	worklist fw_list;		/* Delayed worklist. */ |
| 607 | #	define	fw_state fw_list.wk_state |
| 608 | 	LIST_ENTRY(freework) fw_segs;		/* Seg list. */ |
| 609 | 	TAILQ_ENTRY(freework) fw_next;		/* Hash/Trunc list. */ |
| 610 | 	struct	jnewblk	 *fw_jnewblk;		/* Journal entry to cancel. */ |
| 611 | 	struct	freeblks *fw_freeblks;		/* Root of operation. */ |
| 612 | 	struct	freework *fw_parent;		/* Parent indirect. */ |
| 613 | 	struct	indirdep *fw_indir;		/* indirect block. */ |
| 614 | 	ufs2_daddr_t	 fw_blkno;		/* Our block #. */ |
| 615 | 	ufs_lbn_t	 fw_lbn;		/* Original lbn before free. */ |
| 616 | 	uint16_t	 fw_frags;		/* Number of frags. */ |
| 617 | 	uint16_t	 fw_ref;		/* Number of children out. */ |
| 618 | 	uint16_t	 fw_off;		/* Current working position. */ |
| 619 | 	uint16_t	 fw_start;		/* Start of partial truncate. */ |
| 620 | }; |
| 621 | |
| 622 | /* |
| 623 | * A "freedep" structure is allocated to track the completion of a bitmap |
| 624 | * write for a freework. One freedep may cover many freed blocks so long |
| 625 | * as they reside in the same cylinder group. When the cg is written |
| 626 | * the freedep decrements the ref on the freework which may permit it |
| 627 | * to be freed as well. |
| 628 | */ |
| 629 | struct freedep { |
| 630 | 	struct	worklist fd_list;	/* Delayed worklist. */ |
| 631 | 	struct	freework *fd_freework;	/* Parent freework. */ |
| 632 | }; |
| 633 | |
| 634 | /* |
| 635 | * A "freefile" structure is attached to an inode when its |
| 636 | * link count is reduced to zero. It marks the inode as free in |
| 637 | * the cylinder group map after the zero'ed inode has been written |
| 638 | * to disk and any associated blocks and fragments have been freed. |
| 639 | */ |
| 640 | struct freefile { |
| 641 | 	struct	worklist fx_list;	/* id_inowait or delayed worklist */ |
| 642 | 	mode_t	fx_mode;		/* mode of inode */ |
| 643 | 	ino_t	fx_oldinum;		/* inum of the unlinked file */ |
| 644 | 	struct	vnode *fx_devvp;	/* filesystem device vnode */ |
| 645 | 	struct	workhead fx_jwork;	/* journal work pending. */ |
| 646 | }; |
| 647 | |
| 648 | /* |
| 649 | * A "diradd" structure is linked to an "inodedep" id_inowait list when a |
| 650 | * new directory entry is allocated that references the inode described |
| 651 | * by "inodedep". When the inode itself is written (either the initial |
| 652 | * allocation for new inodes or with the increased link count for |
| 653 | * existing inodes), the COMPLETE flag is set in da_state. If the entry |
| 654 | * is for a newly allocated inode, the "inodedep" structure is associated |
| 655 | * with a bmsafemap which prevents the inode from being written to disk |
| 656 | * until the cylinder group has been updated. Thus the da_state COMPLETE |
| 657 | * flag cannot be set until the inode bitmap dependency has been removed. |
| 658 | * When creating a new file, it is safe to write the directory entry that |
| 659 | * claims the inode once the referenced inode has been written. Since |
| 660 | * writing the inode clears the bitmap dependencies, the DEPCOMPLETE flag |
| 661 | * in the diradd can be set unconditionally when creating a file. When |
| 662 | * creating a directory, there are two additional dependencies described by |
| 663 | * mkdir structures (see their description below). When these dependencies |
| 664 | * are resolved the DEPCOMPLETE flag is set in the diradd structure. |
| 665 | * If there are multiple links created to the same inode, there will be |
| 666 | * a separate diradd structure created for each link. The diradd is |
| 667 | * linked onto the pg_diraddhd list of the pagedep for the directory |
| 668 | * page that contains the entry. When a directory page is written, |
| 669 | * the pg_diraddhd list is traversed to rollback any entries that are |
| 670 | * not yet ready to be written to disk. If a directory entry is being |
| 671 | * changed (by rename) rather than added, the DIRCHG flag is set and |
| 672 | * the da_previous entry points to the entry that will be "removed" |
| 673 | * once the new entry has been committed. During rollback, entries |
| 674 | * with da_previous are replaced with the previous inode number rather |
| 675 | * than zero. |
| 676 | * |
| 677 | * The overlaying of da_pagedep and da_previous is done to keep the |
| 678 | * structure down. If a da_previous entry is present, the pointer to its |
| 679 | * pagedep is available in the associated dirrem entry. If the DIRCHG flag |
| 680 | * is set, the da_previous entry is valid; if not set the da_pagedep entry |
| 681 | * is valid. The DIRCHG flag never changes; it is set when the structure |
| 682 | * is created if appropriate and is never cleared. |
| 683 | */ |
| 684 | struct diradd { |
| 685 | 	struct	worklist da_list;	/* id_inowait or id_pendinghd list */ |
| 686 | #	define	da_state da_list.wk_state /* state of the new directory entry */ |
| 687 | 	LIST_ENTRY(diradd) da_pdlist;	/* pagedep holding directory block */ |
| 688 | 	doff_t	da_offset;		/* offset of new dir entry in dir blk */ |
| 689 | 	ino_t	da_newinum;		/* inode number for the new dir entry */ |
| 690 | 	union { |
| 691 | 	struct	dirrem *dau_previous;	/* entry being replaced in dir change */ |
| 692 | 	struct	pagedep *dau_pagedep;	/* pagedep dependency for addition */ |
| 693 | 	} da_un; |
| 694 | 	struct workhead da_jwork;	/* Journal work awaiting completion. */ |
| 695 | }; |
| 696 | #define	da_previous da_un.dau_previous |
| 697 | #define	da_pagedep da_un.dau_pagedep |
| 698 | |
| 699 | /* |
| 700 | * Two "mkdir" structures are needed to track the additional dependencies |
| 701 | * associated with creating a new directory entry. Normally a directory |
| 702 | * addition can be committed as soon as the newly referenced inode has been |
| 703 | * written to disk with its increased link count. When a directory is |
| 704 | * created there are two additional dependencies: writing the directory |
| 705 | * data block containing the "." and ".." entries (MKDIR_BODY) and writing |
| 706 | * the parent inode with the increased link count for ".." (MKDIR_PARENT). |
| 707 | * These additional dependencies are tracked by two mkdir structures that |
| 708 | * reference the associated "diradd" structure. When they have completed, |
| 709 | * they set the DEPCOMPLETE flag on the diradd so that it knows that its |
| 710 | * extra dependencies have been completed. The md_state field is used only |
| 711 | * to identify which type of dependency the mkdir structure is tracking. |
| 712 | * It is not used in the mainline code for any purpose other than consistency |
| 713 | * checking. All the mkdir structures in the system are linked together on |
| 714 | * a list. This list is needed so that a diradd can find its associated |
| 715 | * mkdir structures and deallocate them if it is prematurely freed (as for |
| 716 | * example if a mkdir is immediately followed by a rmdir of the same directory). |
| 717 | * Here, the free of the diradd must traverse the list to find the associated |
| 718 | * mkdir structures that reference it. The deletion would be faster if the |
| 719 | * diradd structure were simply augmented to have two pointers that referenced |
| 720 | * the associated mkdir's. However, this would increase the size of the diradd |
| 721 | * structure to speed a very infrequent operation. |
| 722 | */ |
| 723 | struct mkdir { |
| 724 | 	struct	worklist md_list;	/* id_inowait or buffer holding dir */ |
| 725 | #	define	md_state md_list.wk_state /* type: MKDIR_PARENT or MKDIR_BODY */ |
| 726 | 	struct	diradd *md_diradd;	/* associated diradd */ |
| 727 | 	struct	jaddref *md_jaddref;	/* dependent jaddref. */ |
| 728 | 	struct	buf *md_buf;		/* MKDIR_BODY: buffer holding dir */ |
| 729 | 	LIST_ENTRY(mkdir) md_mkdirs;	/* list of all mkdirs */ |
| 730 | }; |
| 731 | |
| 732 | /* |
| 733 | * A "dirrem" structure describes an operation to decrement the link |
| 734 | * count on an inode. The dirrem structure is attached to the pg_dirremhd |
| 735 | * list of the pagedep for the directory page that contains the entry. |
| 736 | * It is processed after the directory page with the deleted entry has |
| 737 | * been written to disk. |
| 738 | */ |
| 739 | struct dirrem { |
| 740 | 	struct	worklist dm_list;	/* delayed worklist */ |
| 741 | #	define	dm_state dm_list.wk_state /* state of the old directory entry */ |
| 742 | 	LIST_ENTRY(dirrem) dm_next;	/* pagedep's list of dirrem's */ |
| 743 | 	LIST_ENTRY(dirrem) dm_inonext;	/* inodedep's list of dirrem's */ |
| 744 | 	struct	jremrefhd dm_jremrefhd;	/* Pending remove reference deps. */ |
| 745 | 	ino_t	dm_oldinum;		/* inum of the removed dir entry */ |
| 746 | 	doff_t	dm_offset;		/* offset of removed dir entry in blk */ |
| 747 | 	union { |
| 748 | 	struct	pagedep *dmu_pagedep;	/* pagedep dependency for remove */ |
| 749 | 	ino_t	dmu_dirinum;		/* parent inode number (for rmdir) */ |
| 750 | 	} dm_un; |
| 751 | 	struct workhead dm_jwork;	/* Journal work awaiting completion. */ |
| 752 | }; |
| 753 | #define	dm_pagedep dm_un.dmu_pagedep |
| 754 | #define	dm_dirinum dm_un.dmu_dirinum |
| 755 | |
| 756 | /* |
| 757 | * A "newdirblk" structure tracks the progress of a newly allocated |
| 758 | * directory block from its creation until it is claimed by its on-disk |
| 759 | * inode. When a block is allocated to a directory, an fsync of a file |
| 760 | * whose name is within that block must ensure not only that the block |
| 761 | * containing the file name has been written, but also that the on-disk |
| 762 | * inode references that block. When a new directory block is created, |
| 763 | * we allocate a newdirblk structure which is linked to the associated |
| 764 | * allocdirect (on its ad_newdirblk list). When the allocdirect has been |
| 765 | * satisfied, the newdirblk structure is moved to the inodedep id_bufwait |
| 766 | * list of its directory to await the inode being written. When the inode |
| 767 | * is written, the directory entries are fully committed and can be |
| 768 | * deleted from their pagedep->id_pendinghd and inodedep->id_pendinghd |
| 769 | * lists. Note that we could track directory blocks allocated to indirect |
| 770 | * blocks using a similar scheme with the allocindir structures. Rather |
| 771 | * than adding this level of complexity, we simply write those newly |
| 772 | * allocated indirect blocks synchronously as such allocations are rare. |
| 773 | * In the case of a new directory the . and .. links are tracked with |
| 774 | * a mkdir rather than a pagedep. In this case we track the mkdir |
| 775 | * so it can be released when it is written. A workhead is used |
| 776 | * to simplify canceling a mkdir that is removed by a subsequent dirrem. |
| 777 | */ |
| 778 | struct newdirblk { |
| 779 | 	struct	worklist db_list;	/* id_inowait or pg_newdirblk */ |
| 780 | #	define	db_state db_list.wk_state |
| 781 | 	struct	pagedep *db_pagedep;	/* associated pagedep */ |
| 782 | 	struct	workhead db_mkdir; |
| 783 | }; |
| 784 | |
| 785 | /* |
| 786 | * The inoref structure holds the elements common to jaddref and jremref |
| 787 | * so they may easily be queued in-order on the inodedep. |
| 788 | */ |
| 789 | struct inoref { |
| 790 | 	struct	worklist if_list;	/* Journal pending or jseg entries. */ |
| 791 | #	define	if_state if_list.wk_state |
| 792 | 	TAILQ_ENTRY(inoref) if_deps;	/* Links for inodedep. */ |
| 793 | 	struct	jsegdep	*if_jsegdep;	/* Will track our journal record. */ |
| 794 | 	off_t		if_diroff;	/* Directory offset. */ |
| 795 | 	ino_t		if_ino;		/* Inode number. */ |
| 796 | 	ino_t		if_parent;	/* Parent inode number. */ |
| 797 | 	nlink_t		if_nlink;	/* nlink before addition. */ |
| 798 | 	uint16_t	if_mode;	/* File mode, needed for IFMT. */ |
| 799 | }; |
| 800 | |
| 801 | /* |
| 802 | * A "jaddref" structure tracks a new reference (link count) on an inode |
| 803 | * and prevents the link count increase and bitmap allocation until a |
| 804 | * journal entry can be written. Once the journal entry is written, |
| 805 | * the inode is put on the pendinghd of the bmsafemap and a diradd or |
| 806 | * mkdir entry is placed on the bufwait list of the inode. The DEPCOMPLETE |
| 807 | * flag is used to indicate that all of the required information for writing |
| 808 | * the journal entry is present. MKDIR_BODY and MKDIR_PARENT are used to |
| 809 | * differentiate . and .. links from regular file names. NEWBLOCK indicates |
| 810 | * a bitmap is still pending. If a new reference is canceled by a delete |
| 811 | * prior to writing the journal the jaddref write is canceled and the |
| 812 | * structure persists to prevent any disk-visible changes until it is |
| 813 | * ultimately released when the file is freed or the link is dropped again. |
| 814 | */ |
| 815 | struct jaddref { |
| 816 | 	struct	inoref	ja_ref;		/* see inoref above. */ |
| 817 | #	define	ja_list	ja_ref.if_list	/* Jrnl pending, id_inowait, dm_jwork.*/ |
| 818 | #	define	ja_state ja_ref.if_list.wk_state |
| 819 | 	LIST_ENTRY(jaddref) ja_bmdeps;	/* Links for bmsafemap. */ |
| 820 | 	union { |
| 821 | 		struct	diradd	*jau_diradd;	/* Pending diradd. */ |
| 822 | 		struct	mkdir	*jau_mkdir;	/* MKDIR_{PARENT,BODY} */ |
| 823 | 	} ja_un; |
| 824 | }; |
| 825 | #define	ja_diradd	ja_un.jau_diradd |
| 826 | #define	ja_mkdir	ja_un.jau_mkdir |
| 827 | #define	ja_diroff	ja_ref.if_diroff |
| 828 | #define	ja_ino		ja_ref.if_ino |
| 829 | #define	ja_parent	ja_ref.if_parent |
| 830 | #define	ja_mode		ja_ref.if_mode |
| 831 | |
| 832 | /* |
| 833 | * A "jremref" structure tracks a removed reference (unlink) on an |
| 834 | * inode and prevents the directory remove from proceeding until the |
| 835 | * journal entry is written. Once the journal has been written the remove |
| 836 | * may proceed as normal. |
| 837 | */ |
| 838 | struct jremref { |
| 839 | 	struct	inoref	jr_ref;		/* see inoref above. */ |
| 840 | #	define	jr_list	jr_ref.if_list	/* Linked to softdep_journal_pending. */ |
| 841 | #	define	jr_state jr_ref.if_list.wk_state |
| 842 | 	LIST_ENTRY(jremref) jr_deps;	/* Links for dirrem. */ |
| 843 | 	struct	dirrem	*jr_dirrem;	/* Back pointer to dirrem. */ |
| 844 | }; |
| 845 | |
| 846 | /* |
| 847 | * A "jmvref" structure tracks a name relocations within the same |
| 848 | * directory block that occur as a result of directory compaction. |
| 849 | * It prevents the updated directory entry from being written to disk |
| 850 | * until the journal entry is written. Once the journal has been |
| 851 | * written the compacted directory may be written to disk. |
| 852 | */ |
| 853 | struct jmvref { |
| 854 | 	struct	worklist jm_list;	/* Linked to softdep_journal_pending. */ |
| 855 | 	LIST_ENTRY(jmvref) jm_deps;	/* Jmvref on pagedep. */ |
| 856 | 	struct pagedep	*jm_pagedep;	/* Back pointer to pagedep. */ |
| 857 | 	ino_t		jm_parent;	/* Containing directory inode number. */ |
| 858 | 	ino_t		jm_ino;		/* Inode number of our entry. */ |
| 859 | 	off_t		jm_oldoff;	/* Our old offset in directory. */ |
| 860 | 	off_t		jm_newoff;	/* Our new offset in directory. */ |
| 861 | }; |
| 862 | |
| 863 | /* |
| 864 | * A "jnewblk" structure tracks a newly allocated block or fragment and |
| 865 | * prevents the direct or indirect block pointer as well as the cg bitmap |
| 866 | * from being written until it is logged. After it is logged the jsegdep |
| 867 | * is attached to the allocdirect or allocindir until the operation is |
| 868 | * completed or reverted. If the operation is reverted prior to the journal |
| 869 | * write the jnewblk structure is maintained to prevent the bitmaps from |
| 870 | * reaching the disk. Ultimately the jnewblk structure will be passed |
| 871 | * to the free routine as the in memory cg is modified back to the free |
| 872 | * state at which time it can be released. It may be held on any of the |
| 873 | * fx_jwork, fw_jwork, fb_jwork, ff_jwork, nb_jwork, or ir_jwork lists. |
| 874 | */ |
| 875 | struct jnewblk { |
| 876 | 	struct	worklist jn_list;	/* See lists above. */ |
| 877 | #	define	jn_state jn_list.wk_state |
| 878 | 	struct	jsegdep	*jn_jsegdep;	/* Will track our journal record. */ |
| 879 | 	LIST_ENTRY(jnewblk) jn_deps;	/* Jnewblks on sm_jnewblkhd. */ |
| 880 | 	struct	worklist *jn_dep;	/* Dependency to ref completed seg. */ |
| 881 | 	ufs_lbn_t	jn_lbn;		/* Lbn to which allocated. */ |
| 882 | 	ufs2_daddr_t	jn_blkno;	/* Blkno allocated */ |
| 883 | 	ino_t		jn_ino;		/* Ino to which allocated. */ |
| 884 | 	int		jn_oldfrags;	/* Previous fragments when extended. */ |
| 885 | 	int		jn_frags;	/* Number of fragments. */ |
| 886 | }; |
| 887 | |
| 888 | /* |
| 889 | * A "jblkdep" structure tracks jfreeblk and jtrunc records attached to a |
| 890 | * freeblks structure. |
| 891 | */ |
| 892 | struct jblkdep { |
| 893 | 	struct	worklist jb_list;	/* For softdep journal pending. */ |
| 894 | 	struct	jsegdep *jb_jsegdep;	/* Reference to the jseg. */ |
| 895 | 	struct	freeblks *jb_freeblks;	/* Back pointer to freeblks. */ |
| 896 | 	LIST_ENTRY(jblkdep) jb_deps;	/* Dep list on freeblks. */ |
| 897 | |
| 898 | }; |
| 899 | |
| 900 | /* |
| 901 | * A "jfreeblk" structure tracks the journal write for freeing a block |
| 902 | * or tree of blocks. The block pointer must not be cleared in the inode |
| 903 | * or indirect prior to the jfreeblk being written to the journal. |
| 904 | */ |
| 905 | struct jfreeblk { |
| 906 | 	struct	jblkdep	jf_dep;		/* freeblks linkage. */ |
| 907 | 	ufs_lbn_t	jf_lbn;		/* Lbn from which blocks freed. */ |
| 908 | 	ufs2_daddr_t	jf_blkno;	/* Blkno being freed. */ |
| 909 | 	ino_t		jf_ino;		/* Ino from which blocks freed. */ |
| 910 | 	int		jf_frags;	/* Number of frags being freed. */ |
| 911 | }; |
| 912 | |
| 913 | /* |
| 914 | * A "jfreefrag" tracks the freeing of a single block when a fragment is |
| 915 | * extended or an indirect page is replaced. It is not part of a larger |
| 916 | * freeblks operation. |
| 917 | */ |
| 918 | struct jfreefrag { |
| 919 | 	struct	worklist fr_list;	/* Linked to softdep_journal_pending. */ |
| 920 | #	define	fr_state fr_list.wk_state |
| 921 | 	struct	jsegdep	*fr_jsegdep;	/* Will track our journal record. */ |
| 922 | 	struct freefrag	*fr_freefrag;	/* Back pointer to freefrag. */ |
| 923 | 	ufs_lbn_t	fr_lbn;		/* Lbn from which frag freed. */ |
| 924 | 	ufs2_daddr_t	fr_blkno;	/* Blkno being freed. */ |
| 925 | 	ino_t		fr_ino;		/* Ino from which frag freed. */ |
| 926 | 	int		fr_frags;	/* Size of frag being freed. */ |
| 927 | }; |
| 928 | |
| 929 | /* |
| 930 | * A "jtrunc" journals the intent to truncate an inode's data or extent area. |
| 931 | */ |
| 932 | struct jtrunc { |
| 933 | 	struct	jblkdep	jt_dep;		/* freeblks linkage. */ |
| 934 | 	off_t		jt_size;	/* Final file size. */ |
| 935 | 	int		jt_extsize;	/* Final extent size. */ |
| 936 | 	ino_t		jt_ino;		/* Ino being truncated. */ |
| 937 | }; |
| 938 | |
| 939 | /* |
| 940 | * A "jfsync" journals the completion of an fsync which invalidates earlier |
| 941 | * jtrunc records in the journal. |
| 942 | */ |
| 943 | struct jfsync { |
| 944 | 	struct worklist	jfs_list;	/* For softdep journal pending. */ |
| 945 | 	off_t		jfs_size;	/* Sync file size. */ |
| 946 | 	int		jfs_extsize;	/* Sync extent size. */ |
| 947 | 	ino_t		jfs_ino;	/* ino being synced. */ |
| 948 | }; |
| 949 | |
| 950 | /* |
| 951 | * A "jsegdep" structure tracks a single reference to a written journal |
| 952 | * segment so the journal space can be reclaimed when all dependencies |
| 953 | * have been written. It can hang off of id_inowait, dm_jwork, da_jwork, |
| 954 | * nb_jwork, ff_jwork, or fb_jwork lists. |
| 955 | */ |
| 956 | struct jsegdep { |
| 957 | 	struct	worklist jd_list;	/* See above for lists. */ |
| 958 | #	define	jd_state jd_list.wk_state |
| 959 | 	struct	jseg	*jd_seg;	/* Our journal record. */ |
| 960 | }; |
| 961 | |
| 962 | /* |
| 963 | * A "jseg" structure contains all of the journal records written in a |
| 964 | * single disk write. The jaddref and jremref structures are linked into |
| 965 | * js_entries so thay may be completed when the write completes. The |
| 966 | * js_entries also include the write dependency structures: jmvref, |
| 967 | * jnewblk, jfreeblk, jfreefrag, and jtrunc. The js_refs field counts |
| 968 | * the number of entries on the js_entries list. Thus there is a single |
| 969 | * jseg entry to describe each journal write. |
| 970 | */ |
| 971 | struct jseg { |
| 972 | 	struct	worklist js_list;	/* b_deps link for journal */ |
| 973 | #	define	js_state js_list.wk_state |
| 974 | 	struct	workhead js_entries;	/* Entries awaiting write */ |
| 975 | 	LIST_HEAD(, freework) js_indirs;/* List of indirects in this seg. */ |
| 976 | 	TAILQ_ENTRY(jseg) js_next;	/* List of all unfinished segments. */ |
| 977 | 	struct	jblocks *js_jblocks;	/* Back pointer to block/seg list */ |
| 978 | 	struct	buf *js_buf;		/* Buffer while unwritten */ |
| 979 | 	uint64_t js_seq;		/* Journal record sequence number. */ |
| 980 | 	uint64_t js_oldseq;		/* Oldest valid sequence number. */ |
| 981 | 	int	js_size;		/* Size of journal record in bytes. */ |
| 982 | 	int	js_cnt;			/* Total items allocated. */ |
| 983 | 	int	js_refs;		/* Count of js_entries items. */ |
| 984 | }; |
| 985 | |
| 986 | /* |
| 987 | * A 'sbdep' structure tracks the head of the free inode list and |
| 988 | * superblock writes. This makes sure the superblock is always pointing at |
| 989 | * the first possible unlinked inode for the suj recovery process. If a |
| 990 | * block write completes and we discover a new head is available the buf |
| 991 | * is dirtied and the dep is kept. See the description of the UNLINK* |
| 992 | * flags above for more details. |
| 993 | */ |
| 994 | struct sbdep { |
| 995 | 	struct	worklist sb_list;	/* b_dep linkage */ |
| 996 | 	struct	fs	*sb_fs;		/* Filesystem pointer within buf. */ |
| 997 | 	struct	ufsmount *sb_ump;	/* Our mount structure */ |
| 998 | }; |
| 999 | |
| 1000 | /* |
| 1001 | * Private journaling structures. |
| 1002 | */ |
| 1003 | struct jblocks { |
| 1004 | 	struct jseglst	jb_segs;	/* TAILQ of current segments. */ |
| 1005 | 	struct jseg	*jb_writeseg;	/* Next write to complete. */ |
| 1006 | 	struct jseg	*jb_oldestseg;	/* Oldest segment with valid entries. */ |
| 1007 | 	struct jextent	*jb_extent;	/* Extent array. */ |
| 1008 | 	uint64_t	jb_nextseq;	/* Next sequence number. */ |
| 1009 | 	uint64_t	jb_oldestwrseq;	/* Oldest written sequence number. */ |
| 1010 | 	uint8_t		jb_needseg;	/* Need a forced segment. */ |
| 1011 | 	uint8_t		jb_suspended;	/* Did journal suspend writes? */ |
| 1012 | 	int		jb_avail;	/* Available extents. */ |
| 1013 | 	int		jb_used;	/* Last used extent. */ |
| 1014 | 	int		jb_head;	/* Allocator head. */ |
| 1015 | 	int		jb_off;		/* Allocator extent offset. */ |
| 1016 | 	int		jb_blocks;	/* Total disk blocks covered. */ |
| 1017 | 	int		jb_free;	/* Total disk blocks free. */ |
| 1018 | 	int		jb_min;		/* Minimum free space. */ |
| 1019 | 	int		jb_low;		/* Low on space. */ |
| 1020 | 	int		jb_age;		/* Insertion time of oldest rec. */ |
| 1021 | }; |
| 1022 | |
| 1023 | struct jextent { |
| 1024 | 	ufs2_daddr_t	je_daddr;	/* Disk block address. */ |
| 1025 | 	int		je_blocks;	/* Disk block count. */ |
| 1026 | }; |
| 1027 | |
| 1028 | /* |
| 1029 | * Hash table declarations. |
| 1030 | */ |
| 1031 | LIST_HEAD(mkdirlist, mkdir); |
| 1032 | LIST_HEAD(pagedep_hashhead, pagedep); |
| 1033 | LIST_HEAD(inodedep_hashhead, inodedep); |
| 1034 | LIST_HEAD(newblk_hashhead, newblk); |
| 1035 | LIST_HEAD(bmsafemap_hashhead, bmsafemap); |
| 1036 | TAILQ_HEAD(indir_hashhead, freework); |
| 1037 | |
| 1038 | /* |
| 1039 | * Per-filesystem soft dependency data. |
| 1040 | * Allocated at mount and freed at unmount. |
| 1041 | */ |
| 1042 | struct mount_softdeps { |
| 1043 | 	struct	rwlock sd_fslock;		/* softdep lock */ |
| 1044 | 	struct	workhead sd_workitem_pending;	/* softdep work queue */ |
| 1045 | 	struct	worklist *sd_worklist_tail;	/* Tail pointer for above */ |
| 1046 | 	struct	workhead sd_journal_pending;	/* journal work queue */ |
| 1047 | 	struct	worklist *sd_journal_tail;	/* Tail pointer for above */ |
| 1048 | 	struct	jblocks *sd_jblocks;		/* Journal block information */ |
| 1049 | 	struct	inodedeplst sd_unlinked;	/* Unlinked inodes */ |
| 1050 | 	struct	bmsafemaphd sd_dirtycg;		/* Dirty CGs */ |
| 1051 | 	struct	mkdirlist sd_mkdirlisthd;	/* Track mkdirs */ |
| 1052 | 	struct	pagedep_hashhead *sd_pdhash;	/* pagedep hash table */ |
| 1053 | 	u_long	sd_pdhashsize;			/* pagedep hash table size-1 */ |
| 1054 | 	long	sd_pdnextclean;			/* next hash bucket to clean */ |
| 1055 | 	struct	inodedep_hashhead *sd_idhash;	/* inodedep hash table */ |
| 1056 | 	u_long	sd_idhashsize;			/* inodedep hash table size-1 */ |
| 1057 | 	long	sd_idnextclean;			/* next hash bucket to clean */ |
| 1058 | 	struct	newblk_hashhead *sd_newblkhash;	/* newblk hash table */ |
| 1059 | 	u_long	sd_newblkhashsize;		/* newblk hash table size-1 */ |
| 1060 | 	struct	bmsafemap_hashhead *sd_bmhash;	/* bmsafemap hash table */ |
| 1061 | 	u_long	sd_bmhashsize;			/* bmsafemap hash table size-1*/ |
| 1062 | 	struct	indir_hashhead *sd_indirhash;	/* indir hash table */ |
| 1063 | 	uint64_t sd_indirhashsize;		/* indir hash table size-1 */ |
| 1064 | 	int	sd_on_journal;			/* Items on the journal list */ |
| 1065 | 	int	sd_on_worklist;			/* Items on the worklist */ |
| 1066 | 	int	sd_deps;			/* Total dependency count */ |
| 1067 | 	int	sd_accdeps;			/* accumulated dep count */ |
| 1068 | 	int	sd_req;				/* Wakeup when deps hits 0. */ |
| 1069 | 	int	sd_flags;			/* comm with flushing thread */ |
| 1070 | 	int	sd_cleanups;			/* Calls to cleanup */ |
| 1071 | 	struct	thread *sd_flushtd;		/* thread handling flushing */ |
| 1072 | 	TAILQ_ENTRY(mount_softdeps) sd_next;	/* List of softdep filesystem */ |
| 1073 | 	struct	ufsmount *sd_ump;		/* our ufsmount structure */ |
| 1074 | 	uint64_t sd_curdeps[D_LAST + 1];	/* count of current deps */ |
| 1075 | 	struct	workhead sd_alldeps[D_LAST + 1];/* Lists of all deps */ |
| 1076 | }; |
| 1077 | /* |
| 1078 | * Flags for communicating with the syncer thread. |
| 1079 | */ |
| 1080 | #define FLUSH_EXIT	0x0001	/* time to exit */ |
| 1081 | #define FLUSH_CLEANUP	0x0002	/* need to clear out softdep structures */ |
| 1082 | #define	FLUSH_STARTING	0x0004	/* flush thread not yet started */ |
| 1083 | #define	FLUSH_RC_ACTIVE	0x0008	/* a thread is flushing the mount point */ |
| 1084 | #define	FLUSH_DI_ACTIVE	0x0010	/* a thread is processing delayed |
| 1085 | 				 inactivations */ |
| 1086 | |
| 1087 | /* |
| 1088 | * Keep the old names from when these were in the ufsmount structure. |
| 1089 | */ |
| 1090 | #define	softdep_workitem_pending	um_softdep->sd_workitem_pending |
| 1091 | #define	softdep_worklist_tail		um_softdep->sd_worklist_tail |
| 1092 | #define	softdep_journal_pending		um_softdep->sd_journal_pending |
| 1093 | #define	softdep_journal_tail		um_softdep->sd_journal_tail |
| 1094 | #define	softdep_jblocks			um_softdep->sd_jblocks |
| 1095 | #define	softdep_unlinked		um_softdep->sd_unlinked |
| 1096 | #define	softdep_dirtycg			um_softdep->sd_dirtycg |
| 1097 | #define	softdep_mkdirlisthd		um_softdep->sd_mkdirlisthd |
| 1098 | #define	pagedep_hashtbl			um_softdep->sd_pdhash |
| 1099 | #define	pagedep_hash_size		um_softdep->sd_pdhashsize |
| 1100 | #define	pagedep_nextclean		um_softdep->sd_pdnextclean |
| 1101 | #define	inodedep_hashtbl		um_softdep->sd_idhash |
| 1102 | #define	inodedep_hash_size		um_softdep->sd_idhashsize |
| 1103 | #define	inodedep_nextclean		um_softdep->sd_idnextclean |
| 1104 | #define	newblk_hashtbl			um_softdep->sd_newblkhash |
| 1105 | #define	newblk_hash_size		um_softdep->sd_newblkhashsize |
| 1106 | #define	bmsafemap_hashtbl		um_softdep->sd_bmhash |
| 1107 | #define	bmsafemap_hash_size		um_softdep->sd_bmhashsize |
| 1108 | #define	indir_hashtbl			um_softdep->sd_indirhash |
| 1109 | #define	indir_hash_size			um_softdep->sd_indirhashsize |
| 1110 | #define	softdep_on_journal		um_softdep->sd_on_journal |
| 1111 | #define	softdep_on_worklist		um_softdep->sd_on_worklist |
| 1112 | #define	softdep_deps			um_softdep->sd_deps |
| 1113 | #define	softdep_accdeps			um_softdep->sd_accdeps |
| 1114 | #define	softdep_req			um_softdep->sd_req |
| 1115 | #define	softdep_flags			um_softdep->sd_flags |
| 1116 | #define	softdep_flushtd			um_softdep->sd_flushtd |
| 1117 | #define	softdep_curdeps			um_softdep->sd_curdeps |
| 1118 | #define	softdep_alldeps			um_softdep->sd_alldeps |