int smbfs_strategy(void *v) { struct vop_strategy_args /* { struct vnode *a_vp; struct buf *a_bp; } */ *ap = v; struct buf *bp = ap->a_bp; kauth_cred_t cr; struct lwp *l; int error = 0; SMBVDEBUG0("\n"); if ((bp->b_flags & (B_PHYS|B_ASYNC)) == (B_PHYS|B_ASYNC)) panic("smbfs physio/async"); if (bp->b_flags & B_ASYNC) { l = NULL; cr = NULL; } else { l = curlwp; /* XXX */ cr = l->l_cred; } if ((bp->b_flags & B_ASYNC) == 0) error = smbfs_doio(bp, cr, l); return (error); }
void smbfs_done(void) { pool_destroy(&smbfs_node_pool); malloc_type_detach(M_SMBNODENAME); malloc_type_detach(M_SMBFSDATA); SMBVDEBUG0("done.\n"); }
void smbfs_init(void) { malloc_type_attach(M_SMBNODENAME); malloc_type_attach(M_SMBFSDATA); pool_init(&smbfs_node_pool, sizeof(struct smbnode), 0, 0, 0, "smbfsnopl", &pool_allocator_nointr, IPL_NONE); SMBVDEBUG0("init.\n"); }
/* * smbfs_getattr call from vfs. */ int smbfs_getattr(void *v) { struct vop_getattr_args /* { struct vnode *a_vp; struct vattr *a_vap; kauth_cred_t a_cred; } */ *ap = v; struct vnode *vp = ap->a_vp; struct smbnode *np = VTOSMB(vp); struct vattr *va=ap->a_vap; struct smbfattr fattr; struct smb_cred scred; u_quad_t oldsize; int error; SMBVDEBUG("%p: '%.*s' isroot %d\n", vp, (int) np->n_nmlen, np->n_name, (vp->v_vflag & VV_ROOT) != 0); if ((error = smbfs_attr_cachelookup(vp, va)) == 0) return (0); SMBVDEBUG0("not in the cache\n"); smb_makescred(&scred, curlwp, ap->a_cred); oldsize = np->n_size; error = smbfs_smb_lookup(np, NULL, 0, &fattr, &scred); if (error) { SMBVDEBUG("error %d\n", error); return error; } smbfs_attr_cacheenter(vp, &fattr); smbfs_attr_cachelookup(vp, va); if ((np->n_flag & NOPEN) != 0) np->n_size = oldsize; return 0; }
int smbfs_setattr(void *v) { struct vop_setattr_args /* { struct vnode *a_vp; struct vattr *a_vap; kauth_cred_t a_cred; } */ *ap = v; struct lwp *l = curlwp; struct vnode *vp = ap->a_vp; struct smbnode *np = VTOSMB(vp); struct vattr *vap = ap->a_vap; struct timespec *mtime, *atime; struct smb_cred scred; struct smb_share *ssp = np->n_mount->sm_share; struct smb_vc *vcp = SSTOVC(ssp); u_quad_t tsize = 0; int isreadonly, doclose, error = 0; SMBVDEBUG0("\n"); if (vap->va_flags != VNOVAL) return EOPNOTSUPP; isreadonly = (vp->v_mount->mnt_flag & MNT_RDONLY); /* * Disallow write attempts if the filesystem is mounted read-only. */ if ((vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && isreadonly) return EROFS; smb_makescred(&scred, l, ap->a_cred); if (vap->va_size != VNOVAL) { switch (vp->v_type) { case VDIR: return EISDIR; case VREG: break; default: return EINVAL; }; if (isreadonly) return EROFS; doclose = 0; tsize = np->n_size; np->n_size = vap->va_size; uvm_vnp_setsize(vp, vap->va_size); if ((np->n_flag & NOPEN) == 0) { error = smbfs_smb_open(np, SMB_SM_DENYNONE|SMB_AM_OPENRW, &scred); if (error == 0) doclose = 1; } if (error == 0) error = smbfs_smb_setfsize(np, vap->va_size, &scred); if (doclose) smbfs_smb_close(ssp, np->n_fid, NULL, &scred); if (error) { np->n_size = tsize; uvm_vnp_setsize(vp, tsize); return (error); } } mtime = atime = NULL; if (vap->va_mtime.tv_sec != VNOVAL) mtime = &vap->va_mtime; if (vap->va_atime.tv_sec != VNOVAL) atime = &vap->va_atime; if (mtime != atime) { error = kauth_authorize_vnode(ap->a_cred, KAUTH_VNODE_WRITE_TIMES, ap->a_vp, NULL, genfs_can_chtimes(ap->a_vp, vap->va_vaflags, VTOSMBFS(vp)->sm_args.uid, ap->a_cred)); if (error) return (error); #if 0 if (mtime == NULL) mtime = &np->n_mtime; if (atime == NULL) atime = &np->n_atime; #endif /* * If file is opened, then we can use handle based calls. * If not, use path based ones. */ if ((np->n_flag & NOPEN) == 0) { if (vcp->vc_flags & SMBV_WIN95) { error = VOP_OPEN(vp, FWRITE, ap->a_cred); if (!error) { /* error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred); VOP_GETATTR(vp, &vattr, ap->a_cred);*/ if (mtime) np->n_mtime = *mtime; VOP_CLOSE(vp, FWRITE, ap->a_cred); } } else if (SMB_CAPS(vcp) & SMB_CAP_NT_SMBS) { error = smbfs_smb_setpattrNT(np, 0, mtime, atime, &scred); } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) { error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred); } else { error = smbfs_smb_setpattr(np, 0, mtime, &scred); } } else { if (SMB_CAPS(vcp) & SMB_CAP_NT_SMBS) { error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred); } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) { error = smbfs_smb_setftime(np, mtime, atime, &scred); } else { /* * XXX I have no idea how to handle this for core * level servers. The possible solution is to * update mtime after file is closed. */ } } } /* * Invalidate attribute cache in case if server doesn't set * required attributes. */ smbfs_attr_cacheremove(vp); /* invalidate cache */ VOP_GETATTR(vp, vap, ap->a_cred); np->n_mtime.tv_sec = vap->va_mtime.tv_sec; VN_KNOTE(vp, NOTE_ATTRIB); return error; }
void smbfs_reinit(void) { SMBVDEBUG0("reinit.\n"); }