STATIC void free_lock(lk, line) struct lockit *lk; int line; {  if (lk->lkt_held == -1) panic("softdep_unlock: lock not held at line %d", line); lk->lkt_held = -1; splx(lk->lkt_spl); }  STATIC void acquire_lock_interlocked(lk, s, line) struct lockit *lk; int s; int line; { pid_t holder; int original_line;  if (lk->lkt_held != -1) { holder = lk->lkt_held; original_line = lk->lkt_line; FREE_LOCK_INTERLOCKED(lk); if (holder == CURPROC->p_pid) panic("softdep_lock: locking against myself, acquired at line %d, relocked at line %d", original_line, line); else panic("softdep_lock: lock held by %d, acquired at line %d, relocked at line %d", holder, original_line, line); } lk->lkt_held = CURPROC->p_pid; lk->lkt_line = line; lk->lkt_spl = s; lockcnt++; }  STATIC int free_lock_interlocked(lk, line) struct lockit *lk; int line; {  if (lk->lkt_held == -1) panic("softdep_unlock_interlocked: lock not held at line %d", line); lk->lkt_held = -1;  return (lk->lkt_spl); } #endif    struct sema { int	value; pid_t	holder; char	*name; int	prio; int	timo; }; STATIC	void sema_init __P((struct sema *, char *, int, int)); STATIC	int sema_get __P((struct sema *, struct lockit *)); STATIC	void sema_release __P((struct sema *));  STATIC void sema_init(semap, name, prio, timo) struct sema *semap; char *name; int prio, timo; {  semap->holder = -1; semap->value = 0; semap->name = name; semap->prio = prio; semap->timo = timo; }
LIST_HEAD(, buf) pcbphashhead[PCBPHASHSIZE];#define PCBPHASH(vp, lbn) ((((vaddr_t)(vp) >> 8) ^ (lbn)) & (PCBPHASHSIZE - 1))/* * Internal function prototypes. */STATIC	void softdep_error __P((char *, int));STATIC	void drain_output __P((struct vnode *, int));STATIC	int getdirtybuf __P((struct buf **, int));STATIC	void clear_remove __P((struct proc *));STATIC	void clear_inodedeps __P((struct proc *));STATIC	int flush_pagedep_deps __P((struct vnode *, struct mount *,	    struct diraddhd *));STATIC	int flush_inodedep_deps __P((struct fs *, ino_t));STATIC	int handle_written_filepage __P((struct pagedep *, struct buf *));STATIC  void diradd_inode_written __P((struct diradd *, struct inodedep *));STATIC	int handle_written_inodeblock __P((struct inodedep *, struct buf *));STATIC	void handle_allocdirect_partdone __P((struct allocdirect *));STATIC	void handle_allocindir_partdone __P((struct allocindir *));STATIC	void initiate_write_filepage __P((struct pagedep *, struct buf *));STATIC	void handle_written_mkdir __P((struct mkdir *, int));STATIC	void initiate_write_inodeblock __P((struct inodedep *, struct buf *));STATIC	void handle_workitem_freefile __P((struct freefile *));STATIC	void handle_workitem_remove __P((struct dirrem *));STATIC	struct dirrem *newdirrem __P((struct buf *, struct inode *,	    struct inode *, int, struct dirrem **));STATIC	void free_diradd __P((struct diradd *));STATIC	void free_allocindir __P((struct allocindir *, struct inodedep *));STATIC	int indir_trunc __P((struct inode *, ufs_daddr_t, int, ufs_lbn_t,	    long *));STATIC	void deallocate_dependencies __P((struct buf *, struct inodedep *));STATIC	void free_allocdirect __P((struct allocdirectlst *,	    struct allocdirect *, int));STATIC	int check_inode_unwritten __P((struct inodedep *));STATIC	int free_inodedep __P((struct inodedep *));STATIC	void handle_workitem_freeblocks __P((struct freeblks *));STATIC	void merge_inode_lists __P((struct inodedep *));STATIC	void setup_allocindir_phase2 __P((struct buf *, struct inode *,	    struct allocindir *));STATIC	struct allocindir *newallocindir __P((struct inode *, int, ufs_daddr_t,	    ufs_daddr_t));STATIC	void handle_workitem_freefrag __P((struct freefrag *));STATIC	struct freefrag *newfreefrag __P((struct inode *, ufs_daddr_t, long));STATIC	void allocdirect_merge __P((struct allocdirectlst *,	    struct allocdirect *, struct allocdirect *));STATIC	struct bmsafemap *bmsafemap_lookup __P((struct buf *));STATIC	int newblk_lookup __P((struct fs *, ufs_daddr_t, int,	    struct newblk **));STATIC	int inodedep_lookup __P((struct fs *, ino_t, int, struct inodedep **));STATIC	int pagedep_lookup __P((struct inode *, ufs_lbn_t, int,	    struct pagedep **));STATIC	void pause_timer __P((void *));STATIC	int request_cleanup __P((int, int));STATIC	int process_worklist_item __P((struct mount *, int));STATIC	void add_to_worklist __P((struct worklist *));STATIC struct buf *softdep_setup_pagecache __P((struct inode *, ufs_lbn_t,						long));STATIC void softdep_collect_pagecache __P((struct inode *));STATIC void softdep_free_pagecache __P((struct inode *));STATIC struct vnode *softdep_lookupvp(struct fs *, ino_t);STATIC struct buf *softdep_lookup_pcbp __P((struct vnode *, ufs_lbn_t));void softdep_pageiodone __P((struct buf *));/* * Exported softdep operations. */void softdep_disk_io_initiation __P((struct buf *));void softdep_disk_write_complete __P((struct buf *));void softdep_deallocate_dependencies __P((struct buf *));void softdep_move_dependencies __P((struct buf *, struct buf *));int softdep_count_dependencies __P((struct buf *bp, int, int));struct bio_ops bioops = {	softdep_disk_io_initiation,		/* io_start */	softdep_disk_write_complete,		/* io_complete */	softdep_deallocate_dependencies,	/* io_deallocate */	softdep_move_dependencies,		/* io_movedeps */	softdep_count_dependencies,		/* io_countdeps */	softdep_pageiodone,			/* io_pagedone */};/* * Locking primitives. * * For a uniprocessor, all we need to do is protect against disk * interrupts. For a multiprocessor, this lock would have to be * a mutex. A single mutex is used throughout this file, though * finer grain locking could be used if contention warranted it. * * For a multiprocessor, the sleep call would accept a lock and * release it after the sleep processing was complete. In a uniprocessor * implementation there is no such interlock, so we simple mark * the places where it needs to be done with the `interlocked' form * of the lock calls. Since the uniprocessor sleep already interlocks * the spl, there is nothing that really needs to be done. */#ifndef /* NOT */ DEBUGSTATIC struct lockit {	int	lkt_spl;} lk = { 0 };#define ACQUIRE_LOCK(lk)		(lk)->lkt_spl = splbio()#define FREE_LOCK(lk)			splx((lk)->lkt_spl)#define ACQUIRE_LOCK_INTERLOCKED(lk,s)	(lk)->lkt_spl = (s)#define FREE_LOCK_INTERLOCKED(lk)	((lk)->lkt_spl)#else /* DEBUG */STATIC struct lockit {	int	lkt_spl;	pid_t	lkt_held;	int     lkt_line;} lk = { 0, -1 };STATIC int lockcnt;STATIC	void acquire_lock __P((struct lockit *, int));STATIC	void free_lock __P((struct lockit *, int));STATIC	void acquire_lock_interlocked __P((struct lockit *, int, int));STATIC	int free_lock_interlocked __P((struct lockit *, int));#define ACQUIRE_LOCK(lk)		acquire_lock(lk, __LINE__)#define FREE_LOCK(lk)			free_lock(lk, __LINE__)#define ACQUIRE_LOCK_INTERLOCKED(lk,s)	acquire_lock_interlocked(lk, (s), __LINE__)#define FREE_LOCK_INTERLOCKED(lk)	free_lock_interlocked(lk, __LINE__)STATIC voidacquire_lock(lk, line)	struct lockit *lk;	int line;{	pid_t holder;	int original_line;	if (lk->lkt_held != -1) {		holder = lk->lkt_held;		original_line = lk->lkt_line;		FREE_LOCK(lk);		if (holder == CURPROC->p_pid)			panic("softdep_lock: locking against myself, acquired at line %d, relocked at line %d", original_line, line);		else			panic("softdep_lock: lock held by %d, acquired at line %d, relocked at line %d", holder, original_line, line);	}	lk->lkt_spl = splbio();	lk->lkt_held = CURPROC->p_pid;	lk->lkt_line = line;	lockcnt++;}STATIC voidfree_lock(lk, line)	struct lockit *lk;	int line;{	if (lk->lkt_held == -1)		panic("softdep_unlock: lock not held at line %d", line);	lk->lkt_held = -1;	splx(lk->lkt_spl);}STATIC voidacquire_lock_interlocked(lk, s, line)	struct lockit *lk;	int s;	int line;{	pid_t holder;	int original_line;	if (lk->lkt_held != -1) {		holder = lk->lkt_held;		original_line = lk->lkt_line;		FREE_LOCK_INTERLOCKED(lk);		if (holder == CURPROC->p_pid)			panic("softdep_lock: locking against myself, acquired at line %d, relocked at line %d", original_line, line);		else			panic("softdep_lock: lock held by %d, acquired at line %d, relocked at line %d", holder, original_line, line);	}	lk->lkt_held = CURPROC->p_pid;	lk->lkt_line = line;	lk->lkt_spl = s;	lockcnt++;}STATIC intfree_lock_interlocked(lk, line)	struct lockit *lk;	int line;{	if (lk->lkt_held == -1)		panic("softdep_unlock_interlocked: lock not held at line %d", line);	lk->lkt_held = -1;	return (lk->lkt_spl);}#endif /* DEBUG *//* * Place holder for real semaphores. */struct sema {	int	value;	pid_t	holder;	char	*name;	int	prio;	int	timo;};STATIC	void sema_init __P((struct sema *, char *, int, int));STATIC	int sema_get __P((struct sema *, struct lockit *));STATIC	void sema_release __P((struct sema *));STATIC voidsema_init(semap, name, prio, timo)	struct sema *semap;	char *name;	int prio, timo;{	semap->holder = -1;	semap->value = 0;	semap->name = name;	semap->prio = prio;	semap->timo = timo;}