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

📄 vnodeops_gfs.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
			goto bad;		}		gp = *gpp;		if (access(gp, GWRITE))			goto bad;		if ((gp->g_mode&GFMT) == GFDIR) {			u.u_error = EISDIR;			goto bad;		}		if (vap->va_size == 0) {			if (GTRUNC(gp, (u_long) 0, u.u_cred) == GNOFUNC) {				u.u_error == EOPNOTSUPP;			}			if (u.u_error)				goto bad;		}	}	return(u.u_error);bad:	gput(*gpp);bad2:	/* entry for *gpp already unlocked */	*gpp = NULL;	return (u.u_error);}intvop_remove(pgp, name, cred)	struct gnode *pgp;	char *name;	struct ucred *cred;{	struct nameidata *ndp = &u.u_nd;	struct gnode *gp;		ndp->ni_nameiop = DELETE | LOCKPARENT | NOMOUNT;	ndp->ni_dirp = name;	u.u_cdir = pgp;	gfs_unlock(pgp);	gp = GNAMEI(ndp);	if (gp == NULL) {		return (u.u_error);	}	/* Can't unlink directories -- use vop_rmdir. */	if ((gp->g_mode & GFMT) == GFDIR) {		u.u_error = EISDIR;		goto out;	}	if (gp->g_dev != pgp->g_dev) {		u.u_error = EBUSY;		goto out;	}	if (gp->g_flag & GTEXT)		xrele(gp);	GUNLINK(gp, ndp);out:	if (gp != pgp) 		gput(gp);	gput(pgp);	return (u.u_error);}intvop_link(sgp, tdgp, name, savectime, cred)        struct gnode *sgp;        struct gnode *tdgp;        char *name;	struct timeval *savectime;        struct ucred *cred;{        register struct nameidata *ndp = &u.u_nd;        struct gnode *gp;        int     error = 0;        if (sgp->g_nlink >= LINK_MAX) {                gput(sgp);                grele(tdgp);                u.u_error = EMLINK;                return (u.u_error);        }        if (((sgp->g_mode & GFMT) == GFDIR) && !suser()) {                gput(sgp);                grele(tdgp);                u.u_error = EPERM;                return (u.u_error);        }        sgp->g_nlink++;        sgp->g_flag |= GCHG;        (void) GUPDATE(sgp, timepick, timepick, 1, cred);	/* save ctime for successful cases */	*savectime = sgp->g_ctime;	/* save ctime for successful cases */        ndp->ni_nameiop = CREATE | NOMOUNT;        ndp->ni_dirp = name;        u.u_cdir = tdgp;        gfs_unlock(sgp);        gp = GNAMEI(ndp);        if (u.u_error) {                error = u.u_error;                goto errout;        }        if (gp) {                gput(gp);                error = EEXIST;                goto errout;        }        if (sgp->g_mp != tdgp->g_mp) {                error = EXDEV;                goto errout;        }        /* The UFS routine will do the de-referencing */        (void) GLINK(sgp, ndp);	grele(tdgp);        return (u.u_error);errout:        gfs_lock(sgp);        sgp->g_nlink--;        sgp->g_flag |= GCHG;        (void) GUPDATE(sgp, timepick, timepick, 1, cred);	/* don't bother saving ctime for unsuccessful cases */        gput(sgp);        grele(tdgp);        return (u.u_error = error);}intvop_rename(sdp, sname, tdp, tname, cred)	struct gnode *sdp;	char *sname;	struct gnode *tdp;	char *tname;	struct ucred *cred;{	struct nameidata tnd;	struct nameidata *sndp = &u.u_nd;	struct gnode *sgp;	int ret;	tnd.ni_nameiop = CREATE | LOCKPARENT | NOMOUNT;	tnd.ni_segflg = UIO_SYSSPACE;	tnd.ni_dirp = tname;	/*	 * If sname is a symbolic link, ni_dirp can be bogus	 * when passed down to the local rename routine. SAVE_DIRP	 * ensures the original ni_dirp remains in tact.	 */	sndp->ni_nameiop = DELETE | LOCKPARENT | NOMOUNT | SAVE_DIRP;	sndp->ni_dirp = sname;	u.u_cdir = sdp;	/*	 * XXX - Unlock sdp and tdp to guard against	 * rename("/mnt/a", "/mnt/a/b")	 */	gfs_unlock(sdp);	if (tdp != sdp)		gfs_unlock(tdp);	sgp = GNAMEI(sndp);	if (sgp == NULL) {		return (u.u_error);	}	/*	 * XXX (cont) - If sgp and tdp are equal, target	 * is a direct descendent of source.	 */	if (sgp == tdp) {		gput(sgp);		if (sgp == sdp)			grele(sdp);		else			gput(sdp);		u.u_error = EINVAL;		return (u.u_error);	}	if (sgp->g_flag & GMOUNT) {		gput(sgp);		if (sgp == sdp)			grele(sdp);		else			gput(sdp);		u.u_error = EBUSY;		return (u.u_error);	}	u.u_cdir = tdp;	ret = GRENAMEG(sgp, sdp, sndp, tdp, &tnd, NOMOUNT);	return (u.u_error);}intvop_symlink(pgp, fname, vap, tname, cred)	struct gnode *pgp;	char *fname;	struct vattr *vap;	/* NOT DEALT WITH */	char *tname;	struct ucred *cred;{	register struct nameidata *ndp = &u.u_nd;	struct 	uio auio;	struct iovec aiov;	register struct gnode *gp;		ndp->ni_nameiop = CREATE | LOCKPARENT | NOMOUNT;	ndp->ni_dirp = fname;	u.u_cdir = pgp;	gfs_unlock(pgp);	gp = GNAMEI(ndp);	if (gp) {		gput(gp);		gput(ndp->ni_pdir);		return (EEXIST);	}	if (u.u_error)		return (u.u_error);	if(GSYMLINK(ndp, tname) == GNOFUNC)		u.u_error = EOPNOTSUPP;	return (u.u_error);}intvop_mkdir(pgp, name, vap, gpp, cred)	struct gnode *pgp;	char *name;	struct vattr *vap;	struct gnode **gpp;	struct ucred *cred;{	register struct nameidata *ndp = &u.u_nd;	ndp->ni_nameiop = CREATE | LOCKPARENT | NOMOUNT;	ndp->ni_dirp = name;	u.u_cdir = pgp;	gfs_unlock(pgp);	*gpp = GNAMEI(ndp);	if (u.u_error) {		return (u.u_error);	}	if (*gpp != NULL) {		gput(*gpp);		gput(ndp->ni_pdir);		return (EEXIST);	}	*gpp = GMKDIR(ndp->ni_pdir, name, vap->va_mode);	return (u.u_error);	}intvop_rmdir(pgp, name, cred)	struct gnode *pgp;	char *name;	struct ucred *cred;{	register struct nameidata *ndp = &u.u_nd;	struct gnode *gp;	int ret;		ndp->ni_nameiop = DELETE | LOCKPARENT | NOMOUNT;	ndp->ni_dirp = name;	u.u_cdir = pgp;	gfs_unlock(pgp);	gp = GNAMEI(ndp);	if (gp == NULL) {		return (u.u_error);	}	/*	 * GFS requires the sfs be passed a directory gp. Lets make	 * sure the client was as thoughtful.	 */	if ((gp->g_mode & GFMT) != GFDIR) {		/*		 * Two gputs are ok here because rmdir(".") will		 * never execute this conditional.		 */		gput(ndp->ni_pdir);		gput(gp);		u.u_error = ENOTDIR;		return(ENOTDIR);	}	/*	 * Don't allow rmdir's of mount points. Name translations	 * would fail when attempting to traverse removed entry.	 */	if (gp->g_flag & GMOUNT) {		gput(gp);		if (gp == ndp->ni_pdir)			grele(ndp->ni_pdir);		else			gput(ndp->ni_pdir);		u.u_error = EBUSY;		return(EBUSY);	}	ret = GRMDIR(gp, ndp);	return (u.u_error);}intvop_readdir(gp, uiop, cred)	struct gnode *gp;	struct uio *uiop;	struct ucred *cred;{	if (access(gp, GREAD)) {		u.u_error = EPERM;		return(EPERM);			/* XXX */	}	(void) GGETDIRENTS(gp, uiop, cred);	return (u.u_error);}intvop_brelse(gp, bp)	struct gnode *gp;	struct buf *bp;{	bp->b_resid = 0;	brelse(bp);}intvop_bread(gp, lbn, bpp)	struct gnode *gp;	daddr_t lbn;	struct buf **bpp;{	register struct buf *bp;	register daddr_t bn;	register int size;	size = blksize(FS(gp), gp, lbn);	bn = GBMAP(gp, lbn, B_READ, 0, 0);	if ((long)bn < 0) {		bp = geteblk(size);		clrbuf(bp);	} else if (gp->g_lastr + 1 == lbn) {		bp = breada(gp->g_dev, bn, size, rablock, rasize,			(struct gnode *) 0);	} else {		bp = bread(gp->g_dev, bn, size, (struct gnode *) 0);	}	gp->g_lastr = lbn;	gp->g_flag |= GACC;	if (bp->b_flags & B_ERROR) {		brelse(bp);		return (EIO);	} else {		*bpp = bp;		return (0);	}}/* * Perform chown operation on gnode gp.  This is similar to chown1() * in gfs_syscalls.c, but we leave some preliminary error checking and * the GUPDATE operation for the caller to do.  This routine should not * exist; please merge these someday. */struct dquot *inoquota();chown2(gp, uid, gid)	register struct gnode *gp;	register int uid, gid;{#ifdef QUOTA	register long change;#endif	if (uid == -1)		uid = gp->g_uid;	if (gid == -1)		gid = gp->g_gid;#ifdef QUOTA	if (gp->g_uid == uid)		change = 0;	else		change = gp->g_blocks;	(void) chkdq(gp, -change, 1);	(void) chkiq(gp->g_dev, gp, gp->g_uid, 1);	dquot_lock(gp->g_dquot);	dqrele(gp->g_dquot);	dquot_unlock(gp->g_dquot);#endif	gp->g_uid = uid;	gp->g_gid = gid;	gp->g_flag |= (GCHG | GCID);			if (u.u_ruid != 0)		gp->g_mode &= ~(GSUID|GSGID);#ifdef QUOTA	gp->g_dquot = inoquota(gp);	(void) chkdq(gp, change, 1);	(void) chkiq(gp->g_dev, (struct gnode *)NULL, uid, 1);	return (u.u_error);	#else	return(0);#endif}gattr_to_nattr(gp, na)	register struct gnode *gp;	register struct nfsfattr *na;{	na->na_type = (enum nfsftype)IFTOVT(gp->g_mode);	na->na_mode = gp->g_mode;	na->na_uid = gp->g_uid;	na->na_gid = gp->g_gid;	na->na_fsid = gp->g_dev;	na->na_nodeid = gp->g_number;	na->na_nlink = gp->g_nlink;	na->na_size = gp->g_size;	na->na_atime = gp->g_atime;	na->na_mtime = gp->g_mtime;	na->na_ctime = gp->g_ctime;	na->na_rdev = gp->g_rdev;	na->na_blocks = gp->g_blocks;/*	na->na_blocksize =  KLUDGE: CALLER MUST DO THIS */}/* * Special kludge for fifos (named pipes)   * [to adhere to (unwritten) NFS Protocol Spec] * * VFIFO is not in the protocol spec (VNON will be replaced by VFIFO) * so the over-the-wire representation is VCHR with a '-1' device number. * * NOTE: This kludge becomes unnecessary with the Protocol Revision, *       but it may be necessary to support it (backwards compatibility). *//* identify fifo in nfs attributes */#define NA_ISFIFO(NA)	(((NA)->na_type == NFS_FIFO_TYPE) && \			    ((NA)->na_rdev == NFS_FIFO_DEV))nattr_to_gattr(gp, na)	register struct gnode *gp;	register struct nfsfattr *na;{	gp->g_mode = na->na_mode;	gp->g_uid = na->na_uid;	gp->g_gid = na->na_gid;	gp->g_nlink = na->na_nlink; 	gp->g_size = na->na_size; 	gp->g_atime = na->na_atime;	gp->g_mtime = na->na_mtime;	gp->g_ctime = na->na_ctime; 	gp->g_blocks = na->na_blocks;	gp->g_rdev = na->na_rdev;	/*   *** From nfssrc 4.0 ***	 * This bit of ugliness is a *TEMPORARY* hack to preserve the	 * over-the-wire protocols for named-pipe vnodes.  It remaps the	 * special over-the-wire type to the VFIFO type. (see note in nfs.h)	 *	 * BUYER BEWARE:	 *  If you are porting the NFS to a non-SUN server, you probably	 *  don't want to include the following block of code.  The	 *  over-the-wire special file types will be changing with the	 *  NFS Protocol Revision.	 */	if (NA_ISFIFO(na)) {		gp->g_mode = (gp->g_mode & ~GFMT) | GFPORT;		gp->g_rdev = 0;	}}

⌨️ 快捷键说明

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