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

📄 gfs_descrip.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* set syncronous write if regular file */		if ((gp->g_mode&GFMT) != GFREG) {			if ((gp->g_mode&GFMT) == GFSOCK) {				/*				 * 004 - If a socket was given, return				 * appropriate error.				 */				u.u_error = EOPNOTSUPP;			}			else {				/*					 * 004 - Not a regular file or socket. Return				 * appropriate error.				 */				u.u_error = EINVAL;			}		        break;	        }		/*		 * Its a regular file, now check fp flag to		 * verify that file is open for writing. If not, return		 * an error.		 */		if ((fp->f_flag&FWRITE) == 0) {			u.u_error = EINVAL;		}		else {			fp->f_flag |= FSYNCRON;		}		break;	case F_CLRSYN:		/* Clear syncronous write flag */		/* First verify it is a regular file. */		if ((gp->g_mode&GFMT) != GFREG) {			if ((gp->g_mode&GFMT) == GFSOCK) {				/*				 * If a socket was given, return				 * appropriate error.				 */				u.u_error = EOPNOTSUPP;			}			else {				/*					 * Not a regular file or socket. Return				 * appropriate error.				 */				u.u_error = EINVAL;			}			break;		}		/* Regular file ! */		fp->f_flag &= ~FSYNCRON;		break;	default:		u.u_error = EINVAL;	}	smp_unlock(&fp->f_lk);}fset(fp, bit, value)	register struct file *fp;	register int bit;	int  value;{	if (value)		fp->f_flag |= bit;	else		fp->f_flag &= ~bit;	return (fioctl(fp, (int)(bit == FNDELAY ? FIONBIO : FIOASYNC),	    (caddr_t)&value));}fgetown(fp, valuep)	register struct file *fp;	register int *valuep;{	register int error;	switch (fp->f_type) {	case DTYPE_SOCKET:		*valuep = ((struct socket *)fp->f_data)->so_pgrp; /*001*/		return (0);	case DTYPE_PIPE:	case DTYPE_PORT:		error = fioctl(fp, (int)FIOGETOWN, (caddr_t)valuep);		return (error);	default:		error = fioctl(fp, (int)TIOCGPGRP, (caddr_t)valuep);		*valuep = -*valuep;		return (error);	}}fsetown(fp, value)	register struct file *fp;	int value;{	if (fp->f_type == DTYPE_SOCKET) {		((struct socket *)fp->f_data)->so_pgrp = value; /*001*/		return (0);	}	if ((fp->f_type == DTYPE_PIPE) || (fp->f_type == DTYPE_PORT))	        return (fioctl(fp, (int)FIOSETOWN, (caddr_t)&value));	if (value > 0) {		struct proc *p = pfind(value);		if (p == 0)			return (EINVAL);		value = p->p_pgrp;	} else		value = -value;	return (fioctl(fp, (int)TIOCSPGRP, (caddr_t)&value));}fioctl(fp, cmd, value)	register struct file *fp;	register int cmd;	register caddr_t value;{	return ((*fp->f_ops->fo_ioctl)(fp, cmd, value, u.u_cred));}close(){	register struct a {		int	i;	} *uap = (struct a *)u.u_ap;	register struct file *fp;	register struct gnode *gp;	register int j;	register caddr_t value;	GETF(fp, uap->i);	/* Release all System-V style record locks, if any */	(void) gno_lockrelease (fp);   /* error? */	gp = (struct gnode *)fp->f_data;	if ((U_POFILE(uap->i) & UF_INUSE) && gp) {		U_POFILE_SET(uap->i, U_POFILE(uap->i) & ~UF_INUSE);		/* clear inuse only when last inuse open file */		for (j=0; j <= u.u_omax; j++)			if ((U_POFILE(j) & UF_INUSE) &&			    U_OFILE(j) == fp)				goto stillinuse;		(*fp->f_ops->fo_ioctl)(fp, FIOCINUSE, value, u.u_cred);		gfs_lock(gp);		gp->g_flag &= ~(GINUSE);		gfs_unlock(gp);		wakeup((caddr_t)&gp->g_flag);	}stillinuse:	U_OFILE_SET(uap->i, NULL);	U_POFILE_SET(uap->i, 0);	/* audit info */	if ( audswitch && gp ) {		u.u_gno_dev[0] = (gp->g_mode&GFMT) == GFCHR ? gp->g_rdev : gp->g_dev;		u.u_gno_num[0] = gp->g_number;		u.u_gno_indx = 1;	}	u.u_error = closef(fp);	AUDIT_CALL ( u.u_event, u.u_error, u.u_r.r_val1, AUD_HDR|AUD_PRM|AUD_RES, (int *)0, 0 );	/*	 * It's a no-op, why call it?	 *	 * if (*pf & UF_MAPPED)	 *	munmapfd(uap->i);	 */	}	fstat(){	register struct file *fp;	register struct a {		int	fdes;		struct	stat *sb;	} *uap;	struct stat ub;	uap = (struct a *)u.u_ap;	GETF(fp, uap->fdes);	switch (fp->f_type) {	case DTYPE_PORT:	case DTYPE_INODE:	case DTYPE_PIPE:		if (fp->f_data)			u.u_error = gno_stat((struct gnode *)fp->f_data, &ub);		else			u.u_error = EBADF;		break;	case DTYPE_SOCKET:		u.u_error = soo_stat((struct socket *)fp->f_data, &ub);		break;	default:		panic("fstat");		/*NOTREACHED*/	}	if (u.u_error == 0)		u.u_error = copyout((caddr_t)&ub,(caddr_t)uap->sb,sizeof (ub));}/* * Allocate descriptor slots in the range [0 .. max_nofile], assuming that * the range [0 .. NOFILE_IN_U] is currently allocated.  Intended to be * called only from the enable_fd_slots macro. * * Return 0 on success, -1 on failure. */intalloc_fd_slots(fdno)	int fdno;  /* fd of interest */{	struct file **ofilep;	char *pofilep;	int count;	/*	 * The first overflow buffer will contain 64 file descriptors.	 * Subsequent allocations will double buffer size.  	 */	if (u.u_of_count == 0)		count = NOFILE_IN_U;	else		count = 2 * u.u_of_count;	/*	 * If the buffer size calculated above is not big enough to be	 * able to reference the fd of interest, we figure out how big	 * the buffer needs to be (making it a multiple of NOFILE_IN_U).	 * This case can happen as a result of a dup2.	 */	if (fdno >= (count + NOFILE_IN_U))		count = (fdno / NOFILE_IN_U) * NOFILE_IN_U;        /*         * Allocate new overflow structures. KM_ALLOC may sleep	 * waiting to allocate virtual memory, but will never	 * fail.         */	KM_ALLOC(ofilep, struct file **, count * sizeof (struct file *), 		 KM_NOFILE, KM_CLEAR);	KM_ALLOC(pofilep, char *, count, KM_NOFILE, KM_CLEAR);	/*	 * Copy current overflow buffer if it exists.	 */	if (u.u_of_count) {		bcopy(u.u_ofile_of, ofilep, 		      u.u_of_count * sizeof (struct file *));		bcopy(u.u_pofile_of, pofilep, u.u_of_count);		/*		 * Release previous memory back to pool.		 */		KM_FREE(u.u_ofile_of, KM_NOFILE);		KM_FREE(u.u_pofile_of, KM_NOFILE);	}	/*	 * Update pointers and current counts.	 */	u.u_ofile_of = ofilep;	u.u_pofile_of = pofilep;	u.u_of_count = count;	return(u.u_error);}/* * Allocate a user file descriptor. */ufalloc(i)	register int i;{	for (; i < max_nofile; i++) {                /*                 * Make sure that slot i exists before referring to it.                 */                if (enable_fd_slot(i))                        return (-1);		if (U_OFILE(i) == NULL) {			u.u_r.r_val1 = i;			U_POFILE_SET(i, 0);			if (i > u.u_omax)				u.u_omax = i;			return (i);		}	}	u.u_error = EMFILE;	return (-1);}ufavail(){        register int i;	register int maxfd;        register int avail;        /*         * If the process hasn't yet had occasion to allocate its         * overflow descriptor array out to the maximum extent, confine the         * search to the preallocated slots and credit the descriptors         * obtainable by reallocating to the maximum extent.         */	if (u.u_omax >= 0)		maxfd = u.u_omax;	else		return(max_nofile);	avail = (max_nofile - maxfd) - 1;        for (i = 0; i < maxfd; i++)                if (U_OFILE(i) == NULL)                        avail++;        return (avail);}struct	file *lastf;/* * Allocate a user file descriptor * and a file structure. * Initialize the descriptor * to point at the file structure. */struct file *falloc(){	register struct file *fp;	register int i;	i = ufalloc(0);	if (i < 0)		return (NULL);	smp_lock(&lk_file, LK_RETRY);	if (lastf == 0)		lastf = file;	for (fp = lastf; fp < fileNFILE; fp++)		if (fp->f_count == 0)			goto slot;	for (fp = file; fp < lastf; fp++)		if (fp->f_count == 0)			goto slot;	smp_unlock(&lk_file);	tablefull("file");	u.u_error = ENFILE;	return (NULL);slot:	fp->f_data = 0;	fp->f_count = 1;	lastf = fp + 1;	smp_unlock(&lk_file);	U_OFILE_SET(i, fp);	fp->f_offset = 0;	crhold(u.u_cred);	fp->f_cred = u.u_cred;	return (fp);}/* * Convert a user supplied file descriptor into a pointer * to a file structure.  Only task is to check range of the descriptor. * Critical paths should use the GETF macro. */struct file *getf(f)	register int f;{	register struct file *fp;	if (f < 0 || (unsigned)f > u.u_omax ||	    (fp = U_OFILE(f)) == NULL) {		u.u_error = EBADF;		return (NULL);	}	return (fp);}/* * Internal form of close. * Decrement reference count on file structure. */int closef_nulls = 0;int gc_count = 0;closef(fp)	register struct file *fp;{	register int othernbuf = 0;	int err;	if (fp == NULL) {		closef_nulls++;		return(0);	}	smp_lock(&fp->f_lk, LK_RETRY);	cleanlocks(fp);			/* 002  */	if(fp->f_flag&FNBUF) {		struct gnode *gp = (struct gnode *)fp->f_data;		othernbuf = asyncclose(gp->g_rdev, fp->f_flag);	}	smp_lock(&lk_file, LK_RETRY);	if (fp->f_count > 1) {		fp->f_count--;		smp_unlock(&lk_file);		if (fp->f_count == fp->f_msgcount)			gc_count += fp->f_msgcount;		smp_unlock(&fp->f_lk);		return(0);	}	smp_unlock(&lk_file);	if(fp->f_flag&FNBUF) {		struct gnode *gp = (struct gnode *)fp->f_data;		fp->f_flag &= ~FNBUF;		if(!othernbuf) {		        gfs_lock(gp);			gp->g_flag &= ~GSYNC;			gfs_unlock(gp);		}	}	err = (*fp->f_ops->fo_close)(fp);	crfree(fp->f_cred);	smp_lock(&lk_file, LK_RETRY);	fp->f_data = (caddr_t)0;	fp->f_count = 0;	smp_unlock(&lk_file);	smp_unlock(&fp->f_lk);	return(err);}/* * Apply an advisory lock on a file descriptor. */flock(){	register struct a {		int	fd;		int	how;	} *uap = (struct a *)u.u_ap;	register struct file *fp;	GETF(fp, uap->fd);	if (fp->f_type != DTYPE_INODE && fp->f_type != DTYPE_PORT ) {		u.u_error = EOPNOTSUPP;		return;	} 	if ((uap->how & (LOCK_UN|LOCK_EX|LOCK_SH)) == 0){ 		u.u_error = EINVAL;			 		return; 	}	if (uap->how & LOCK_UN) {		smp_lock(&fp->f_lk, LK_RETRY);		gno_unlock(fp, FSHLOCK|FEXLOCK);		smp_unlock(&fp->f_lk);		return;	}	/* SMP lock file table entry while locking file descriptor */	smp_lock(&fp->f_lk, LK_RETRY);	/* avoid work... */	if ((fp->f_flag & FEXLOCK) && (uap->how & LOCK_EX) ||	    (fp->f_flag & FSHLOCK) && (uap->how & LOCK_SH)) {		smp_unlock(&fp->f_lk);		return;	}	if (fp->f_data)		u.u_error = gno_lock(fp, uap->how);	else		u.u_error = EBADF;	smp_unlock(&fp->f_lk);}/* *	Normalize System V-style record locks */rewhence(ld, fp, newwhence)	struct flock *ld;	struct file *fp;	int newwhence;{	register int error;	struct gnode *gp = (struct gnode *)fp->f_data;	/* 	 * If reference is to end-of-file, then get current attributes.  	 * Three return values are possible:  unimplemented (GNOFUNC), 	 * error (u.u_error),  and normal return (0).  	 */	if ((ld->l_whence == 2) || (newwhence == 2)) {		if ((error = GGETVAL(gp)) > 0 ) {			return (error);		}	}	/* normalize to start of file */	switch (ld->l_whence) {	case 0:		break;	case 1:		ld->l_start += fp->f_offset;		break;	case 2:		ld->l_start += gp->g_size;		break;	default:		return(EINVAL);	}	/* renormalize to given start point */	switch (ld->l_whence = newwhence) {		case 0:			break;		case 1:			ld->l_start -= fp->f_offset;			break;		case 2:			ld->l_start -= gp->g_size;			break;		default:			return (EINVAL);	}	return(0);}/* * Initialize the file table locks. */finit(){        struct file *fp;	extern struct lk_acct lk_acct;	lockinit(&lk_file, &lock_file_d);	lockinit(&lk_acct, &lock_acct_d);	for (fp = file; fp < fileNFILE; fp++) {	        lockinit(&fp->f_lk, &lock_eachfile_d);	}}

⌨️ 快捷键说明

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