mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 04:43:53 +00:00
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.
This commit is contained in:
parent
994f027fbc
commit
afe097512c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=242386
|
@ -75,7 +75,7 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
|
||||||
{
|
{
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
struct componentname cn;
|
struct componentname cn;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
struct smbfs_fctx *ctx;
|
struct smbfs_fctx *ctx;
|
||||||
struct vnode *newvp;
|
struct vnode *newvp;
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
|
@ -84,11 +84,14 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
|
||||||
|
|
||||||
np = VTOSMB(vp);
|
np = VTOSMB(vp);
|
||||||
SMBVDEBUG("dirname='%s'\n", np->n_name);
|
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 */
|
offset = uio->uio_offset / DE_SIZE; /* offset in the directory */
|
||||||
limit = uio->uio_resid / DE_SIZE;
|
limit = uio->uio_resid / DE_SIZE;
|
||||||
if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0)
|
if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) {
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
while (limit && offset < 2) {
|
while (limit && offset < 2) {
|
||||||
limit--;
|
limit--;
|
||||||
bzero((caddr_t)&de, DE_SIZE);
|
bzero((caddr_t)&de, DE_SIZE);
|
||||||
|
@ -104,40 +107,43 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
|
||||||
de.d_type = DT_DIR;
|
de.d_type = DT_DIR;
|
||||||
error = uiomove(&de, DE_SIZE, uio);
|
error = uiomove(&de, DE_SIZE, uio);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
offset++;
|
offset++;
|
||||||
uio->uio_offset += DE_SIZE;
|
uio->uio_offset += DE_SIZE;
|
||||||
}
|
}
|
||||||
if (limit == 0)
|
if (limit == 0) {
|
||||||
return 0;
|
error = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (offset != np->n_dirofs || np->n_dirseq == NULL) {
|
if (offset != np->n_dirofs || np->n_dirseq == NULL) {
|
||||||
SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs);
|
SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs);
|
||||||
if (np->n_dirseq) {
|
if (np->n_dirseq) {
|
||||||
smbfs_findclose(np->n_dirseq, &scred);
|
smbfs_findclose(np->n_dirseq, scred);
|
||||||
np->n_dirseq = NULL;
|
np->n_dirseq = NULL;
|
||||||
}
|
}
|
||||||
np->n_dirofs = 2;
|
np->n_dirofs = 2;
|
||||||
error = smbfs_findopen(np, "*", 1,
|
error = smbfs_findopen(np, "*", 1,
|
||||||
SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR,
|
SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR,
|
||||||
&scred, &ctx);
|
scred, &ctx);
|
||||||
if (error) {
|
if (error) {
|
||||||
SMBVDEBUG("can not open search, error = %d", error);
|
SMBVDEBUG("can not open search, error = %d", error);
|
||||||
return error;
|
goto out;
|
||||||
}
|
}
|
||||||
np->n_dirseq = ctx;
|
np->n_dirseq = ctx;
|
||||||
} else
|
} else
|
||||||
ctx = np->n_dirseq;
|
ctx = np->n_dirseq;
|
||||||
while (np->n_dirofs < offset) {
|
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) {
|
if (error) {
|
||||||
smbfs_findclose(np->n_dirseq, &scred);
|
smbfs_findclose(np->n_dirseq, scred);
|
||||||
np->n_dirseq = NULL;
|
np->n_dirseq = NULL;
|
||||||
return error == ENOENT ? 0 : error;
|
error = ENOENT ? 0 : error;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
error = 0;
|
error = 0;
|
||||||
for (; limit; limit--, offset++) {
|
for (; limit; limit--, offset++) {
|
||||||
error = smbfs_findnext(ctx, limit, &scred);
|
error = smbfs_findnext(ctx, limit, scred);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
np->n_dirofs++;
|
np->n_dirofs++;
|
||||||
|
@ -165,6 +171,8 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
|
||||||
if (error == ENOENT)
|
if (error == ENOENT)
|
||||||
error = 0;
|
error = 0;
|
||||||
uio->uio_offset = offset * DE_SIZE;
|
uio->uio_offset = offset * DE_SIZE;
|
||||||
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +183,7 @@ smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred)
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
struct vattr vattr;
|
struct vattr vattr;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error, lks;
|
int error, lks;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -223,8 +231,11 @@ smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred)
|
||||||
np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
|
np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
smb_makescred(&scred, td, cred);
|
scred = smbfs_malloc_scred();
|
||||||
return smb_read(smp->sm_share, np->n_fid, uiop, &scred);
|
smb_makescred(scred, td, cred);
|
||||||
|
error = smb_read(smp->sm_share, np->n_fid, uiop, scred);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -233,7 +244,7 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop,
|
||||||
{
|
{
|
||||||
struct smbmount *smp = VTOSMBFS(vp);
|
struct smbmount *smp = VTOSMBFS(vp);
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
@ -272,9 +283,11 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop,
|
||||||
|
|
||||||
if (vn_rlimit_fsize(vp, uiop, td))
|
if (vn_rlimit_fsize(vp, uiop, td))
|
||||||
return (EFBIG);
|
return (EFBIG);
|
||||||
|
|
||||||
smb_makescred(&scred, td, cred);
|
scred = smbfs_malloc_scred();
|
||||||
error = smb_write(smp->sm_share, np->n_fid, uiop, &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,
|
SMBVDEBUG("after: ofs=%jd,resid=%zd\n", (intmax_t)uiop->uio_offset,
|
||||||
uiop->uio_resid);
|
uiop->uio_resid);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
|
@ -294,17 +307,19 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
|
||||||
{
|
{
|
||||||
struct smbmount *smp = VFSTOSMBFS(vp->v_mount);
|
struct smbmount *smp = VFSTOSMBFS(vp->v_mount);
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct uio uio, *uiop = &uio;
|
struct uio *uiop;
|
||||||
struct iovec io;
|
struct iovec io;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
uiop = malloc(sizeof(struct uio), M_SMBFSDATA, M_WAITOK);
|
||||||
uiop->uio_iov = &io;
|
uiop->uio_iov = &io;
|
||||||
uiop->uio_iovcnt = 1;
|
uiop->uio_iovcnt = 1;
|
||||||
uiop->uio_segflg = UIO_SYSSPACE;
|
uiop->uio_segflg = UIO_SYSSPACE;
|
||||||
uiop->uio_td = td;
|
uiop->uio_td = td;
|
||||||
|
|
||||||
smb_makescred(&scred, td, cr);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, td, cr);
|
||||||
|
|
||||||
if (bp->b_iocmd == BIO_READ) {
|
if (bp->b_iocmd == BIO_READ) {
|
||||||
io.iov_len = uiop->uio_resid = bp->b_bcount;
|
io.iov_len = uiop->uio_resid = bp->b_bcount;
|
||||||
|
@ -313,7 +328,7 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
|
||||||
switch (vp->v_type) {
|
switch (vp->v_type) {
|
||||||
case VREG:
|
case VREG:
|
||||||
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
|
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)
|
if (error)
|
||||||
break;
|
break;
|
||||||
if (uiop->uio_resid) {
|
if (uiop->uio_resid) {
|
||||||
|
@ -340,7 +355,7 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
|
||||||
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
|
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
|
||||||
io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
|
io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
|
||||||
uiop->uio_rw = UIO_WRITE;
|
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
|
* For an interrupted write, the buffer is still valid
|
||||||
|
@ -380,11 +395,15 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
|
||||||
} else {
|
} else {
|
||||||
bp->b_resid = 0;
|
bp->b_resid = 0;
|
||||||
bufdone(bp);
|
bufdone(bp);
|
||||||
|
free(uiop, M_SMBFSDATA);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bp->b_resid = uiop->uio_resid;
|
bp->b_resid = uiop->uio_resid;
|
||||||
bufdone(bp);
|
bufdone(bp);
|
||||||
|
free(uiop, M_SMBFSDATA);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +434,7 @@ smbfs_getpages(ap)
|
||||||
struct ucred *cred;
|
struct ucred *cred;
|
||||||
struct smbmount *smp;
|
struct smbmount *smp;
|
||||||
struct smbnode *np;
|
struct smbnode *np;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
vm_object_t object;
|
vm_object_t object;
|
||||||
vm_page_t *pages, m;
|
vm_page_t *pages, m;
|
||||||
|
|
||||||
|
@ -455,7 +474,8 @@ smbfs_getpages(ap)
|
||||||
}
|
}
|
||||||
VM_OBJECT_UNLOCK(object);
|
VM_OBJECT_UNLOCK(object);
|
||||||
|
|
||||||
smb_makescred(&scred, td, cred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, td, cred);
|
||||||
|
|
||||||
bp = getpbuf(&smbfs_pbuf_freecnt);
|
bp = getpbuf(&smbfs_pbuf_freecnt);
|
||||||
|
|
||||||
|
@ -474,7 +494,8 @@ smbfs_getpages(ap)
|
||||||
uio.uio_rw = UIO_READ;
|
uio.uio_rw = UIO_READ;
|
||||||
uio.uio_td = td;
|
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);
|
pmap_qremove(kva, npages);
|
||||||
|
|
||||||
relpbuf(bp, &smbfs_pbuf_freecnt);
|
relpbuf(bp, &smbfs_pbuf_freecnt);
|
||||||
|
@ -570,7 +591,7 @@ smbfs_putpages(ap)
|
||||||
int *rtvals;
|
int *rtvals;
|
||||||
struct smbmount *smp;
|
struct smbmount *smp;
|
||||||
struct smbnode *np;
|
struct smbnode *np;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
vm_page_t *pages;
|
vm_page_t *pages;
|
||||||
|
|
||||||
td = curthread; /* XXX */
|
td = curthread; /* XXX */
|
||||||
|
@ -606,8 +627,10 @@ smbfs_putpages(ap)
|
||||||
SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uio.uio_offset,
|
SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uio.uio_offset,
|
||||||
uio.uio_resid);
|
uio.uio_resid);
|
||||||
|
|
||||||
smb_makescred(&scred, td, cred);
|
scred = smbfs_malloc_scred();
|
||||||
error = smb_write(smp->sm_share, np->n_fid, &uio, &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);*/
|
/* VOP_CLOSE(vp, FWRITE, cred, td);*/
|
||||||
SMBVDEBUG("paged write done: %d\n", error);
|
SMBVDEBUG("paged write done: %d\n", error);
|
||||||
|
|
||||||
|
|
|
@ -349,25 +349,27 @@ smbfs_inactive(ap)
|
||||||
struct ucred *cred = td->td_ucred;
|
struct ucred *cred = td->td_ucred;
|
||||||
struct vnode *vp = ap->a_vp;
|
struct vnode *vp = ap->a_vp;
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
struct vattr va;
|
struct vattr va;
|
||||||
|
|
||||||
SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vrefcnt(vp));
|
SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vrefcnt(vp));
|
||||||
if ((np->n_flag & NOPEN) != 0) {
|
if ((np->n_flag & NOPEN) != 0) {
|
||||||
smb_makescred(&scred, td, cred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, td, cred);
|
||||||
smbfs_vinvalbuf(vp, td);
|
smbfs_vinvalbuf(vp, td);
|
||||||
if (vp->v_type == VREG) {
|
if (vp->v_type == VREG) {
|
||||||
VOP_GETATTR(vp, &va, cred);
|
VOP_GETATTR(vp, &va, cred);
|
||||||
smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
|
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) {
|
} else if (vp->v_type == VDIR) {
|
||||||
if (np->n_dirseq != NULL) {
|
if (np->n_dirseq != NULL) {
|
||||||
smbfs_findclose(np->n_dirseq, &scred);
|
smbfs_findclose(np->n_dirseq, scred);
|
||||||
np->n_dirseq = NULL;
|
np->n_dirseq = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
np->n_flag &= ~NOPEN;
|
np->n_flag &= ~NOPEN;
|
||||||
smbfs_attr_cacheremove(vp);
|
smbfs_attr_cacheremove(vp);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
}
|
}
|
||||||
if (np->n_flag & NGONE)
|
if (np->n_flag & NGONE)
|
||||||
vrecycle(vp);
|
vrecycle(vp);
|
||||||
|
|
|
@ -87,16 +87,19 @@ smbfs_smb_lockandx(struct smbnode *np, int op, u_int32_t pid, off_t start, off_t
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_share *ssp = np->n_mount->sm_share;
|
struct smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
u_char ltype = 0;
|
u_char ltype = 0;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (op == SMB_LOCK_SHARED)
|
if (op == SMB_LOCK_SHARED)
|
||||||
ltype |= SMB_LOCKING_ANDX_SHARED_LOCK;
|
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);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_LOCKING_ANDX, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_uint8(mbp, 0xff); /* secondary command */
|
mb_put_uint8(mbp, 0xff); /* secondary command */
|
||||||
|
@ -116,6 +119,7 @@ smbfs_smb_lockandx(struct smbnode *np, int op, u_int32_t pid, off_t start, off_t
|
||||||
smb_rq_bend(rqp);
|
smb_rq_bend(rqp);
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,20 +183,24 @@ int
|
||||||
smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
|
smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct mdchain *mdp;
|
struct mdchain *mdp;
|
||||||
u_int16_t units, bpu, bsize, funits;
|
u_int16_t units, bpu, bsize, funits;
|
||||||
int error;
|
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);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION_DISK, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
smb_rq_wend(rqp);
|
smb_rq_wend(rqp);
|
||||||
smb_rq_bstart(rqp);
|
smb_rq_bstart(rqp);
|
||||||
smb_rq_bend(rqp);
|
smb_rq_bend(rqp);
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -208,6 +216,7 @@ smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
|
||||||
sbp->f_files = 0xffff; /* total file nodes in filesystem */
|
sbp->f_files = 0xffff; /* total file nodes in filesystem */
|
||||||
sbp->f_ffree = 0xffff; /* free file nodes in fs */
|
sbp->f_ffree = 0xffff; /* free file nodes in fs */
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,16 +253,19 @@ static int
|
||||||
smb_smb_flush(struct smbnode *np, struct smb_cred *scred)
|
smb_smb_flush(struct smbnode *np, struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_share *ssp = np->n_mount->sm_share;
|
struct smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((np->n_flag & NOPEN) == 0 || !SMBTOV(np) ||
|
if ((np->n_flag & NOPEN) == 0 || !SMBTOV(np) ||
|
||||||
SMBTOV(np)->v_type != VREG)
|
SMBTOV(np)->v_type != VREG)
|
||||||
return 0; /* not a regular open file */
|
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);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_FLUSH, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return (error);
|
return (error);
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
|
mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
|
||||||
|
@ -262,6 +274,7 @@ smb_smb_flush(struct smbnode *np, struct smb_cred *scred)
|
||||||
smb_rq_bend(rqp);
|
smb_rq_bend(rqp);
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
if (!error)
|
if (!error)
|
||||||
np->n_flag &= ~NFLUSHWIRE;
|
np->n_flag &= ~NFLUSHWIRE;
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -279,7 +292,7 @@ int
|
||||||
smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
|
smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_share *ssp = np->n_mount->sm_share;
|
struct smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -288,9 +301,12 @@ smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_WRITE, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_WRITE, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
|
mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
|
||||||
|
@ -304,6 +320,7 @@ smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
|
||||||
smb_rq_bend(rqp);
|
smb_rq_bend(rqp);
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +328,7 @@ int
|
||||||
smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
|
smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
|
||||||
struct smbfattr *fap, struct smb_cred *scred)
|
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 smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
struct mdchain *mdp;
|
struct mdchain *mdp;
|
||||||
|
@ -320,9 +337,12 @@ smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
|
||||||
u_int16_t wattr;
|
u_int16_t wattr;
|
||||||
u_int32_t lint;
|
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);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
smb_rq_wend(rqp);
|
smb_rq_wend(rqp);
|
||||||
|
@ -357,6 +377,7 @@ smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
|
||||||
fap->fa_size = lint;
|
fap->fa_size = lint;
|
||||||
} while(0);
|
} while(0);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,15 +388,18 @@ int
|
||||||
smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
|
smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct smb_share *ssp = np->n_mount->sm_share;
|
struct smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
u_long time;
|
u_long time;
|
||||||
int error, svtz;
|
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);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
svtz = SSTOVC(ssp)->vc_sopt.sv_tz;
|
svtz = SSTOVC(ssp)->vc_sopt.sv_tz;
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
|
@ -407,6 +431,7 @@ smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
|
||||||
}
|
}
|
||||||
} while(0);
|
} while(0);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,15 +548,18 @@ int
|
||||||
smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime,
|
smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime,
|
||||||
struct timespec *atime, struct smb_cred *scred)
|
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 smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
u_int16_t date, time;
|
u_int16_t date, time;
|
||||||
int error, tzoff;
|
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);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION2, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
tzoff = SSTOVC(ssp)->vc_sopt.sv_tz;
|
tzoff = SSTOVC(ssp)->vc_sopt.sv_tz;
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
|
@ -556,6 +584,7 @@ smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime,
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
SMBSDEBUG("%d\n", error);
|
SMBSDEBUG("%d\n", error);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +640,7 @@ smbfs_smb_setfattrNT(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
|
||||||
int
|
int
|
||||||
smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred)
|
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 smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
struct mdchain *mdp;
|
struct mdchain *mdp;
|
||||||
|
@ -619,9 +648,12 @@ smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred)
|
||||||
u_int16_t fid, wattr, grantedmode;
|
u_int16_t fid, wattr, grantedmode;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_uint16le(mbp, accmode);
|
mb_put_uint16le(mbp, accmode);
|
||||||
|
@ -652,6 +684,7 @@ smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred)
|
||||||
*/
|
*/
|
||||||
} while(0);
|
} while(0);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
np->n_fid = fid;
|
np->n_fid = fid;
|
||||||
|
@ -664,14 +697,17 @@ int
|
||||||
smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime,
|
smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime,
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
u_long time;
|
u_long time;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_mem(mbp, (caddr_t)&fid, sizeof(fid), MB_MSYSTEM);
|
mb_put_mem(mbp, (caddr_t)&fid, sizeof(fid), MB_MSYSTEM);
|
||||||
|
@ -685,6 +721,7 @@ smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime,
|
||||||
smb_rq_bend(rqp);
|
smb_rq_bend(rqp);
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +729,7 @@ int
|
||||||
smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
|
smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct smb_share *ssp = dnp->n_mount->sm_share;
|
struct smb_share *ssp = dnp->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
struct mdchain *mdp;
|
struct mdchain *mdp;
|
||||||
|
@ -702,9 +739,12 @@ smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
|
||||||
u_long tm;
|
u_long tm;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_uint16le(mbp, SMB_FA_ARCHIVE); /* attributes */
|
mb_put_uint16le(mbp, SMB_FA_ARCHIVE); /* attributes */
|
||||||
|
@ -731,20 +771,24 @@ smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
smbfs_smb_close(ssp, fid, &ctime, scred);
|
smbfs_smb_close(ssp, fid, &ctime, scred);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred)
|
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 smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
|
mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
|
||||||
|
@ -757,6 +801,7 @@ smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred)
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
}
|
}
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,14 +809,17 @@ int
|
||||||
smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp,
|
smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp,
|
||||||
const char *tname, int tnmlen, struct smb_cred *scred)
|
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 smb_share *ssp = src->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_RENAME, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_RENAME, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
|
mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
|
||||||
|
@ -790,6 +838,7 @@ smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp,
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
} while(0);
|
} while(0);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,14 +846,17 @@ int
|
||||||
smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp,
|
smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp,
|
||||||
const char *tname, int tnmlen, u_int16_t flags, struct smb_cred *scred)
|
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 smb_share *ssp = src->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_MOVE, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_MOVE, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_uint16le(mbp, SMB_TID_UNKNOWN);
|
mb_put_uint16le(mbp, SMB_TID_UNKNOWN);
|
||||||
|
@ -825,6 +877,7 @@ smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp,
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
} while(0);
|
} while(0);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,14 +885,17 @@ int
|
||||||
smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len,
|
smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len,
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct smb_share *ssp = dnp->n_mount->sm_share;
|
struct smb_share *ssp = dnp->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE_DIRECTORY, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE_DIRECTORY, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
smb_rq_wend(rqp);
|
smb_rq_wend(rqp);
|
||||||
|
@ -851,20 +907,24 @@ smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len,
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
}
|
}
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred)
|
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 smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE_DIRECTORY, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE_DIRECTORY, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
smb_rq_wend(rqp);
|
smb_rq_wend(rqp);
|
||||||
|
@ -876,6 +936,7 @@ smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred)
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
}
|
}
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1139,13 +1200,16 @@ smbfs_smb_trans2find2(struct smbfs_fctx *ctx)
|
||||||
static int
|
static int
|
||||||
smbfs_smb_findclose2(struct smbfs_fctx *ctx)
|
smbfs_smb_findclose2(struct smbfs_fctx *ctx)
|
||||||
{
|
{
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
int error;
|
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);
|
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;
|
return error;
|
||||||
|
}
|
||||||
smb_rq_getrequest(rqp, &mbp);
|
smb_rq_getrequest(rqp, &mbp);
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
mb_put_mem(mbp, (caddr_t)&ctx->f_Sid, 2, MB_MSYSTEM);
|
mb_put_mem(mbp, (caddr_t)&ctx->f_Sid, 2, MB_MSYSTEM);
|
||||||
|
@ -1154,6 +1218,7 @@ smbfs_smb_findclose2(struct smbfs_fctx *ctx)
|
||||||
smb_rq_bend(rqp);
|
smb_rq_bend(rqp);
|
||||||
error = smb_rq_simple(rqp);
|
error = smb_rq_simple(rqp);
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBFSDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include <fs/smbfs/smbfs_subr.h>
|
#include <fs/smbfs/smbfs_subr.h>
|
||||||
|
|
||||||
MALLOC_DEFINE(M_SMBFSDATA, "smbfs_data", "SMBFS private data");
|
MALLOC_DEFINE(M_SMBFSDATA, "smbfs_data", "SMBFS private data");
|
||||||
|
MALLOC_DEFINE(M_SMBFSCRED, "smbfs_cred", "SMBFS cred data");
|
||||||
|
|
||||||
void
|
void
|
||||||
smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds)
|
smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds)
|
||||||
|
@ -222,3 +223,15 @@ smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int *nmlen, int caseopt)
|
||||||
}
|
}
|
||||||
return error;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#ifdef MALLOC_DECLARE
|
#ifdef MALLOC_DECLARE
|
||||||
MALLOC_DECLARE(M_SMBFSDATA);
|
MALLOC_DECLARE(M_SMBFSDATA);
|
||||||
|
MALLOC_DECLARE(M_SMBFSCRED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SMBFSERR(format, args...) printf("%s: "format, __func__ ,## args)
|
#define SMBFSERR(format, args...) printf("%s: "format, __func__ ,## args)
|
||||||
|
@ -178,4 +179,6 @@ void smb_time_unix2dos(struct timespec *tsp, int tzoff, u_int16_t *ddp,
|
||||||
u_int16_t *dtp, u_int8_t *dhp);
|
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 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_ */
|
#endif /* !_FS_SMBFS_SMBFS_SUBR_H_ */
|
||||||
|
|
|
@ -137,7 +137,7 @@ smbfs_mount(struct mount *mp)
|
||||||
struct smb_share *ssp = NULL;
|
struct smb_share *ssp = NULL;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error, v;
|
int error, v;
|
||||||
char *pc, *pe;
|
char *pc, *pe;
|
||||||
|
|
||||||
|
@ -150,15 +150,18 @@ smbfs_mount(struct mount *mp)
|
||||||
return (EINVAL);
|
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)) {
|
if (1 != vfs_scanopt(mp->mnt_optnew, "dev", "%d", &v)) {
|
||||||
vfs_mount_error(mp, "No dev option");
|
vfs_mount_error(mp, "No dev option");
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
error = smb_dev2share(v, SMBM_EXEC, &scred, &ssp);
|
error = smb_dev2share(v, SMBM_EXEC, scred, &ssp);
|
||||||
if (error) {
|
if (error) {
|
||||||
printf("invalid device handle %d (%d)\n", v, error);
|
printf("invalid device handle %d (%d)\n", v, error);
|
||||||
vfs_mount_error(mp, "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;
|
return error;
|
||||||
}
|
}
|
||||||
vcp = SSTOVC(ssp);
|
vcp = SSTOVC(ssp);
|
||||||
|
@ -237,6 +240,7 @@ smbfs_mount(struct mount *mp)
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
SMBERROR("mp=%p\n", mp);
|
SMBERROR("mp=%p\n", mp);
|
||||||
#endif
|
#endif
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
bad:
|
bad:
|
||||||
if (smp) {
|
if (smp) {
|
||||||
|
@ -246,7 +250,8 @@ smbfs_mount(struct mount *mp)
|
||||||
free(smp, M_SMBFSDATA);
|
free(smp, M_SMBFSDATA);
|
||||||
}
|
}
|
||||||
if (ssp)
|
if (ssp)
|
||||||
smb_share_put(ssp, &scred);
|
smb_share_put(ssp, scred);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +261,7 @@ smbfs_unmount(struct mount *mp, int mntflags)
|
||||||
{
|
{
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
struct smbmount *smp = VFSTOSMBFS(mp);
|
struct smbmount *smp = VFSTOSMBFS(mp);
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error, flags;
|
int error, flags;
|
||||||
|
|
||||||
SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
|
SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
|
||||||
|
@ -279,11 +284,12 @@ smbfs_unmount(struct mount *mp, int mntflags)
|
||||||
} while (error == EBUSY && smp->sm_didrele != 0);
|
} while (error == EBUSY && smp->sm_didrele != 0);
|
||||||
if (error)
|
if (error)
|
||||||
return 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);
|
error = smb_share_lock(smp->sm_share, LK_EXCLUSIVE);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
smb_share_put(smp->sm_share, &scred);
|
smb_share_put(smp->sm_share, scred);
|
||||||
mp->mnt_data = NULL;
|
mp->mnt_data = NULL;
|
||||||
|
|
||||||
if (smp->sm_hash)
|
if (smp->sm_hash)
|
||||||
|
@ -293,6 +299,8 @@ smbfs_unmount(struct mount *mp, int mntflags)
|
||||||
MNT_ILOCK(mp);
|
MNT_ILOCK(mp);
|
||||||
mp->mnt_flag &= ~MNT_LOCAL;
|
mp->mnt_flag &= ~MNT_LOCAL;
|
||||||
MNT_IUNLOCK(mp);
|
MNT_IUNLOCK(mp);
|
||||||
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +316,7 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp)
|
||||||
struct smbfattr fattr;
|
struct smbfattr fattr;
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
struct ucred *cred;
|
struct ucred *cred;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
td = curthread;
|
td = curthread;
|
||||||
|
@ -323,19 +331,22 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp)
|
||||||
*vpp = SMBTOV(smp->sm_root);
|
*vpp = SMBTOV(smp->sm_root);
|
||||||
return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td);
|
return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||||
}
|
}
|
||||||
smb_makescred(&scred, td, cred);
|
scred = smbfs_malloc_scred();
|
||||||
error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, &scred);
|
smb_makescred(scred, td, cred);
|
||||||
|
error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, scred);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp);
|
error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
ASSERT_VOP_LOCKED(vp, "smbfs_root");
|
ASSERT_VOP_LOCKED(vp, "smbfs_root");
|
||||||
vp->v_vflag |= VV_ROOT;
|
vp->v_vflag |= VV_ROOT;
|
||||||
np = VTOSMB(vp);
|
np = VTOSMB(vp);
|
||||||
smp->sm_root = np;
|
smp->sm_root = np;
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
return 0;
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -381,7 +392,7 @@ smbfs_statfs(struct mount *mp, struct statfs *sbp)
|
||||||
struct smbmount *smp = VFSTOSMBFS(mp);
|
struct smbmount *smp = VFSTOSMBFS(mp);
|
||||||
struct smbnode *np = smp->sm_root;
|
struct smbnode *np = smp->sm_root;
|
||||||
struct smb_share *ssp = smp->sm_share;
|
struct smb_share *ssp = smp->sm_share;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if (np == NULL) {
|
if (np == NULL) {
|
||||||
|
@ -390,14 +401,18 @@ smbfs_statfs(struct mount *mp, struct statfs *sbp)
|
||||||
}
|
}
|
||||||
|
|
||||||
sbp->f_iosize = SSTOVC(ssp)->vc_txmax; /* optimal transfer block size */
|
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)
|
if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0)
|
||||||
error = smbfs_smb_statfs2(ssp, sbp, &scred);
|
error = smbfs_smb_statfs2(ssp, sbp, scred);
|
||||||
else
|
else
|
||||||
error = smbfs_smb_statfs(ssp, sbp, &scred);
|
error = smbfs_smb_statfs(ssp, sbp, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
sbp->f_flags = 0; /* copy of mount exported flags */
|
sbp->f_flags = 0; /* copy of mount exported flags */
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ smbfs_open(ap)
|
||||||
{
|
{
|
||||||
struct vnode *vp = ap->a_vp;
|
struct vnode *vp = ap->a_vp;
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
struct vattr vattr;
|
struct vattr vattr;
|
||||||
int mode = ap->a_mode;
|
int mode = ap->a_mode;
|
||||||
int error, accmode;
|
int error, accmode;
|
||||||
|
@ -197,14 +197,15 @@ smbfs_open(ap)
|
||||||
accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
|
accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
|
||||||
if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
|
if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
|
||||||
accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW;
|
accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW;
|
||||||
smb_makescred(&scred, ap->a_td, ap->a_cred);
|
scred = smbfs_malloc_scred();
|
||||||
error = smbfs_smb_open(np, accmode, &scred);
|
smb_makescred(scred, ap->a_td, ap->a_cred);
|
||||||
|
error = smbfs_smb_open(np, accmode, scred);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (mode & FWRITE)
|
if (mode & FWRITE)
|
||||||
return EACCES;
|
return EACCES;
|
||||||
else if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
|
else if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
|
||||||
accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
|
accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
|
||||||
error = smbfs_smb_open(np, accmode, &scred);
|
error = smbfs_smb_open(np, accmode, scred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
|
@ -212,6 +213,7 @@ smbfs_open(ap)
|
||||||
vnode_create_vobject(ap->a_vp, vattr.va_size, ap->a_td);
|
vnode_create_vobject(ap->a_vp, vattr.va_size, ap->a_td);
|
||||||
}
|
}
|
||||||
smbfs_attr_cacheremove(vp);
|
smbfs_attr_cacheremove(vp);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,12 +230,14 @@ smbfs_close(ap)
|
||||||
struct vnode *vp = ap->a_vp;
|
struct vnode *vp = ap->a_vp;
|
||||||
struct thread *td = ap->a_td;
|
struct thread *td = ap->a_td;
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
|
|
||||||
if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 &&
|
if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 &&
|
||||||
np->n_dirseq != NULL) {
|
np->n_dirseq != NULL) {
|
||||||
smb_makescred(&scred, td, ap->a_cred);
|
scred = smbfs_malloc_scred();
|
||||||
smbfs_findclose(np->n_dirseq, &scred);
|
smb_makescred(scred, td, ap->a_cred);
|
||||||
|
smbfs_findclose(np->n_dirseq, scred);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
np->n_dirseq = NULL;
|
np->n_dirseq = NULL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -254,7 +258,7 @@ smbfs_getattr(ap)
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct vattr *va=ap->a_vap;
|
struct vattr *va=ap->a_vap;
|
||||||
struct smbfattr fattr;
|
struct smbfattr fattr;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
u_quad_t oldsize;
|
u_quad_t oldsize;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -263,17 +267,20 @@ smbfs_getattr(ap)
|
||||||
if (!error)
|
if (!error)
|
||||||
return 0;
|
return 0;
|
||||||
SMBVDEBUG("not in the cache\n");
|
SMBVDEBUG("not in the cache\n");
|
||||||
smb_makescred(&scred, curthread, ap->a_cred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, curthread, ap->a_cred);
|
||||||
oldsize = np->n_size;
|
oldsize = np->n_size;
|
||||||
error = smbfs_smb_lookup(np, NULL, 0, &fattr, &scred);
|
error = smbfs_smb_lookup(np, NULL, 0, &fattr, scred);
|
||||||
if (error) {
|
if (error) {
|
||||||
SMBVDEBUG("error %d\n", error);
|
SMBVDEBUG("error %d\n", error);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
smbfs_attr_cacheenter(vp, &fattr);
|
smbfs_attr_cacheenter(vp, &fattr);
|
||||||
smbfs_attr_cachelookup(vp, va);
|
smbfs_attr_cachelookup(vp, va);
|
||||||
if (np->n_flag & NOPEN)
|
if (np->n_flag & NOPEN)
|
||||||
np->n_size = oldsize;
|
np->n_size = oldsize;
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +296,7 @@ smbfs_setattr(ap)
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct vattr *vap = ap->a_vap;
|
struct vattr *vap = ap->a_vap;
|
||||||
struct timespec *mtime, *atime;
|
struct timespec *mtime, *atime;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
struct smb_share *ssp = np->n_mount->sm_share;
|
struct smb_share *ssp = np->n_mount->sm_share;
|
||||||
struct smb_vc *vcp = SSTOVC(ssp);
|
struct smb_vc *vcp = SSTOVC(ssp);
|
||||||
struct thread *td = curthread;
|
struct thread *td = curthread;
|
||||||
|
@ -308,18 +315,23 @@ smbfs_setattr(ap)
|
||||||
vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
|
vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
|
||||||
vap->va_mode != (mode_t)VNOVAL) && isreadonly)
|
vap->va_mode != (mode_t)VNOVAL) && isreadonly)
|
||||||
return EROFS;
|
return EROFS;
|
||||||
smb_makescred(&scred, td, ap->a_cred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, td, ap->a_cred);
|
||||||
if (vap->va_size != VNOVAL) {
|
if (vap->va_size != VNOVAL) {
|
||||||
switch (vp->v_type) {
|
switch (vp->v_type) {
|
||||||
case VDIR:
|
case VDIR:
|
||||||
return EISDIR;
|
error = EISDIR;
|
||||||
|
goto out;
|
||||||
case VREG:
|
case VREG:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
error = EINVAL;
|
||||||
|
goto out;
|
||||||
};
|
};
|
||||||
if (isreadonly)
|
if (isreadonly) {
|
||||||
return EROFS;
|
error = EROFS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
doclose = 0;
|
doclose = 0;
|
||||||
vnode_pager_setsize(vp, (u_long)vap->va_size);
|
vnode_pager_setsize(vp, (u_long)vap->va_size);
|
||||||
tsize = np->n_size;
|
tsize = np->n_size;
|
||||||
|
@ -327,18 +339,18 @@ smbfs_setattr(ap)
|
||||||
if ((np->n_flag & NOPEN) == 0) {
|
if ((np->n_flag & NOPEN) == 0) {
|
||||||
error = smbfs_smb_open(np,
|
error = smbfs_smb_open(np,
|
||||||
SMB_SM_DENYNONE|SMB_AM_OPENRW,
|
SMB_SM_DENYNONE|SMB_AM_OPENRW,
|
||||||
&scred);
|
scred);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
doclose = 1;
|
doclose = 1;
|
||||||
}
|
}
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
error = smbfs_smb_setfsize(np, vap->va_size, &scred);
|
error = smbfs_smb_setfsize(np, vap->va_size, scred);
|
||||||
if (doclose)
|
if (doclose)
|
||||||
smbfs_smb_close(ssp, np->n_fid, NULL, &scred);
|
smbfs_smb_close(ssp, np->n_fid, NULL, scred);
|
||||||
if (error) {
|
if (error) {
|
||||||
np->n_size = tsize;
|
np->n_size = tsize;
|
||||||
vnode_pager_setsize(vp, (u_long)tsize);
|
vnode_pager_setsize(vp, (u_long)tsize);
|
||||||
return error;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vap->va_mode != (mode_t)VNOVAL) {
|
if (vap->va_mode != (mode_t)VNOVAL) {
|
||||||
|
@ -348,9 +360,9 @@ smbfs_setattr(ap)
|
||||||
else
|
else
|
||||||
np->n_dosattr |= SMB_FA_RDONLY;
|
np->n_dosattr |= SMB_FA_RDONLY;
|
||||||
if (np->n_dosattr != old_n_dosattr) {
|
if (np->n_dosattr != old_n_dosattr) {
|
||||||
error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, &scred);
|
error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, scred);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mtime = atime = NULL;
|
mtime = atime = NULL;
|
||||||
|
@ -381,25 +393,25 @@ smbfs_setattr(ap)
|
||||||
NULL);
|
NULL);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
/* error = smbfs_smb_setfattrNT(np, 0,
|
/* error = smbfs_smb_setfattrNT(np, 0,
|
||||||
mtime, atime, &scred);
|
mtime, atime, scred);
|
||||||
VOP_GETATTR(vp, &vattr, ap->a_cred); */
|
VOP_GETATTR(vp, &vattr, ap->a_cred); */
|
||||||
if (mtime)
|
if (mtime)
|
||||||
np->n_mtime = *mtime;
|
np->n_mtime = *mtime;
|
||||||
VOP_CLOSE(vp, FWRITE, ap->a_cred, td);
|
VOP_CLOSE(vp, FWRITE, ap->a_cred, td);
|
||||||
}
|
}
|
||||||
} else if ((vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS)) {
|
} else if ((vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS)) {
|
||||||
error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred);
|
error = smbfs_smb_setptime2(np, mtime, atime, 0, scred);
|
||||||
/* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, &scred);*/
|
/* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, scred);*/
|
||||||
} else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) {
|
} else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) {
|
||||||
error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred);
|
error = smbfs_smb_setptime2(np, mtime, atime, 0, scred);
|
||||||
} else {
|
} else {
|
||||||
error = smbfs_smb_setpattr(np, 0, mtime, &scred);
|
error = smbfs_smb_setpattr(np, 0, mtime, scred);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS) {
|
if (vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS) {
|
||||||
error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred);
|
error = smbfs_smb_setfattrNT(np, 0, mtime, atime, scred);
|
||||||
} else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) {
|
} else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) {
|
||||||
error = smbfs_smb_setftime(np, mtime, atime, &scred);
|
error = smbfs_smb_setftime(np, mtime, atime, scred);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* I have no idea how to handle this for core
|
* I have no idea how to handle this for core
|
||||||
|
@ -417,6 +429,8 @@ smbfs_setattr(ap)
|
||||||
smbfs_attr_cacheremove(vp); /* invalidate cache */
|
smbfs_attr_cacheremove(vp); /* invalidate cache */
|
||||||
VOP_GETATTR(vp, vap, ap->a_cred);
|
VOP_GETATTR(vp, vap, ap->a_cred);
|
||||||
np->n_mtime.tv_sec = vap->va_mtime.tv_sec;
|
np->n_mtime.tv_sec = vap->va_mtime.tv_sec;
|
||||||
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -482,7 +496,7 @@ smbfs_create(ap)
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct vattr vattr;
|
struct vattr vattr;
|
||||||
struct smbfattr fattr;
|
struct smbfattr fattr;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
char *name = cnp->cn_nameptr;
|
char *name = cnp->cn_nameptr;
|
||||||
int nmlen = cnp->cn_namelen;
|
int nmlen = cnp->cn_namelen;
|
||||||
int error;
|
int error;
|
||||||
|
@ -494,20 +508,23 @@ smbfs_create(ap)
|
||||||
return EOPNOTSUPP;
|
return EOPNOTSUPP;
|
||||||
if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)))
|
if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)))
|
||||||
return error;
|
return error;
|
||||||
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
|
||||||
|
|
||||||
error = smbfs_smb_create(dnp, name, nmlen, &scred);
|
error = smbfs_smb_create(dnp, name, nmlen, scred);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred);
|
error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, scred);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, &vp);
|
error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, &vp);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
if (cnp->cn_flags & MAKEENTRY)
|
if (cnp->cn_flags & MAKEENTRY)
|
||||||
cache_enter(dvp, vp, cnp);
|
cache_enter(dvp, vp, cnp);
|
||||||
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,16 +541,18 @@ smbfs_remove(ap)
|
||||||
/* struct vnode *dvp = ap->a_dvp;*/
|
/* struct vnode *dvp = ap->a_dvp;*/
|
||||||
struct componentname *cnp = ap->a_cnp;
|
struct componentname *cnp = ap->a_cnp;
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 || vrefcnt(vp) != 1)
|
if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 || vrefcnt(vp) != 1)
|
||||||
return EPERM;
|
return EPERM;
|
||||||
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred);
|
scred = smbfs_malloc_scred();
|
||||||
error = smbfs_smb_delete(np, &scred);
|
smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
|
||||||
|
error = smbfs_smb_delete(np, scred);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
np->n_flag |= NGONE;
|
np->n_flag |= NGONE;
|
||||||
cache_purge(vp);
|
cache_purge(vp);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,19 +576,19 @@ smbfs_rename(ap)
|
||||||
struct vnode *tdvp = ap->a_tdvp;
|
struct vnode *tdvp = ap->a_tdvp;
|
||||||
struct componentname *tcnp = ap->a_tcnp;
|
struct componentname *tcnp = ap->a_tcnp;
|
||||||
/* struct componentname *fcnp = ap->a_fcnp;*/
|
/* struct componentname *fcnp = ap->a_fcnp;*/
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
u_int16_t flags = 6;
|
u_int16_t flags = 6;
|
||||||
int error=0;
|
int error=0;
|
||||||
|
|
||||||
/* Check for cross-device rename */
|
/* Check for cross-device rename */
|
||||||
if ((fvp->v_mount != tdvp->v_mount) ||
|
if ((fvp->v_mount != tdvp->v_mount) ||
|
||||||
(tvp && (fvp->v_mount != tvp->v_mount))) {
|
(tvp && (fvp->v_mount != tvp->v_mount))) {
|
||||||
error = EXDEV;
|
return EXDEV;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tvp && vrefcnt(tvp) > 1) {
|
if (tvp && vrefcnt(tvp) > 1) {
|
||||||
error = EBUSY;
|
return EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
flags = 0x10; /* verify all writes */
|
flags = 0x10; /* verify all writes */
|
||||||
|
@ -578,17 +597,17 @@ smbfs_rename(ap)
|
||||||
} else if (fvp->v_type == VREG) {
|
} else if (fvp->v_type == VREG) {
|
||||||
flags |= 1;
|
flags |= 1;
|
||||||
} else {
|
} else {
|
||||||
error = EINVAL;
|
return EINVAL;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
smb_makescred(&scred, tcnp->cn_thread, tcnp->cn_cred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, tcnp->cn_thread, tcnp->cn_cred);
|
||||||
/*
|
/*
|
||||||
* It seems that Samba doesn't implement SMB_COM_MOVE call...
|
* It seems that Samba doesn't implement SMB_COM_MOVE call...
|
||||||
*/
|
*/
|
||||||
#ifdef notnow
|
#ifdef notnow
|
||||||
if (SMB_DIALECT(SSTOCN(smp->sm_share)) >= SMB_DIALECT_LANMAN1_0) {
|
if (SMB_DIALECT(SSTOCN(smp->sm_share)) >= SMB_DIALECT_LANMAN1_0) {
|
||||||
error = smbfs_smb_move(VTOSMB(fvp), VTOSMB(tdvp),
|
error = smbfs_smb_move(VTOSMB(fvp), VTOSMB(tdvp),
|
||||||
tcnp->cn_nameptr, tcnp->cn_namelen, flags, &scred);
|
tcnp->cn_nameptr, tcnp->cn_namelen, flags, scred);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -596,13 +615,13 @@ smbfs_rename(ap)
|
||||||
* We have to do the work atomicaly
|
* We have to do the work atomicaly
|
||||||
*/
|
*/
|
||||||
if (tvp && tvp != fvp) {
|
if (tvp && tvp != fvp) {
|
||||||
error = smbfs_smb_delete(VTOSMB(tvp), &scred);
|
error = smbfs_smb_delete(VTOSMB(tvp), scred);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_cacherem;
|
goto out_cacherem;
|
||||||
VTOSMB(fvp)->n_flag |= NGONE;
|
VTOSMB(fvp)->n_flag |= NGONE;
|
||||||
}
|
}
|
||||||
error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp),
|
error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp),
|
||||||
tcnp->cn_nameptr, tcnp->cn_namelen, &scred);
|
tcnp->cn_nameptr, tcnp->cn_namelen, scred);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fvp->v_type == VDIR) {
|
if (fvp->v_type == VDIR) {
|
||||||
|
@ -615,6 +634,7 @@ smbfs_rename(ap)
|
||||||
smbfs_attr_cacheremove(fdvp);
|
smbfs_attr_cacheremove(fdvp);
|
||||||
smbfs_attr_cacheremove(tdvp);
|
smbfs_attr_cacheremove(tdvp);
|
||||||
out:
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
if (tdvp == tvp)
|
if (tdvp == tvp)
|
||||||
vrele(tdvp);
|
vrele(tdvp);
|
||||||
else
|
else
|
||||||
|
@ -685,7 +705,7 @@ smbfs_mkdir(ap)
|
||||||
struct componentname *cnp = ap->a_cnp;
|
struct componentname *cnp = ap->a_cnp;
|
||||||
struct smbnode *dnp = VTOSMB(dvp);
|
struct smbnode *dnp = VTOSMB(dvp);
|
||||||
struct vattr vattr;
|
struct vattr vattr;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
struct smbfattr fattr;
|
struct smbfattr fattr;
|
||||||
char *name = cnp->cn_nameptr;
|
char *name = cnp->cn_nameptr;
|
||||||
int len = cnp->cn_namelen;
|
int len = cnp->cn_namelen;
|
||||||
|
@ -696,17 +716,20 @@ smbfs_mkdir(ap)
|
||||||
}
|
}
|
||||||
if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.'))))
|
if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.'))))
|
||||||
return EEXIST;
|
return EEXIST;
|
||||||
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred);
|
scred = smbfs_malloc_scred();
|
||||||
error = smbfs_smb_mkdir(dnp, name, len, &scred);
|
smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
|
||||||
|
error = smbfs_smb_mkdir(dnp, name, len, scred);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
error = smbfs_smb_lookup(dnp, name, len, &fattr, &scred);
|
error = smbfs_smb_lookup(dnp, name, len, &fattr, scred);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp);
|
error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
*ap->a_vpp = vp;
|
*ap->a_vpp = vp;
|
||||||
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,20 +750,22 @@ smbfs_rmdir(ap)
|
||||||
/* struct smbmount *smp = VTOSMBFS(vp);*/
|
/* struct smbmount *smp = VTOSMBFS(vp);*/
|
||||||
struct smbnode *dnp = VTOSMB(dvp);
|
struct smbnode *dnp = VTOSMB(dvp);
|
||||||
struct smbnode *np = VTOSMB(vp);
|
struct smbnode *np = VTOSMB(vp);
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (dvp == vp)
|
if (dvp == vp)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred);
|
scred = smbfs_malloc_scred();
|
||||||
error = smbfs_smb_rmdir(np, &scred);
|
smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
|
||||||
|
error = smbfs_smb_rmdir(np, scred);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
np->n_flag |= NGONE;
|
np->n_flag |= NGONE;
|
||||||
dnp->n_flag |= NMODIFIED;
|
dnp->n_flag |= NMODIFIED;
|
||||||
smbfs_attr_cacheremove(dvp);
|
smbfs_attr_cacheremove(dvp);
|
||||||
/* cache_purge(dvp);*/
|
/* cache_purge(dvp);*/
|
||||||
cache_purge(vp);
|
cache_purge(vp);
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,7 +961,7 @@ smbfs_advlock(ap)
|
||||||
caddr_t id = (caddr_t)1 /* ap->a_id */;
|
caddr_t id = (caddr_t)1 /* ap->a_id */;
|
||||||
/* int flags = ap->a_flags;*/
|
/* int flags = ap->a_flags;*/
|
||||||
struct thread *td = curthread;
|
struct thread *td = curthread;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
u_quad_t size;
|
u_quad_t size;
|
||||||
off_t start, end, oadd;
|
off_t start, end, oadd;
|
||||||
int error, lkop;
|
int error, lkop;
|
||||||
|
@ -986,7 +1011,8 @@ smbfs_advlock(ap)
|
||||||
return EOVERFLOW;
|
return EOVERFLOW;
|
||||||
end = start + oadd;
|
end = start + oadd;
|
||||||
}
|
}
|
||||||
smb_makescred(&scred, td, td->td_ucred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, td, td->td_ucred);
|
||||||
switch (ap->a_op) {
|
switch (ap->a_op) {
|
||||||
case F_SETLK:
|
case F_SETLK:
|
||||||
switch (fl->l_type) {
|
switch (fl->l_type) {
|
||||||
|
@ -1000,13 +1026,14 @@ smbfs_advlock(ap)
|
||||||
lkop = SMB_LOCK_RELEASE;
|
lkop = SMB_LOCK_RELEASE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
error = lf_advlock(ap, &vp->v_lockf, size);
|
error = lf_advlock(ap, &vp->v_lockf, size);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
lkop = SMB_LOCK_EXCL;
|
lkop = SMB_LOCK_EXCL;
|
||||||
error = smbfs_smb_lock(np, lkop, id, start, end, &scred);
|
error = smbfs_smb_lock(np, lkop, id, start, end, scred);
|
||||||
if (error) {
|
if (error) {
|
||||||
int oldtype = fl->l_type;
|
int oldtype = fl->l_type;
|
||||||
fl->l_type = F_UNLCK;
|
fl->l_type = F_UNLCK;
|
||||||
|
@ -1017,14 +1044,16 @@ smbfs_advlock(ap)
|
||||||
break;
|
break;
|
||||||
case F_UNLCK:
|
case F_UNLCK:
|
||||||
lf_advlock(ap, &vp->v_lockf, size);
|
lf_advlock(ap, &vp->v_lockf, size);
|
||||||
error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, id, start, end, &scred);
|
error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, id, start, end, scred);
|
||||||
break;
|
break;
|
||||||
case F_GETLK:
|
case F_GETLK:
|
||||||
error = lf_advlock(ap, &vp->v_lockf, size);
|
error = lf_advlock(ap, &vp->v_lockf, size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
smbfs_free_scred(scred);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1091,7 +1120,7 @@ smbfs_lookup(ap)
|
||||||
struct mount *mp = dvp->v_mount;
|
struct mount *mp = dvp->v_mount;
|
||||||
struct smbnode *dnp;
|
struct smbnode *dnp;
|
||||||
struct smbfattr fattr, *fap;
|
struct smbfattr fattr, *fap;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
char *name = cnp->cn_nameptr;
|
char *name = cnp->cn_nameptr;
|
||||||
int flags = cnp->cn_flags;
|
int flags = cnp->cn_flags;
|
||||||
int nameiop = cnp->cn_nameiop;
|
int nameiop = cnp->cn_nameiop;
|
||||||
|
@ -1182,20 +1211,21 @@ smbfs_lookup(ap)
|
||||||
*/
|
*/
|
||||||
error = 0;
|
error = 0;
|
||||||
*vpp = NULLVP;
|
*vpp = NULLVP;
|
||||||
smb_makescred(&scred, td, cnp->cn_cred);
|
scred = smbfs_malloc_scred();
|
||||||
|
smb_makescred(scred, td, cnp->cn_cred);
|
||||||
fap = &fattr;
|
fap = &fattr;
|
||||||
if (flags & ISDOTDOT) {
|
if (flags & ISDOTDOT) {
|
||||||
error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
|
error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
|
||||||
&scred);
|
scred);
|
||||||
SMBVDEBUG("result of dotdot lookup: %d\n", error);
|
SMBVDEBUG("result of dotdot lookup: %d\n", error);
|
||||||
} else {
|
} else {
|
||||||
fap = &fattr;
|
fap = &fattr;
|
||||||
error = smbfs_smb_lookup(dnp, name, nmlen, fap, &scred);
|
error = smbfs_smb_lookup(dnp, name, nmlen, fap, scred);
|
||||||
/* if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')*/
|
/* if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')*/
|
||||||
SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error);
|
SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error);
|
||||||
}
|
}
|
||||||
if (error && error != ENOENT)
|
if (error && error != ENOENT)
|
||||||
return error;
|
goto out;
|
||||||
if (error) { /* entry not found */
|
if (error) { /* entry not found */
|
||||||
/*
|
/*
|
||||||
* Handle RENAME or CREATE case...
|
* Handle RENAME or CREATE case...
|
||||||
|
@ -1203,11 +1233,13 @@ smbfs_lookup(ap)
|
||||||
if ((nameiop == CREATE || nameiop == RENAME) && islastcn) {
|
if ((nameiop == CREATE || nameiop == RENAME) && islastcn) {
|
||||||
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
|
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
cnp->cn_flags |= SAVENAME;
|
cnp->cn_flags |= SAVENAME;
|
||||||
return (EJUSTRETURN);
|
error = EJUSTRETURN;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
return ENOENT;
|
error = ENOENT;
|
||||||
|
goto out;
|
||||||
}/* else {
|
}/* else {
|
||||||
SMBVDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum);
|
SMBVDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum);
|
||||||
}*/
|
}*/
|
||||||
|
@ -1217,38 +1249,40 @@ smbfs_lookup(ap)
|
||||||
if (nameiop == DELETE && islastcn) { /* delete last component */
|
if (nameiop == DELETE && islastcn) { /* delete last component */
|
||||||
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
|
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
if (isdot) {
|
if (isdot) {
|
||||||
VREF(dvp);
|
VREF(dvp);
|
||||||
*vpp = dvp;
|
*vpp = dvp;
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
|
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
cnp->cn_flags |= SAVENAME;
|
cnp->cn_flags |= SAVENAME;
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
if (nameiop == RENAME && islastcn) {
|
if (nameiop == RENAME && islastcn) {
|
||||||
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
|
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
if (isdot)
|
if (isdot) {
|
||||||
return EISDIR;
|
error = EISDIR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
|
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
cnp->cn_flags |= SAVENAME;
|
cnp->cn_flags |= SAVENAME;
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
if (flags & ISDOTDOT) {
|
if (flags & ISDOTDOT) {
|
||||||
VOP_UNLOCK(dvp, 0);
|
VOP_UNLOCK(dvp, 0);
|
||||||
error = smbfs_nget(mp, dvp, name, nmlen, NULL, &vp);
|
error = smbfs_nget(mp, dvp, name, nmlen, NULL, &vp);
|
||||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
} else if (isdot) {
|
} else if (isdot) {
|
||||||
vref(dvp);
|
vref(dvp);
|
||||||
|
@ -1256,7 +1290,7 @@ smbfs_lookup(ap)
|
||||||
} else {
|
} else {
|
||||||
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
|
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
goto out;
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
SMBVDEBUG("lookup: getnewvp!\n");
|
SMBVDEBUG("lookup: getnewvp!\n");
|
||||||
}
|
}
|
||||||
|
@ -1264,5 +1298,7 @@ smbfs_lookup(ap)
|
||||||
/* VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_vattr.va_ctime.tv_sec;*/
|
/* VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_vattr.va_ctime.tv_sec;*/
|
||||||
cache_enter(dvp, *vpp, cnp);
|
cache_enter(dvp, *vpp, cnp);
|
||||||
}
|
}
|
||||||
return 0;
|
out:
|
||||||
|
smbfs_free_scred(scred);
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -868,8 +868,6 @@ smb_share_getinfo(struct smb_share *ssp, struct smb_share_info *sip)
|
||||||
static int
|
static int
|
||||||
smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
|
smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
struct thread *td = req->td;
|
|
||||||
struct smb_cred scred;
|
|
||||||
struct smb_connobj *scp1, *scp2;
|
struct smb_connobj *scp1, *scp2;
|
||||||
struct smb_vc *vcp;
|
struct smb_vc *vcp;
|
||||||
struct smb_share *ssp;
|
struct smb_share *ssp;
|
||||||
|
@ -877,7 +875,6 @@ smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
|
||||||
struct smb_share_info ssi;
|
struct smb_share_info ssi;
|
||||||
int error, itype;
|
int error, itype;
|
||||||
|
|
||||||
smb_makescred(&scred, td, td->td_ucred);
|
|
||||||
error = sysctl_wire_old_buffer(req, 0);
|
error = sysctl_wire_old_buffer(req, 0);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
|
@ -157,22 +157,24 @@ nsmb_dev_close(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||||
struct smb_dev *sdp;
|
struct smb_dev *sdp;
|
||||||
struct smb_vc *vcp;
|
struct smb_vc *vcp;
|
||||||
struct smb_share *ssp;
|
struct smb_share *ssp;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
|
scred = malloc(sizeof(struct smb_cred), M_NSMBDEV, M_WAITOK);
|
||||||
SMB_CHECKMINOR(dev);
|
SMB_CHECKMINOR(dev);
|
||||||
s = splimp();
|
s = splimp();
|
||||||
if ((sdp->sd_flags & NSMBFL_OPEN) == 0) {
|
if ((sdp->sd_flags & NSMBFL_OPEN) == 0) {
|
||||||
splx(s);
|
splx(s);
|
||||||
|
free(scred, M_NSMBDEV);
|
||||||
return EBADF;
|
return EBADF;
|
||||||
}
|
}
|
||||||
smb_makescred(&scred, td, NULL);
|
smb_makescred(scred, td, NULL);
|
||||||
ssp = sdp->sd_share;
|
ssp = sdp->sd_share;
|
||||||
if (ssp != NULL)
|
if (ssp != NULL)
|
||||||
smb_share_rele(ssp, &scred);
|
smb_share_rele(ssp, scred);
|
||||||
vcp = sdp->sd_vc;
|
vcp = sdp->sd_vc;
|
||||||
if (vcp != NULL)
|
if (vcp != NULL)
|
||||||
smb_vc_rele(vcp, &scred);
|
smb_vc_rele(vcp, scred);
|
||||||
/*
|
/*
|
||||||
smb_flushq(&sdp->sd_rqlist);
|
smb_flushq(&sdp->sd_rqlist);
|
||||||
smb_flushq(&sdp->sd_rplist);
|
smb_flushq(&sdp->sd_rplist);
|
||||||
|
@ -181,6 +183,7 @@ nsmb_dev_close(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||||
free(sdp, M_NSMBDEV);
|
free(sdp, M_NSMBDEV);
|
||||||
destroy_dev_sched(dev);
|
destroy_dev_sched(dev);
|
||||||
splx(s);
|
splx(s);
|
||||||
|
free(scred, M_NSMBDEV);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,20 +194,23 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
struct smb_dev *sdp;
|
struct smb_dev *sdp;
|
||||||
struct smb_vc *vcp;
|
struct smb_vc *vcp;
|
||||||
struct smb_share *ssp;
|
struct smb_share *ssp;
|
||||||
struct smb_cred scred;
|
struct smb_cred *scred;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
SMB_CHECKMINOR(dev);
|
SMB_CHECKMINOR(dev);
|
||||||
if ((sdp->sd_flags & NSMBFL_OPEN) == 0)
|
if ((sdp->sd_flags & NSMBFL_OPEN) == 0)
|
||||||
return EBADF;
|
return EBADF;
|
||||||
|
|
||||||
smb_makescred(&scred, td, NULL);
|
scred = malloc(sizeof(struct smb_cred), M_NSMBDEV, M_WAITOK);
|
||||||
|
smb_makescred(scred, td, NULL);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SMBIOC_OPENSESSION:
|
case SMBIOC_OPENSESSION:
|
||||||
if (sdp->sd_vc)
|
if (sdp->sd_vc) {
|
||||||
return EISCONN;
|
error = EISCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
error = smb_usr_opensession((struct smbioc_ossn*)data,
|
error = smb_usr_opensession((struct smbioc_ossn*)data,
|
||||||
&scred, &vcp);
|
scred, &vcp);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
sdp->sd_vc = vcp;
|
sdp->sd_vc = vcp;
|
||||||
|
@ -212,12 +218,16 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
sdp->sd_level = SMBL_VC;
|
sdp->sd_level = SMBL_VC;
|
||||||
break;
|
break;
|
||||||
case SMBIOC_OPENSHARE:
|
case SMBIOC_OPENSHARE:
|
||||||
if (sdp->sd_share)
|
if (sdp->sd_share) {
|
||||||
return EISCONN;
|
error = EISCONN;
|
||||||
if (sdp->sd_vc == NULL)
|
goto out;
|
||||||
return ENOTCONN;
|
}
|
||||||
|
if (sdp->sd_vc == NULL) {
|
||||||
|
error = ENOTCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
error = smb_usr_openshare(sdp->sd_vc,
|
error = smb_usr_openshare(sdp->sd_vc,
|
||||||
(struct smbioc_oshare*)data, &scred, &ssp);
|
(struct smbioc_oshare*)data, scred, &ssp);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
sdp->sd_share = ssp;
|
sdp->sd_share = ssp;
|
||||||
|
@ -225,16 +235,20 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
sdp->sd_level = SMBL_SHARE;
|
sdp->sd_level = SMBL_SHARE;
|
||||||
break;
|
break;
|
||||||
case SMBIOC_REQUEST:
|
case SMBIOC_REQUEST:
|
||||||
if (sdp->sd_share == NULL)
|
if (sdp->sd_share == NULL) {
|
||||||
return ENOTCONN;
|
error = ENOTCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
error = smb_usr_simplerequest(sdp->sd_share,
|
error = smb_usr_simplerequest(sdp->sd_share,
|
||||||
(struct smbioc_rq*)data, &scred);
|
(struct smbioc_rq*)data, scred);
|
||||||
break;
|
break;
|
||||||
case SMBIOC_T2RQ:
|
case SMBIOC_T2RQ:
|
||||||
if (sdp->sd_share == NULL)
|
if (sdp->sd_share == NULL) {
|
||||||
return ENOTCONN;
|
error = ENOTCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
error = smb_usr_t2request(sdp->sd_share,
|
error = smb_usr_t2request(sdp->sd_share,
|
||||||
(struct smbioc_t2rq*)data, &scred);
|
(struct smbioc_t2rq*)data, scred);
|
||||||
break;
|
break;
|
||||||
case SMBIOC_SETFLAGS: {
|
case SMBIOC_SETFLAGS: {
|
||||||
struct smbioc_flags *fl = (struct smbioc_flags*)data;
|
struct smbioc_flags *fl = (struct smbioc_flags*)data;
|
||||||
|
@ -243,9 +257,11 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
if (fl->ioc_level == SMBL_VC) {
|
if (fl->ioc_level == SMBL_VC) {
|
||||||
if (fl->ioc_mask & SMBV_PERMANENT) {
|
if (fl->ioc_mask & SMBV_PERMANENT) {
|
||||||
on = fl->ioc_flags & SMBV_PERMANENT;
|
on = fl->ioc_flags & SMBV_PERMANENT;
|
||||||
if ((vcp = sdp->sd_vc) == NULL)
|
if ((vcp = sdp->sd_vc) == NULL) {
|
||||||
return ENOTCONN;
|
error = ENOTCONN;
|
||||||
error = smb_vc_get(vcp, LK_EXCLUSIVE, &scred);
|
goto out;
|
||||||
|
}
|
||||||
|
error = smb_vc_get(vcp, LK_EXCLUSIVE, scred);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
if (on && (vcp->obj.co_flags & SMBV_PERMANENT) == 0) {
|
if (on && (vcp->obj.co_flags & SMBV_PERMANENT) == 0) {
|
||||||
|
@ -253,17 +269,19 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
smb_vc_ref(vcp);
|
smb_vc_ref(vcp);
|
||||||
} else if (!on && (vcp->obj.co_flags & SMBV_PERMANENT)) {
|
} else if (!on && (vcp->obj.co_flags & SMBV_PERMANENT)) {
|
||||||
vcp->obj.co_flags &= ~SMBV_PERMANENT;
|
vcp->obj.co_flags &= ~SMBV_PERMANENT;
|
||||||
smb_vc_rele(vcp, &scred);
|
smb_vc_rele(vcp, scred);
|
||||||
}
|
}
|
||||||
smb_vc_put(vcp, &scred);
|
smb_vc_put(vcp, scred);
|
||||||
} else
|
} else
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
} else if (fl->ioc_level == SMBL_SHARE) {
|
} else if (fl->ioc_level == SMBL_SHARE) {
|
||||||
if (fl->ioc_mask & SMBS_PERMANENT) {
|
if (fl->ioc_mask & SMBS_PERMANENT) {
|
||||||
on = fl->ioc_flags & SMBS_PERMANENT;
|
on = fl->ioc_flags & SMBS_PERMANENT;
|
||||||
if ((ssp = sdp->sd_share) == NULL)
|
if ((ssp = sdp->sd_share) == NULL) {
|
||||||
return ENOTCONN;
|
error = ENOTCONN;
|
||||||
error = smb_share_get(ssp, LK_EXCLUSIVE, &scred);
|
goto out;
|
||||||
|
}
|
||||||
|
error = smb_share_get(ssp, LK_EXCLUSIVE, scred);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
if (on && (ssp->obj.co_flags & SMBS_PERMANENT) == 0) {
|
if (on && (ssp->obj.co_flags & SMBS_PERMANENT) == 0) {
|
||||||
|
@ -271,9 +289,9 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
smb_share_ref(ssp);
|
smb_share_ref(ssp);
|
||||||
} else if (!on && (ssp->obj.co_flags & SMBS_PERMANENT)) {
|
} else if (!on && (ssp->obj.co_flags & SMBS_PERMANENT)) {
|
||||||
ssp->obj.co_flags &= ~SMBS_PERMANENT;
|
ssp->obj.co_flags &= ~SMBS_PERMANENT;
|
||||||
smb_share_rele(ssp, &scred);
|
smb_share_rele(ssp, scred);
|
||||||
}
|
}
|
||||||
smb_share_put(ssp, &scred);
|
smb_share_put(ssp, scred);
|
||||||
} else
|
} else
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
|
@ -282,11 +300,13 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMBIOC_LOOKUP:
|
case SMBIOC_LOOKUP:
|
||||||
if (sdp->sd_vc || sdp->sd_share)
|
if (sdp->sd_vc || sdp->sd_share) {
|
||||||
return EISCONN;
|
error = EISCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
vcp = NULL;
|
vcp = NULL;
|
||||||
ssp = NULL;
|
ssp = NULL;
|
||||||
error = smb_usr_lookup((struct smbioc_lookup*)data, &scred, &vcp, &ssp);
|
error = smb_usr_lookup((struct smbioc_lookup*)data, scred, &vcp, &ssp);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
if (vcp) {
|
if (vcp) {
|
||||||
|
@ -305,8 +325,10 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
struct uio auio;
|
struct uio auio;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
|
|
||||||
if ((ssp = sdp->sd_share) == NULL)
|
if ((ssp = sdp->sd_share) == NULL) {
|
||||||
return ENOTCONN;
|
error = ENOTCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
iov.iov_base = rwrq->ioc_base;
|
iov.iov_base = rwrq->ioc_base;
|
||||||
iov.iov_len = rwrq->ioc_cnt;
|
iov.iov_len = rwrq->ioc_cnt;
|
||||||
auio.uio_iov = &iov;
|
auio.uio_iov = &iov;
|
||||||
|
@ -317,15 +339,17 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
|
||||||
auio.uio_rw = (cmd == SMBIOC_READ) ? UIO_READ : UIO_WRITE;
|
auio.uio_rw = (cmd == SMBIOC_READ) ? UIO_READ : UIO_WRITE;
|
||||||
auio.uio_td = td;
|
auio.uio_td = td;
|
||||||
if (cmd == SMBIOC_READ)
|
if (cmd == SMBIOC_READ)
|
||||||
error = smb_read(ssp, rwrq->ioc_fh, &auio, &scred);
|
error = smb_read(ssp, rwrq->ioc_fh, &auio, scred);
|
||||||
else
|
else
|
||||||
error = smb_write(ssp, rwrq->ioc_fh, &auio, &scred);
|
error = smb_write(ssp, rwrq->ioc_fh, &auio, scred);
|
||||||
rwrq->ioc_cnt -= auio.uio_resid;
|
rwrq->ioc_cnt -= auio.uio_resid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
error = ENODEV;
|
error = ENODEV;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
free(scred, M_NSMBDEV);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,8 +192,8 @@ nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct thread *td)
|
||||||
static int
|
static int
|
||||||
nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
|
nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
|
||||||
{
|
{
|
||||||
struct mbchain mb, *mbp = &mb;
|
struct mbchain *mbp;
|
||||||
struct mdchain md, *mdp = &md;
|
struct mdchain *mdp;
|
||||||
struct mbuf *m0;
|
struct mbuf *m0;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
@ -201,9 +201,14 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
|
||||||
u_int8_t rpcode;
|
u_int8_t rpcode;
|
||||||
int error, rplen;
|
int error, rplen;
|
||||||
|
|
||||||
|
mbp = malloc(sizeof(struct mbchain), M_NBDATA, M_WAITOK);
|
||||||
|
mdp = malloc(sizeof(struct mbchain), M_NBDATA, M_WAITOK);
|
||||||
error = mb_init(mbp);
|
error = mb_init(mbp);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(mbp, M_NBDATA);
|
||||||
|
free(mdp, M_NBDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
mb_put_uint32le(mbp, 0);
|
mb_put_uint32le(mbp, 0);
|
||||||
nb_put_name(mbp, nbp->nbp_paddr);
|
nb_put_name(mbp, nbp->nbp_paddr);
|
||||||
nb_put_name(mbp, nbp->nbp_laddr);
|
nb_put_name(mbp, nbp->nbp_laddr);
|
||||||
|
@ -214,19 +219,26 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
|
||||||
}
|
}
|
||||||
mb_detach(mbp);
|
mb_detach(mbp);
|
||||||
mb_done(mbp);
|
mb_done(mbp);
|
||||||
if (error)
|
free(mbp, M_NBDATA);
|
||||||
|
if (error) {
|
||||||
|
free(mdp, M_NBDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo);
|
TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo);
|
||||||
error = selsocket(nbp->nbp_tso, POLLIN, &tv, td);
|
error = selsocket(nbp->nbp_tso, POLLIN, &tv, td);
|
||||||
if (error == EWOULDBLOCK) { /* Timeout */
|
if (error == EWOULDBLOCK) { /* Timeout */
|
||||||
NBDEBUG("initial request timeout\n");
|
NBDEBUG("initial request timeout\n");
|
||||||
|
free(mdp, M_NBDATA);
|
||||||
return ETIMEDOUT;
|
return ETIMEDOUT;
|
||||||
}
|
}
|
||||||
if (error) /* restart or interrupt */
|
if (error) { /* restart or interrupt */
|
||||||
|
free(mdp, M_NBDATA);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
error = nbssn_recv(nbp, &m0, &rplen, &rpcode, td);
|
error = nbssn_recv(nbp, &m0, &rplen, &rpcode, td);
|
||||||
if (error) {
|
if (error) {
|
||||||
NBDEBUG("recv() error %d\n", error);
|
NBDEBUG("recv() error %d\n", error);
|
||||||
|
free(mdp, M_NBDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -264,6 +276,7 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
|
||||||
} while(0);
|
} while(0);
|
||||||
if (m0)
|
if (m0)
|
||||||
md_done(mdp);
|
md_done(mdp);
|
||||||
|
free(mdp, M_NBDATA);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,8 +127,8 @@ smb_usr_lookup(struct smbioc_lookup *dp, struct smb_cred *scred,
|
||||||
struct smb_vc **vcpp, struct smb_share **sspp)
|
struct smb_vc **vcpp, struct smb_share **sspp)
|
||||||
{
|
{
|
||||||
struct smb_vc *vcp = NULL;
|
struct smb_vc *vcp = NULL;
|
||||||
struct smb_vcspec vspec;
|
struct smb_vcspec vspec; /* XXX */
|
||||||
struct smb_sharespec sspec, *sspecp = NULL;
|
struct smb_sharespec sspec, *sspecp = NULL; /* XXX */
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (dp->ioc_level < SMBL_VC || dp->ioc_level > SMBL_SHARE)
|
if (dp->ioc_level < SMBL_VC || dp->ioc_level > SMBL_SHARE)
|
||||||
|
@ -212,7 +212,7 @@ int
|
||||||
smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp,
|
smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp,
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_rq rq, *rqp = &rq;
|
struct smb_rq *rqp;
|
||||||
struct mbchain *mbp;
|
struct mbchain *mbp;
|
||||||
struct mdchain *mdp;
|
struct mdchain *mdp;
|
||||||
u_int8_t wc;
|
u_int8_t wc;
|
||||||
|
@ -231,9 +231,12 @@ smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp,
|
||||||
case SMB_COM_TREE_CONNECT_ANDX:
|
case SMB_COM_TREE_CONNECT_ANDX:
|
||||||
return EPERM;
|
return EPERM;
|
||||||
}
|
}
|
||||||
|
rqp = malloc(sizeof(struct smb_rq), M_SMBTEMP, M_WAITOK);
|
||||||
error = smb_rq_init(rqp, SSTOCP(ssp), dp->ioc_cmd, scred);
|
error = smb_rq_init(rqp, SSTOCP(ssp), dp->ioc_cmd, scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(rqp, M_SMBTEMP);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
mbp = &rqp->sr_rq;
|
mbp = &rqp->sr_rq;
|
||||||
smb_rq_wstart(rqp);
|
smb_rq_wstart(rqp);
|
||||||
error = mb_put_mem(mbp, dp->ioc_twords, dp->ioc_twc * 2, MB_MUSER);
|
error = mb_put_mem(mbp, dp->ioc_twords, dp->ioc_twc * 2, MB_MUSER);
|
||||||
|
@ -271,6 +274,7 @@ smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp,
|
||||||
dp->ioc_serror = rqp->sr_serror;
|
dp->ioc_serror = rqp->sr_serror;
|
||||||
dp->ioc_error = rqp->sr_error;
|
dp->ioc_error = rqp->sr_error;
|
||||||
smb_rq_done(rqp);
|
smb_rq_done(rqp);
|
||||||
|
free(rqp, M_SMBTEMP);
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -292,15 +296,18 @@ int
|
||||||
smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *dp,
|
smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *dp,
|
||||||
struct smb_cred *scred)
|
struct smb_cred *scred)
|
||||||
{
|
{
|
||||||
struct smb_t2rq t2, *t2p = &t2;
|
struct smb_t2rq *t2p;
|
||||||
struct mdchain *mdp;
|
struct mdchain *mdp;
|
||||||
int error, len;
|
int error, len;
|
||||||
|
|
||||||
if (dp->ioc_setupcnt > 3)
|
if (dp->ioc_setupcnt > 3)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
t2p = malloc(sizeof(struct smb_t2rq), M_SMBTEMP, M_WAITOK);
|
||||||
error = smb_t2_init(t2p, SSTOCP(ssp), dp->ioc_setup[0], scred);
|
error = smb_t2_init(t2p, SSTOCP(ssp), dp->ioc_setup[0], scred);
|
||||||
if (error)
|
if (error) {
|
||||||
|
free(t2p, M_SMBTEMP);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
len = t2p->t2_setupcount = dp->ioc_setupcnt;
|
len = t2p->t2_setupcount = dp->ioc_setupcnt;
|
||||||
if (len > 1)
|
if (len > 1)
|
||||||
t2p->t2_setupdata = dp->ioc_setup;
|
t2p->t2_setupdata = dp->ioc_setup;
|
||||||
|
@ -351,5 +358,6 @@ smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *dp,
|
||||||
if (t2p->t_name)
|
if (t2p->t_name)
|
||||||
smb_strfree(t2p->t_name);
|
smb_strfree(t2p->t_name);
|
||||||
smb_t2_done(t2p);
|
smb_t2_done(t2p);
|
||||||
|
free(t2p, M_SMBTEMP);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue