ffs_softdep.c (92462) | ffs_softdep.c (92728) |
---|---|
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 * --- 25 unchanged lines hidden (view full) --- 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 * from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00 39 */ 40 41#include <sys/cdefs.h> | 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 * --- 25 unchanged lines hidden (view full) --- 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 * from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00 39 */ 40 41#include <sys/cdefs.h> |
42__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 92462 2002-03-17 01:25:47Z mckusick $"); | 42__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 92728 2002-03-19 22:40:48Z alfred $"); |
43 44/* 45 * For now we want the safety net that the DIAGNOSTIC and DEBUG flags provide. 46 */ 47#ifndef DIAGNOSTIC 48#define DIAGNOSTIC 49#endif 50#ifndef DEBUG --- 92 unchanged lines hidden (view full) --- 143 ((unsigned)(type) < D_LAST ? memtype[type]->ks_shortdesc : "???") 144/* 145 * End system adaptaion definitions. 146 */ 147 148/* 149 * Internal function prototypes. 150 */ | 43 44/* 45 * For now we want the safety net that the DIAGNOSTIC and DEBUG flags provide. 46 */ 47#ifndef DIAGNOSTIC 48#define DIAGNOSTIC 49#endif 50#ifndef DEBUG --- 92 unchanged lines hidden (view full) --- 143 ((unsigned)(type) < D_LAST ? memtype[type]->ks_shortdesc : "???") 144/* 145 * End system adaptaion definitions. 146 */ 147 148/* 149 * Internal function prototypes. 150 */ |
151static void softdep_error __P((char *, int)); 152static void drain_output __P((struct vnode *, int)); 153static int getdirtybuf __P((struct buf **, int)); 154static void clear_remove __P((struct thread *)); 155static void clear_inodedeps __P((struct thread *)); 156static int flush_pagedep_deps __P((struct vnode *, struct mount *, 157 struct diraddhd *)); 158static int flush_inodedep_deps __P((struct fs *, ino_t)); 159static int handle_written_filepage __P((struct pagedep *, struct buf *)); 160static void diradd_inode_written __P((struct diradd *, struct inodedep *)); 161static int handle_written_inodeblock __P((struct inodedep *, struct buf *)); 162static void handle_allocdirect_partdone __P((struct allocdirect *)); 163static void handle_allocindir_partdone __P((struct allocindir *)); 164static void initiate_write_filepage __P((struct pagedep *, struct buf *)); 165static void handle_written_mkdir __P((struct mkdir *, int)); 166static void initiate_write_inodeblock __P((struct inodedep *, struct buf *)); 167static void handle_workitem_freefile __P((struct freefile *)); 168static void handle_workitem_remove __P((struct dirrem *, struct vnode *)); 169static struct dirrem *newdirrem __P((struct buf *, struct inode *, 170 struct inode *, int, struct dirrem **)); 171static void free_diradd __P((struct diradd *)); 172static void free_allocindir __P((struct allocindir *, struct inodedep *)); 173static void free_newdirblk __P((struct newdirblk *)); 174static int indir_trunc __P((struct freeblks *, ufs_daddr_t, int, ufs_lbn_t, 175 long *)); 176static void deallocate_dependencies __P((struct buf *, struct inodedep *)); 177static void free_allocdirect __P((struct allocdirectlst *, 178 struct allocdirect *, int)); 179static int check_inode_unwritten __P((struct inodedep *)); 180static int free_inodedep __P((struct inodedep *)); 181static void handle_workitem_freeblocks __P((struct freeblks *, int)); 182static void merge_inode_lists __P((struct inodedep *)); 183static void setup_allocindir_phase2 __P((struct buf *, struct inode *, 184 struct allocindir *)); 185static struct allocindir *newallocindir __P((struct inode *, int, ufs_daddr_t, 186 ufs_daddr_t)); 187static void handle_workitem_freefrag __P((struct freefrag *)); 188static struct freefrag *newfreefrag __P((struct inode *, ufs_daddr_t, long)); 189static void allocdirect_merge __P((struct allocdirectlst *, 190 struct allocdirect *, struct allocdirect *)); 191static struct bmsafemap *bmsafemap_lookup __P((struct buf *)); 192static int newblk_lookup __P((struct fs *, ufs_daddr_t, int, 193 struct newblk **)); 194static int inodedep_lookup __P((struct fs *, ino_t, int, struct inodedep **)); 195static int pagedep_lookup __P((struct inode *, ufs_lbn_t, int, 196 struct pagedep **)); 197static void pause_timer __P((void *)); 198static int request_cleanup __P((int, int)); 199static int process_worklist_item __P((struct mount *, int)); 200static void add_to_worklist __P((struct worklist *)); | 151static void softdep_error(char *, int); 152static void drain_output(struct vnode *, int); 153static int getdirtybuf(struct buf **, int); 154static void clear_remove(struct thread *); 155static void clear_inodedeps(struct thread *); 156static int flush_pagedep_deps(struct vnode *, struct mount *, 157 struct diraddhd *); 158static int flush_inodedep_deps(struct fs *, ino_t); 159static int handle_written_filepage(struct pagedep *, struct buf *); 160static void diradd_inode_written(struct diradd *, struct inodedep *); 161static int handle_written_inodeblock(struct inodedep *, struct buf *); 162static void handle_allocdirect_partdone(struct allocdirect *); 163static void handle_allocindir_partdone(struct allocindir *); 164static void initiate_write_filepage(struct pagedep *, struct buf *); 165static void handle_written_mkdir(struct mkdir *, int); 166static void initiate_write_inodeblock(struct inodedep *, struct buf *); 167static void handle_workitem_freefile(struct freefile *); 168static void handle_workitem_remove(struct dirrem *, struct vnode *); 169static struct dirrem *newdirrem(struct buf *, struct inode *, 170 struct inode *, int, struct dirrem **); 171static void free_diradd(struct diradd *); 172static void free_allocindir(struct allocindir *, struct inodedep *); 173static void free_newdirblk(struct newdirblk *); 174static int indir_trunc(struct freeblks *, ufs_daddr_t, int, ufs_lbn_t, long *); 175static void deallocate_dependencies(struct buf *, struct inodedep *); 176static void free_allocdirect(struct allocdirectlst *, 177 struct allocdirect *, int); 178static int check_inode_unwritten(struct inodedep *); 179static int free_inodedep(struct inodedep *); 180static void handle_workitem_freeblocks(struct freeblks *, int); 181static void merge_inode_lists(struct inodedep *); 182static void setup_allocindir_phase2(struct buf *, struct inode *, 183 struct allocindir *); 184static struct allocindir *newallocindir(struct inode *, int, ufs_daddr_t, 185 ufs_daddr_t); 186static void handle_workitem_freefrag(struct freefrag *); 187static struct freefrag *newfreefrag(struct inode *, ufs_daddr_t, long); 188static void allocdirect_merge(struct allocdirectlst *, 189 struct allocdirect *, struct allocdirect *); 190static struct bmsafemap *bmsafemap_lookup(struct buf *); 191static int newblk_lookup(struct fs *, ufs_daddr_t, int, struct newblk **); 192static int inodedep_lookup(struct fs *, ino_t, int, struct inodedep **); 193static int pagedep_lookup(struct inode *, ufs_lbn_t, int, struct pagedep **); 194static void pause_timer(void *); 195static int request_cleanup(int, int); 196static int process_worklist_item(struct mount *, int); 197static void add_to_worklist(struct worklist *); |
201 202/* 203 * Exported softdep operations. 204 */ | 198 199/* 200 * Exported softdep operations. 201 */ |
205static void softdep_disk_io_initiation __P((struct buf *)); 206static void softdep_disk_write_complete __P((struct buf *)); 207static void softdep_deallocate_dependencies __P((struct buf *)); 208static void softdep_move_dependencies __P((struct buf *, struct buf *)); 209static int softdep_count_dependencies __P((struct buf *bp, int)); | 202static void softdep_disk_io_initiation(struct buf *); 203static void softdep_disk_write_complete(struct buf *); 204static void softdep_deallocate_dependencies(struct buf *); 205static void softdep_move_dependencies(struct buf *, struct buf *); 206static int softdep_count_dependencies(struct buf *bp, int); |
210 211/* 212 * Locking primitives. 213 * 214 * For a uniprocessor, all we need to do is protect against disk 215 * interrupts. For a multiprocessor, this lock would have to be 216 * a mutex. A single mutex is used throughout this file, though 217 * finer grain locking could be used if contention warranted it. --- 16 unchanged lines hidden (view full) --- 234#define NOHOLDER ((struct thread *)-1) 235#define SPECIAL_FLAG ((struct thread *)-2) 236static struct lockit { 237 int lkt_spl; 238 struct thread *lkt_held; 239} lk = { 0, NOHOLDER }; 240static int lockcnt; 241 | 207 208/* 209 * Locking primitives. 210 * 211 * For a uniprocessor, all we need to do is protect against disk 212 * interrupts. For a multiprocessor, this lock would have to be 213 * a mutex. A single mutex is used throughout this file, though 214 * finer grain locking could be used if contention warranted it. --- 16 unchanged lines hidden (view full) --- 231#define NOHOLDER ((struct thread *)-1) 232#define SPECIAL_FLAG ((struct thread *)-2) 233static struct lockit { 234 int lkt_spl; 235 struct thread *lkt_held; 236} lk = { 0, NOHOLDER }; 237static int lockcnt; 238 |
242static void acquire_lock __P((struct lockit *)); 243static void free_lock __P((struct lockit *)); 244void softdep_panic __P((char *)); | 239static void acquire_lock(struct lockit *); 240static void free_lock(struct lockit *); 241void softdep_panic(char *); |
245 246#define ACQUIRE_LOCK(lk) acquire_lock(lk) 247#define FREE_LOCK(lk) free_lock(lk) 248 249static void 250acquire_lock(lk) 251 struct lockit *lk; 252{ --- 32 unchanged lines hidden (view full) --- 285{ 286 287 if (lk.lkt_held != NOHOLDER) 288 FREE_LOCK(&lk); 289 panic(msg); 290} 291#endif /* DEBUG */ 292 | 242 243#define ACQUIRE_LOCK(lk) acquire_lock(lk) 244#define FREE_LOCK(lk) free_lock(lk) 245 246static void 247acquire_lock(lk) 248 struct lockit *lk; 249{ --- 32 unchanged lines hidden (view full) --- 282{ 283 284 if (lk.lkt_held != NOHOLDER) 285 FREE_LOCK(&lk); 286 panic(msg); 287} 288#endif /* DEBUG */ 289 |
293static int interlocked_sleep __P((struct lockit *, int, void *, int, 294 const char *, int)); | 290static int interlocked_sleep(struct lockit *, int, void *, int, 291 const char *, int); |
295 296/* 297 * When going to sleep, we must save our SPL so that it does 298 * not get lost if some other process uses the lock while we 299 * are sleeping. We restore it after we have slept. This routine 300 * wraps the interlocking with functions that sleep. The list 301 * below enumerates the available set of operations. 302 */ --- 50 unchanged lines hidden (view full) --- 353 */ 354struct sema { 355 int value; 356 struct thread *holder; 357 char *name; 358 int prio; 359 int timo; 360}; | 292 293/* 294 * When going to sleep, we must save our SPL so that it does 295 * not get lost if some other process uses the lock while we 296 * are sleeping. We restore it after we have slept. This routine 297 * wraps the interlocking with functions that sleep. The list 298 * below enumerates the available set of operations. 299 */ --- 50 unchanged lines hidden (view full) --- 350 */ 351struct sema { 352 int value; 353 struct thread *holder; 354 char *name; 355 int prio; 356 int timo; 357}; |
361static void sema_init __P((struct sema *, char *, int, int)); 362static int sema_get __P((struct sema *, struct lockit *)); 363static void sema_release __P((struct sema *)); | 358static void sema_init(struct sema *, char *, int, int); 359static int sema_get(struct sema *, struct lockit *); 360static void sema_release(struct sema *); |
364 365static void 366sema_init(semap, name, prio, timo) 367 struct sema *semap; 368 char *name; 369 int prio, timo; 370{ 371 --- 55 unchanged lines hidden (view full) --- 427} while (0) 428#define WORKLIST_REMOVE(item) do { \ 429 (item)->wk_state &= ~ONWORKLIST; \ 430 LIST_REMOVE(item, wk_list); \ 431} while (0) 432#define WORKITEM_FREE(item, type) FREE(item, DtoM(type)) 433 434#else /* DEBUG */ | 361 362static void 363sema_init(semap, name, prio, timo) 364 struct sema *semap; 365 char *name; 366 int prio, timo; 367{ 368 --- 55 unchanged lines hidden (view full) --- 424} while (0) 425#define WORKLIST_REMOVE(item) do { \ 426 (item)->wk_state &= ~ONWORKLIST; \ 427 LIST_REMOVE(item, wk_list); \ 428} while (0) 429#define WORKITEM_FREE(item, type) FREE(item, DtoM(type)) 430 431#else /* DEBUG */ |
435static void worklist_insert __P((struct workhead *, struct worklist *)); 436static void worklist_remove __P((struct worklist *)); 437static void workitem_free __P((struct worklist *, int)); | 432static void worklist_insert(struct workhead *, struct worklist *); 433static void worklist_remove(struct worklist *); 434static void workitem_free(struct worklist *, int); |
438 439#define WORKLIST_INSERT(head, item) worklist_insert(head, item) 440#define WORKLIST_REMOVE(item) worklist_remove(item) 441#define WORKITEM_FREE(item, type) workitem_free((struct worklist *)item, type) 442 443static void 444worklist_insert(head, item) 445 struct workhead *head; --- 4839 unchanged lines hidden --- | 435 436#define WORKLIST_INSERT(head, item) worklist_insert(head, item) 437#define WORKLIST_REMOVE(item) worklist_remove(item) 438#define WORKITEM_FREE(item, type) workitem_free((struct worklist *)item, type) 439 440static void 441worklist_insert(head, item) 442 struct workhead *head; --- 4839 unchanged lines hidden --- |