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>