⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ufs_flock.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
			}		} else	if (lckdat->l_start < f->set.l_end			    && lckdat->l_end > f->set.l_start			    && (f->set.l_type == F_WRLCK				|| (f->set.l_type == F_RDLCK				    && lckdat->l_type == F_WRLCK)))				return(f);	}	for ( ; f != NULL; f = f->next) {		if (lckdat->l_start < f->set.l_end		    && lckdat->l_end > f->set.l_start		    && f->set.l_pid != u.u_procp->p_pid		    && (f->set.l_type == F_WRLCK			|| (f->set.l_type == F_RDLCK && lckdat->l_type == F_WRLCK)))			return(f);		if (f->set.l_start > lckdat->l_end)			break;	}	return(NULL);}/* deadflck does the deadlock detection for the given record */struct filock *ufs_deadlock(flp)	register struct filock *flp;{	register struct filock *blck, *sf;	register int blckpid;	blck = flp;	/* current blocking lock pointer */	blckpid = blck->set.l_pid;	do {		if (blckpid == u.u_procp->p_pid)			return((struct filock *)1);		/* if the blocking process is sleeping on a locked region,		 * change the blocked lock to this one.		 */		for (sf = sleeplcks.fl_flck; sf != NULL; sf = sf->next) {			if (blckpid == sf->set.l_pid) {				blckpid = sf->stat.blkpid;				break;			}		}		blck = sf;	} while (blck != NULL);	return((struct filock*) 0);}/* find file id */struct flino *findfid(fp)	register struct file *fp;{	register struct flino *flip;	dev_t d;	register gno_t n;	register struct gnode *gp = (struct gnode *)fp->f_data;	d = gp->g_dev;	n = gp->g_number;	flip = fids;	while (flip != NULL) {		if (flip->fl_dev == d && flip->fl_number == n) {			flip->fl_refcnt++;			break;		}		flip = flip->next;	}	return (flip);}struct flino *allocfid(fp)	register struct file *fp;{	register struct flino *flip;	register struct gnode *gp = (struct gnode *)fp->f_data;	flip = frfid;	if (flip != NULL) {		++flckinfo.filcnt;		++flckinfo.filtot;		/* remove from free list */		frfid = flip->next;		if (frfid != NULL)			frfid->prev = NULL;		/* insert into allocated file identifier list */		if (fids != NULL)			fids->prev = flip;		flip->next = fids;		fids = flip;		/* set up file identifier info */		++flip->fl_refcnt;		flip->fl_dev = gp->g_dev;		flip->fl_number = gp->g_number;	}	return (flip);}freefid(flip)	register struct flino *flip;{	if (--flip->fl_refcnt <= 0 && flip->fl_flck == NULL) {		--flckinfo.filcnt;		if (flip->prev != NULL)			flip->prev->next = flip->next;		else			fids = flip->next;		if (flip->next != NULL)			flip->next->prev = flip->prev;		flip->fl_dev = 0;		flip->fl_number = 0;		flip->fl_refcnt = 0;		if (frfid != NULL)			frfid->prev = flip;		flip->next = frfid;		flip->prev = NULL;		frfid = flip;	}}	/* build file lock free list */flckinit(){	register int i;	/* Initialize file and record locking lock	*/	lockinit(&lk_frlock, &lock_frlock_d);	for (i=0; i<flckinfo.fils; i++) {		freefid(&flinotab[i]);	}	flckinfo.filcnt = 0;	for (i=0; i<flckinfo.recs; i++) {		if (frlock == NULL) {			flox[i].next = flox[i].prev = NULL;			frlock = &flox[i];		} else {			flox[i].next = frlock;			flox[i].prev = NULL;			frlock = (frlock->prev = &flox[i]);		}	}	flckinfo.reccnt = 0;}/* regflck sets the type of span of this (un)lock relative to the specified * already existing locked section. * There are five regions: * *  S_BEFORE        S_START         S_MIDDLE         S_END          S_AFTER *     010            020             030             040             050 *  E_BEFORE        E_START         E_MIDDLE         E_END          E_AFTER *      01             02              03              04              05 * 			|-------------------------------| * * relative to the already locked section.  The type is two octal digits, * the 8's digit is the start type and the 1's digit is the end type. */intregflck(ld, flp)	register struct flock *ld;	register struct filock *flp;{	register int regntype;	if (ld->l_start > flp->set.l_start) {		if (ld->l_start > flp->set.l_end)			return(S_AFTER|E_AFTER);		else if (ld->l_start == flp->set.l_end)			return(S_END|E_AFTER);		else			regntype = S_MIDDLE;	} else if (ld->l_start == flp->set.l_start)		regntype = S_START;	else		regntype = S_BEFORE;	if (ld->l_end > flp->set.l_start) {		if (ld->l_end > flp->set.l_end)			regntype |= E_AFTER;		else if (ld->l_end == flp->set.l_end)			regntype |= E_END;		else			regntype |= E_MIDDLE;	} else if (ld->l_end == flp->set.l_start)		regntype |= E_START;	else		regntype |= E_BEFORE;	return (regntype);}/* locate overlapping file locks */getflck(fp, lckdat)	register struct file *fp;	register struct flock *lckdat;{	register struct flino *flip;	struct filock *found, *insrt = NULL;	/* get file identifier and file lock list pointer if there is one */	/* SMP lock operations on file and record locking linked lists */	smp_lock(&lk_frlock, LK_RETRY);	flip = findfid(fp);	if (flip == NULL) {		smp_unlock(&lk_frlock);		lckdat->l_type = F_UNLCK;		return (0);	}	if (lckdat->l_len == 0)		lckdat->l_end = MAXEND;	else		lckdat->l_end += lckdat->l_start;	/* find overlapping lock */	found = ufs_krlock((struct gnode *)fp->f_data, BLOCKLOCK,		(struct flino *) flip->fl_flck, (struct filock *) lckdat,		(struct flock *) &insrt);	if (found != NULL)		*lckdat = found->set;	else		lckdat->l_type = F_UNLCK;	freefid(flip);	smp_unlock(&lk_frlock);	/* restore length */	if (lckdat->l_end == MAXEND)		lckdat->l_len = 0;	else		lckdat->l_len -= lckdat->l_start;	return (0);}/* clear and set file locks */setflck(fp, lckdat, slpflg)	register struct file *fp;	struct flock *lckdat;	int slpflg;{	register struct flino *flip;	register struct filock *found, *sf;	struct filock *insrt = NULL;	register int retval = 0;	register int contflg = 0;	if (lckdat->l_len == 0)		lckdat->l_end = MAXEND;	else		lckdat->l_end += lckdat->l_start;	/* get or create a file/inode record lock header */	/* SMP lock operations on file and record locking linked lists */	smp_lock(&lk_frlock, LK_RETRY);	flip = findfid(fp);	if (flip == NULL) {		if (lckdat->l_type == F_UNLCK) {			smp_unlock(&lk_frlock);			return (0);		}		if ((flip=allocfid(fp)) == NULL) {			smp_unlock(&lk_frlock);			return (EMFILE);		}	}	do {		contflg = 0;		switch (lckdat->l_type) {		case F_RDLCK:		case F_WRLCK:			if((found = (struct filock *)ufs_krlock((struct gnode *)			fp->f_data, BLOCKLOCK, (struct flino *) flip->fl_flck,			(struct filock *) lckdat, (struct flock *) &insrt))			== NULL)				retval = (int)ufs_krlock((struct gnode *) fp->f_data,				ADJLOCK, flip, insrt, lckdat);			else if (slpflg) {				/* do deadlock detection here */				if(ufs_krlock((struct gnode *)fp->f_data,					DEADLOCK, (struct flino *) found,					(struct filock *) 0, 					(struct flock *) 0))					retval = EDEADLK;				else					if((sf = ufs_krlock((struct gnode *) fp->f_data,					MAKELOCK, &sleeplcks, lckdat, NULL))					== NULL)						retval = ENOSPC;					else {						found->stat.wakeflg++;						sf->stat.blkpid = found->set.l_pid;						smp_unlock(&fp->f_lk);						if (SLEEP(found, PCATCH|(PZERO+1)))							retval = EINTR;						else							contflg = 1;						smp_lock(&fp->f_lk, LK_RETRY);						smp_lock(&lk_frlock, LK_RETRY);						sf->stat.blkpid = 0;						(void) ufs_krlock((struct gnode *) fp->f_data, DELLOCK,						&sleeplcks, sf, (struct flock *)NULL);					}			} else				retval = EACCES;			break;		case F_UNLCK:			/* removing a file record lock */			retval = (int) ufs_krlock((struct gnode *)fp->f_data,			ADJLOCK, flip, flip->fl_flck, lckdat);			break;		default:			retval = EINVAL;	/* invalid lock type */			break;		}	} while (contflg);	freefid(flip);	smp_unlock(&lk_frlock);	return(retval);}/* Clean up record locks left around by process (called in closef) */cleanlocks(fp)	register struct file *fp;{	register struct filock *flp, *nflp;	register struct flino *flip;	/*	 *	Locks can only happen to disk inodes.	 */	if ( fp->f_type != DTYPE_INODE )		return;	/*	 *	Make sure the inode pointer is valid	 */	if ( fp->f_data == NULL )		return;	/* SMP lock operations on file and record locking linked lists */	smp_lock(&lk_frlock, LK_RETRY);	flip = findfid(fp);	if (flip == NULL) {		smp_unlock(&lk_frlock);		return;	}	for (flp=flip->fl_flck; flp!=NULL; flp=nflp) {		nflp = flp->next;		if (flp->set.l_pid == u.u_procp->p_pid)			ufs_krlock((struct gnode *)fp->f_data, DELLOCK, flip, 				flp,(struct flock *) 0);	}	freefid(flip);	smp_unlock(&lk_frlock);	return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -