Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 31 Oct 2012 03:34:07 +0000 (UTC)
From:      Davide Italiano <davide@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r242386 - in head/sys: fs/smbfs netsmb
Message-ID:  <201210310334.q9V3Y7If039084@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davide
Date: Wed Oct 31 03:34:07 2012
New Revision: 242386
URL: http://svn.freebsd.org/changeset/base/242386

Log:
  Fix panic due to page faults while in kernel mode, under conditions of
  VM pressure. The reason is that in some codepaths pointers to stack
  variables were passed from one thread to another.
  
  In collaboration with:	pho
  Reported by:	pho's stress2 suite
  Sponsored by:	iXsystems inc.

Modified:
  head/sys/fs/smbfs/smbfs_io.c
  head/sys/fs/smbfs/smbfs_node.c
  head/sys/fs/smbfs/smbfs_smb.c
  head/sys/fs/smbfs/smbfs_subr.c
  head/sys/fs/smbfs/smbfs_subr.h
  head/sys/fs/smbfs/smbfs_vfsops.c
  head/sys/fs/smbfs/smbfs_vnops.c
  head/sys/netsmb/smb_conn.c
  head/sys/netsmb/smb_dev.c
  head/sys/netsmb/smb_trantcp.c
  head/sys/netsmb/smb_usr.c

Modified: head/sys/fs/smbfs/smbfs_io.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_io.c	Wed Oct 31 03:29:52 2012	(r242385)
+++ head/sys/fs/smbfs/smbfs_io.c	Wed Oct 31 03:34:07 2012	(r242386)
@@ -75,7 +75,7 @@ smbfs_readvdir(struct vnode *vp, struct 
 {
 	struct dirent de;
 	struct componentname cn;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	struct smbfs_fctx *ctx;
 	struct vnode *newvp;
 	struct smbnode *np = VTOSMB(vp);
@@ -84,11 +84,14 @@ smbfs_readvdir(struct vnode *vp, struct 
 
 	np = VTOSMB(vp);
 	SMBVDEBUG("dirname='%s'\n", np->n_name);
-	smb_makescred(&scred, uio->uio_td, cred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, uio->uio_td, cred);
 	offset = uio->uio_offset / DE_SIZE;	/* offset in the directory */
 	limit = uio->uio_resid / DE_SIZE;
-	if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0)
-		return EINVAL;
+	if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) {
+		error = EINVAL;
+		goto out;
+	}
 	while (limit && offset < 2) {
 		limit--;
 		bzero((caddr_t)&de, DE_SIZE);
@@ -104,40 +107,43 @@ smbfs_readvdir(struct vnode *vp, struct 
 		de.d_type = DT_DIR;
 		error = uiomove(&de, DE_SIZE, uio);
 		if (error)
-			return error;
+			goto out;
 		offset++;
 		uio->uio_offset += DE_SIZE;
 	}
-	if (limit == 0)
-		return 0;
+	if (limit == 0) {
+		error = 0;
+		goto out;
+	}
 	if (offset != np->n_dirofs || np->n_dirseq == NULL) {
 		SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs);
 		if (np->n_dirseq) {
-			smbfs_findclose(np->n_dirseq, &scred);
+			smbfs_findclose(np->n_dirseq, scred);
 			np->n_dirseq = NULL;
 		}
 		np->n_dirofs = 2;
 		error = smbfs_findopen(np, "*", 1,
 		    SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR,
-		    &scred, &ctx);
+		    scred, &ctx);
 		if (error) {
 			SMBVDEBUG("can not open search, error = %d", error);
-			return error;
+			goto out;
 		}
 		np->n_dirseq = ctx;
 	} else
 		ctx = np->n_dirseq;
 	while (np->n_dirofs < offset) {
-		error = smbfs_findnext(ctx, offset - np->n_dirofs++, &scred);
+		error = smbfs_findnext(ctx, offset - np->n_dirofs++, scred);
 		if (error) {
-			smbfs_findclose(np->n_dirseq, &scred);
+			smbfs_findclose(np->n_dirseq, scred);
 			np->n_dirseq = NULL;
-			return error == ENOENT ? 0 : error;
+			error = ENOENT ? 0 : error;
+			goto out;
 		}
 	}
 	error = 0;
 	for (; limit; limit--, offset++) {
-		error = smbfs_findnext(ctx, limit, &scred);
+		error = smbfs_findnext(ctx, limit, scred);
 		if (error)
 			break;
 		np->n_dirofs++;
@@ -165,6 +171,8 @@ smbfs_readvdir(struct vnode *vp, struct 
 	if (error == ENOENT)
 		error = 0;
 	uio->uio_offset = offset * DE_SIZE;
+out:
+	smbfs_free_scred(scred);
 	return error;
 }
 
@@ -175,7 +183,7 @@ smbfs_readvnode(struct vnode *vp, struct
 	struct smbnode *np = VTOSMB(vp);
 	struct thread *td;
 	struct vattr vattr;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	int error, lks;
 
 	/*
@@ -223,8 +231,11 @@ smbfs_readvnode(struct vnode *vp, struct
 			np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
 		}
 	}
-	smb_makescred(&scred, td, cred);
-	return smb_read(smp->sm_share, np->n_fid, uiop, &scred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, cred);
+	error = smb_read(smp->sm_share, np->n_fid, uiop, scred);
+	smbfs_free_scred(scred);
+	return (error);
 }
 
 int
@@ -233,7 +244,7 @@ smbfs_writevnode(struct vnode *vp, struc
 {
 	struct smbmount *smp = VTOSMBFS(vp);
 	struct smbnode *np = VTOSMB(vp);
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	struct thread *td;
 	int error = 0;
 
@@ -272,9 +283,11 @@ smbfs_writevnode(struct vnode *vp, struc
 
 	if (vn_rlimit_fsize(vp, uiop, td))
 		return (EFBIG);
-
-	smb_makescred(&scred, td, cred);
-	error = smb_write(smp->sm_share, np->n_fid, uiop, &scred);
+	
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, cred);
+	error = smb_write(smp->sm_share, np->n_fid, uiop, scred);
+	smbfs_free_scred(scred);
 	SMBVDEBUG("after: ofs=%jd,resid=%zd\n", (intmax_t)uiop->uio_offset, 
 	    uiop->uio_resid);
 	if (!error) {
@@ -294,17 +307,19 @@ smbfs_doio(struct vnode *vp, struct buf 
 {
 	struct smbmount *smp = VFSTOSMBFS(vp->v_mount);
 	struct smbnode *np = VTOSMB(vp);
-	struct uio uio, *uiop = &uio;
+	struct uio *uiop;
 	struct iovec io;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	int error = 0;
 
+	uiop = malloc(sizeof(struct uio), M_SMBFSDATA, M_WAITOK);
 	uiop->uio_iov = &io;
 	uiop->uio_iovcnt = 1;
 	uiop->uio_segflg = UIO_SYSSPACE;
 	uiop->uio_td = td;
 
-	smb_makescred(&scred, td, cr);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, cr);
 
 	if (bp->b_iocmd == BIO_READ) {
 	    io.iov_len = uiop->uio_resid = bp->b_bcount;
@@ -313,7 +328,7 @@ smbfs_doio(struct vnode *vp, struct buf 
 	    switch (vp->v_type) {
 	      case VREG:
 		uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
-		error = smb_read(smp->sm_share, np->n_fid, uiop, &scred);
+		error = smb_read(smp->sm_share, np->n_fid, uiop, scred);
 		if (error)
 			break;
 		if (uiop->uio_resid) {
@@ -340,7 +355,7 @@ smbfs_doio(struct vnode *vp, struct buf 
 		uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
 		io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
 		uiop->uio_rw = UIO_WRITE;
-		error = smb_write(smp->sm_share, np->n_fid, uiop, &scred);
+		error = smb_write(smp->sm_share, np->n_fid, uiop, scred);
 
 		/*
 		 * For an interrupted write, the buffer is still valid
@@ -380,11 +395,15 @@ smbfs_doio(struct vnode *vp, struct buf 
 	    } else {
 		bp->b_resid = 0;
 		bufdone(bp);
+		free(uiop, M_SMBFSDATA);
+		smbfs_free_scred(scred);
 		return 0;
 	    }
 	}
 	bp->b_resid = uiop->uio_resid;
 	bufdone(bp);
+	free(uiop, M_SMBFSDATA);
+	smbfs_free_scred(scred);
 	return error;
 }
 
@@ -415,7 +434,7 @@ smbfs_getpages(ap)
 	struct ucred *cred;
 	struct smbmount *smp;
 	struct smbnode *np;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	vm_object_t object;
 	vm_page_t *pages, m;
 
@@ -455,7 +474,8 @@ smbfs_getpages(ap)
 	}
 	VM_OBJECT_UNLOCK(object);
 
-	smb_makescred(&scred, td, cred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, cred);
 
 	bp = getpbuf(&smbfs_pbuf_freecnt);
 
@@ -474,7 +494,8 @@ smbfs_getpages(ap)
 	uio.uio_rw = UIO_READ;
 	uio.uio_td = td;
 
-	error = smb_read(smp->sm_share, np->n_fid, &uio, &scred);
+	error = smb_read(smp->sm_share, np->n_fid, &uio, scred);
+	smbfs_free_scred(scred);
 	pmap_qremove(kva, npages);
 
 	relpbuf(bp, &smbfs_pbuf_freecnt);
@@ -570,7 +591,7 @@ smbfs_putpages(ap)
 	int *rtvals;
 	struct smbmount *smp;
 	struct smbnode *np;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	vm_page_t *pages;
 
 	td = curthread;			/* XXX */
@@ -606,8 +627,10 @@ smbfs_putpages(ap)
 	SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uio.uio_offset, 
 	    uio.uio_resid);
 
-	smb_makescred(&scred, td, cred);
-	error = smb_write(smp->sm_share, np->n_fid, &uio, &scred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, cred);
+	error = smb_write(smp->sm_share, np->n_fid, &uio, scred);
+	smbfs_free_scred(scred);
 /*	VOP_CLOSE(vp, FWRITE, cred, td);*/
 	SMBVDEBUG("paged write done: %d\n", error);
 

Modified: head/sys/fs/smbfs/smbfs_node.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_node.c	Wed Oct 31 03:29:52 2012	(r242385)
+++ head/sys/fs/smbfs/smbfs_node.c	Wed Oct 31 03:34:07 2012	(r242386)
@@ -349,25 +349,27 @@ smbfs_inactive(ap)
 	struct ucred *cred = td->td_ucred;
 	struct vnode *vp = ap->a_vp;
 	struct smbnode *np = VTOSMB(vp);
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	struct vattr va;
 
 	SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vrefcnt(vp));
 	if ((np->n_flag & NOPEN) != 0) {
-		smb_makescred(&scred, td, cred);
+		scred = smbfs_malloc_scred();
+		smb_makescred(scred, td, cred);
 		smbfs_vinvalbuf(vp, td);
 		if (vp->v_type == VREG) {
 			VOP_GETATTR(vp, &va, cred);
 			smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
-			    &np->n_mtime, &scred);
+			    &np->n_mtime, scred);
 		} else if (vp->v_type == VDIR) {
 			if (np->n_dirseq != NULL) {
-				smbfs_findclose(np->n_dirseq, &scred);
+				smbfs_findclose(np->n_dirseq, scred);
 				np->n_dirseq = NULL;
 			}
 		}
 		np->n_flag &= ~NOPEN;
 		smbfs_attr_cacheremove(vp);
+		smbfs_free_scred(scred);
 	}
 	if (np->n_flag & NGONE)
 		vrecycle(vp);

Modified: head/sys/fs/smbfs/smbfs_smb.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_smb.c	Wed Oct 31 03:29:52 2012	(r242385)
+++ head/sys/fs/smbfs/smbfs_smb.c	Wed Oct 31 03:34:07 2012	(r242386)
@@ -87,16 +87,19 @@ smbfs_smb_lockandx(struct smbnode *np, i
 	struct smb_cred *scred)
 {
 	struct smb_share *ssp = np->n_mount->sm_share;
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct mbchain *mbp;
 	u_char ltype = 0;
 	int error;
 
 	if (op == SMB_LOCK_SHARED)
 		ltype |= SMB_LOCKING_ANDX_SHARED_LOCK;
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_LOCKING_ANDX, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_uint8(mbp, 0xff);	/* secondary command */
@@ -116,6 +119,7 @@ smbfs_smb_lockandx(struct smbnode *np, i
 	smb_rq_bend(rqp);
 	error = smb_rq_simple(rqp);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -179,20 +183,24 @@ int
 smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
 	struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct mdchain *mdp;
 	u_int16_t units, bpu, bsize, funits;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION_DISK, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_wstart(rqp);
 	smb_rq_wend(rqp);
 	smb_rq_bstart(rqp);
 	smb_rq_bend(rqp);
 	error = smb_rq_simple(rqp);
 	if (error) {
+		free(rqp, M_SMBFSDATA);
 		smb_rq_done(rqp);
 		return error;
 	}
@@ -208,6 +216,7 @@ smbfs_smb_statfs(struct smb_share *ssp, 
 	sbp->f_files = 0xffff;		/* total file nodes in filesystem */
 	sbp->f_ffree = 0xffff;		/* free file nodes in fs */
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return 0;
 }
 
@@ -244,16 +253,19 @@ static int
 smb_smb_flush(struct smbnode *np, struct smb_cred *scred)
 {
 	struct smb_share *ssp = np->n_mount->sm_share;
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct mbchain *mbp;
 	int error;
 
 	if ((np->n_flag & NOPEN) == 0 || !SMBTOV(np) ||
 	    SMBTOV(np)->v_type != VREG)
 		return 0; /* not a regular open file */
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_FLUSH, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return (error);
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
@@ -262,6 +274,7 @@ smb_smb_flush(struct smbnode *np, struct
 	smb_rq_bend(rqp);
 	error = smb_rq_simple(rqp);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	if (!error)
 		np->n_flag &= ~NFLUSHWIRE;
 	return (error);
@@ -279,7 +292,7 @@ int
 smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
 {
 	struct smb_share *ssp = np->n_mount->sm_share;
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct mbchain *mbp;
 	int error;
 
@@ -288,9 +301,12 @@ smbfs_smb_setfsize(struct smbnode *np, i
 		return (0);
 	}
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_WRITE, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
@@ -304,6 +320,7 @@ smbfs_smb_setfsize(struct smbnode *np, i
 	smb_rq_bend(rqp);
 	error = smb_rq_simple(rqp);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -311,7 +328,7 @@ int
 smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
 		     struct smbfattr *fap, struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = np->n_mount->sm_share;
 	struct mbchain *mbp;
 	struct mdchain *mdp;
@@ -320,9 +337,12 @@ smbfs_smb_query_info(struct smbnode *np,
 	u_int16_t wattr;
 	u_int32_t lint;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	smb_rq_wend(rqp);
@@ -357,6 +377,7 @@ smbfs_smb_query_info(struct smbnode *np,
 		fap->fa_size = lint;
 	} while(0);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -367,15 +388,18 @@ int
 smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
 	struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = np->n_mount->sm_share;
 	struct mbchain *mbp;
 	u_long time;
 	int error, svtz;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	svtz = SSTOVC(ssp)->vc_sopt.sv_tz;
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
@@ -407,6 +431,7 @@ smbfs_smb_setpattr(struct smbnode *np, u
 		}
 	} while(0);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -523,15 +548,18 @@ int
 smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime,
 	struct timespec *atime, struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = np->n_mount->sm_share;
 	struct mbchain *mbp;
 	u_int16_t date, time;
 	int error, tzoff;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION2, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	tzoff = SSTOVC(ssp)->vc_sopt.sv_tz;
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
@@ -556,6 +584,7 @@ smbfs_smb_setftime(struct smbnode *np, s
 	error = smb_rq_simple(rqp);
 	SMBSDEBUG("%d\n", error);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -611,7 +640,7 @@ smbfs_smb_setfattrNT(struct smbnode *np,
 int
 smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = np->n_mount->sm_share;
 	struct mbchain *mbp;
 	struct mdchain *mdp;
@@ -619,9 +648,12 @@ smbfs_smb_open(struct smbnode *np, int a
 	u_int16_t fid, wattr, grantedmode;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_uint16le(mbp, accmode);
@@ -652,6 +684,7 @@ smbfs_smb_open(struct smbnode *np, int a
 		 */
 	} while(0);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	if (error)
 		return error;
 	np->n_fid = fid;
@@ -664,14 +697,17 @@ int
 smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime,
 	struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct mbchain *mbp;
 	u_long time;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_mem(mbp, (caddr_t)&fid, sizeof(fid), MB_MSYSTEM);
@@ -685,6 +721,7 @@ smbfs_smb_close(struct smb_share *ssp, u
 	smb_rq_bend(rqp);
 	error = smb_rq_simple(rqp);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -692,7 +729,7 @@ int
 smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
 	struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = dnp->n_mount->sm_share;
 	struct mbchain *mbp;
 	struct mdchain *mdp;
@@ -702,9 +739,12 @@ smbfs_smb_create(struct smbnode *dnp, co
 	u_long tm;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_uint16le(mbp, SMB_FA_ARCHIVE);		/* attributes  */
@@ -731,20 +771,24 @@ smbfs_smb_create(struct smbnode *dnp, co
 	if (error)
 		return error;
 	smbfs_smb_close(ssp, fid, &ctime, scred);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
 int
 smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = np->n_mount->sm_share;
 	struct mbchain *mbp;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
@@ -757,6 +801,7 @@ smbfs_smb_delete(struct smbnode *np, str
 		error = smb_rq_simple(rqp);
 	}
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -764,14 +809,17 @@ int
 smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp,
 	const char *tname, int tnmlen, struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = src->n_mount->sm_share;
 	struct mbchain *mbp;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_RENAME, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
@@ -790,6 +838,7 @@ smbfs_smb_rename(struct smbnode *src, st
 		error = smb_rq_simple(rqp);
 	} while(0);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -797,14 +846,17 @@ int
 smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp,
 	const char *tname, int tnmlen, u_int16_t flags, struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = src->n_mount->sm_share;
 	struct mbchain *mbp;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_MOVE, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_uint16le(mbp, SMB_TID_UNKNOWN);
@@ -825,6 +877,7 @@ smbfs_smb_move(struct smbnode *src, stru
 		error = smb_rq_simple(rqp);
 	} while(0);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -832,14 +885,17 @@ int
 smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len,
 	struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = dnp->n_mount->sm_share;
 	struct mbchain *mbp;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE_DIRECTORY, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	smb_rq_wend(rqp);
@@ -851,20 +907,24 @@ smbfs_smb_mkdir(struct smbnode *dnp, con
 		error = smb_rq_simple(rqp);
 	}
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
 int
 smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct smb_share *ssp = np->n_mount->sm_share;
 	struct mbchain *mbp;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE_DIRECTORY, scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	smb_rq_wend(rqp);
@@ -876,6 +936,7 @@ smbfs_smb_rmdir(struct smbnode *np, stru
 		error = smb_rq_simple(rqp);
 	}
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 
@@ -1139,13 +1200,16 @@ smbfs_smb_trans2find2(struct smbfs_fctx 
 static int
 smbfs_smb_findclose2(struct smbfs_fctx *ctx)
 {
-	struct smb_rq rq, *rqp = &rq;
+	struct smb_rq *rqp;
 	struct mbchain *mbp;
 	int error;
 
+	rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
 	error = smb_rq_init(rqp, SSTOCP(ctx->f_ssp), SMB_COM_FIND_CLOSE2, ctx->f_scred);
-	if (error)
+	if (error) {
+		free(rqp, M_SMBFSDATA);
 		return error;
+	}
 	smb_rq_getrequest(rqp, &mbp);
 	smb_rq_wstart(rqp);
 	mb_put_mem(mbp, (caddr_t)&ctx->f_Sid, 2, MB_MSYSTEM);
@@ -1154,6 +1218,7 @@ smbfs_smb_findclose2(struct smbfs_fctx *
 	smb_rq_bend(rqp);
 	error = smb_rq_simple(rqp);
 	smb_rq_done(rqp);
+	free(rqp, M_SMBFSDATA);
 	return error;
 }
 

Modified: head/sys/fs/smbfs/smbfs_subr.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_subr.c	Wed Oct 31 03:29:52 2012	(r242385)
+++ head/sys/fs/smbfs/smbfs_subr.c	Wed Oct 31 03:34:07 2012	(r242386)
@@ -46,6 +46,7 @@
 #include <fs/smbfs/smbfs_subr.h>
 
 MALLOC_DEFINE(M_SMBFSDATA, "smbfs_data", "SMBFS private data");
+MALLOC_DEFINE(M_SMBFSCRED, "smbfs_cred", "SMBFS cred data");
 
 void
 smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds)
@@ -222,3 +223,15 @@ smbfs_fname_tolocal(struct smb_vc *vcp, 
 	}
 	return error;
 }
+
+void *
+smbfs_malloc_scred(void)
+{
+	return (malloc(sizeof(struct smb_cred), M_SMBFSCRED, M_WAITOK));
+}
+
+void
+smbfs_free_scred(void *scred)
+{
+	free(scred, M_SMBFSCRED);
+}

Modified: head/sys/fs/smbfs/smbfs_subr.h
==============================================================================
--- head/sys/fs/smbfs/smbfs_subr.h	Wed Oct 31 03:29:52 2012	(r242385)
+++ head/sys/fs/smbfs/smbfs_subr.h	Wed Oct 31 03:34:07 2012	(r242386)
@@ -30,6 +30,7 @@
 
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_SMBFSDATA);
+MALLOC_DECLARE(M_SMBFSCRED);
 #endif
 
 #define SMBFSERR(format, args...) printf("%s: "format, __func__ ,## args)
@@ -178,4 +179,6 @@ void  smb_time_unix2dos(struct timespec 
 	     u_int16_t *dtp, u_int8_t *dhp);
 void smb_dos2unixtime (u_int dd, u_int dt, u_int dh, int tzoff, struct timespec *tsp);
 
+void *smbfs_malloc_scred(void);
+void smbfs_free_scred(void *);
 #endif /* !_FS_SMBFS_SMBFS_SUBR_H_ */

Modified: head/sys/fs/smbfs/smbfs_vfsops.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_vfsops.c	Wed Oct 31 03:29:52 2012	(r242385)
+++ head/sys/fs/smbfs/smbfs_vfsops.c	Wed Oct 31 03:34:07 2012	(r242386)
@@ -137,7 +137,7 @@ smbfs_mount(struct mount *mp)
 	struct smb_share *ssp = NULL;
 	struct vnode *vp;
 	struct thread *td;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	int error, v;
 	char *pc, *pe;
 
@@ -150,15 +150,18 @@ smbfs_mount(struct mount *mp)
 		return (EINVAL);
 	}
 
-	smb_makescred(&scred, td, td->td_ucred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, td->td_ucred);
 	if (1 != vfs_scanopt(mp->mnt_optnew, "dev", "%d", &v)) {
 		vfs_mount_error(mp, "No dev option");
+		smbfs_free_scred(scred);
 		return (EINVAL);
 	}
-	error = smb_dev2share(v, SMBM_EXEC, &scred, &ssp);
+	error = smb_dev2share(v, SMBM_EXEC, scred, &ssp);
 	if (error) {
 		printf("invalid device handle %d (%d)\n", v, error);
 		vfs_mount_error(mp, "invalid device handle %d (%d)\n", v, error);
+		smbfs_free_scred(scred);
 		return error;
 	}
 	vcp = SSTOVC(ssp);
@@ -237,6 +240,7 @@ smbfs_mount(struct mount *mp)
 #ifdef DIAGNOSTIC
 	SMBERROR("mp=%p\n", mp);
 #endif
+	smbfs_free_scred(scred);
 	return error;
 bad:
         if (smp) {
@@ -246,7 +250,8 @@ bad:
 		free(smp, M_SMBFSDATA);
 	}
 	if (ssp)
-		smb_share_put(ssp, &scred);
+		smb_share_put(ssp, scred);
+	smbfs_free_scred(scred);
         return error;
 }
 
@@ -256,7 +261,7 @@ smbfs_unmount(struct mount *mp, int mntf
 {
 	struct thread *td;
 	struct smbmount *smp = VFSTOSMBFS(mp);
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	int error, flags;
 
 	SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
@@ -279,11 +284,12 @@ smbfs_unmount(struct mount *mp, int mntf
 	} while (error == EBUSY && smp->sm_didrele != 0);
 	if (error)
 		return error;
-	smb_makescred(&scred, td, td->td_ucred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, td->td_ucred);
 	error = smb_share_lock(smp->sm_share, LK_EXCLUSIVE);
 	if (error)
-		return error;
-	smb_share_put(smp->sm_share, &scred);
+		goto out;
+	smb_share_put(smp->sm_share, scred);
 	mp->mnt_data = NULL;
 
 	if (smp->sm_hash)
@@ -293,6 +299,8 @@ smbfs_unmount(struct mount *mp, int mntf
 	MNT_ILOCK(mp);
 	mp->mnt_flag &= ~MNT_LOCAL;
 	MNT_IUNLOCK(mp);
+out:
+	smbfs_free_scred(scred);
 	return error;
 }
 
@@ -308,7 +316,7 @@ smbfs_root(struct mount *mp, int flags, 
 	struct smbfattr fattr;
 	struct thread *td;
 	struct ucred *cred;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	int error;
 
 	td = curthread;
@@ -323,19 +331,22 @@ smbfs_root(struct mount *mp, int flags, 
 		*vpp = SMBTOV(smp->sm_root);
 		return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td);
 	}
-	smb_makescred(&scred, td, cred);
-	error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, &scred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, cred);
+	error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, scred);
 	if (error)
-		return error;
+		goto out;
 	error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp);
 	if (error)
-		return error;
+		goto out;
 	ASSERT_VOP_LOCKED(vp, "smbfs_root");
 	vp->v_vflag |= VV_ROOT;
 	np = VTOSMB(vp);
 	smp->sm_root = np;
 	*vpp = vp;
-	return 0;
+out:
+	smbfs_free_scred(scred);
+	return error;
 }
 
 /*
@@ -381,7 +392,7 @@ smbfs_statfs(struct mount *mp, struct st
 	struct smbmount *smp = VFSTOSMBFS(mp);
 	struct smbnode *np = smp->sm_root;
 	struct smb_share *ssp = smp->sm_share;
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	int error = 0;
 
 	if (np == NULL) {
@@ -390,14 +401,18 @@ smbfs_statfs(struct mount *mp, struct st
 	}
 	
 	sbp->f_iosize = SSTOVC(ssp)->vc_txmax;		/* optimal transfer block size */
-	smb_makescred(&scred, td, td->td_ucred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, td, td->td_ucred);
 
 	if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0)
-		error = smbfs_smb_statfs2(ssp, sbp, &scred);
+		error = smbfs_smb_statfs2(ssp, sbp, scred);
 	else
-		error = smbfs_smb_statfs(ssp, sbp, &scred);
-	if (error)
+		error = smbfs_smb_statfs(ssp, sbp, scred);
+	if (error) {
+		smbfs_free_scred(scred);
 		return error;
+	}
 	sbp->f_flags = 0;		/* copy of mount exported flags */
+	smbfs_free_scred(scred);
 	return 0;
 }

Modified: head/sys/fs/smbfs/smbfs_vnops.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_vnops.c	Wed Oct 31 03:29:52 2012	(r242385)
+++ head/sys/fs/smbfs/smbfs_vnops.c	Wed Oct 31 03:34:07 2012	(r242386)
@@ -153,7 +153,7 @@ smbfs_open(ap)
 {
 	struct vnode *vp = ap->a_vp;
 	struct smbnode *np = VTOSMB(vp);
-	struct smb_cred scred;
+	struct smb_cred *scred;
 	struct vattr vattr;
 	int mode = ap->a_mode;
 	int error, accmode;
@@ -197,14 +197,15 @@ smbfs_open(ap)
 	accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
 	if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
 		accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW;
-	smb_makescred(&scred, ap->a_td, ap->a_cred);
-	error = smbfs_smb_open(np, accmode, &scred);
+	scred = smbfs_malloc_scred();
+	smb_makescred(scred, ap->a_td, ap->a_cred);
+	error = smbfs_smb_open(np, accmode, scred);
 	if (error) {
 		if (mode & FWRITE)
 			return EACCES;
 		else if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
 			accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
-			error = smbfs_smb_open(np, accmode, &scred);
+			error = smbfs_smb_open(np, accmode, scred);
 		}
 	}
 	if (error == 0) {
@@ -212,6 +213,7 @@ smbfs_open(ap)
 		vnode_create_vobject(ap->a_vp, vattr.va_size, ap->a_td);
 	}
 	smbfs_attr_cacheremove(vp);
+	smbfs_free_scred(scred);
 	return error;
 }
 
@@ -228,12 +230,14 @@ smbfs_close(ap)
 	struct vnode *vp = ap->a_vp;
 	struct thread *td = ap->a_td;
 	struct smbnode *np = VTOSMB(vp);
-	struct smb_cred scred;
+	struct smb_cred *scred;
 
 	if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 &&
 	    np->n_dirseq != NULL) {
-		smb_makescred(&scred, td, ap->a_cred);
-		smbfs_findclose(np->n_dirseq, &scred);
+		scred = smbfs_malloc_scred();
+		smb_makescred(scred, td, ap->a_cred);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210310334.q9V3Y7If039084>