/* * lookup name pointed by cnp in directory dvp and return file info in np. * May be I should create a little cache, but another way is to minimize * number of calls, on other hand, in multiprocess environment ... */ int ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap, struct thread *td,struct ucred *cred) { struct nwmount *nmp; struct nwnode *dnp; int error; if (!dvp || dvp->v_type != VDIR) { nwfs_printf("dvp is NULL or not a directory.\n"); return (ENOENT); } dnp = VTONW(dvp); nmp = VTONWFS(dvp); if (len == 1 && name[0] == '.') { if (dnp->n_flag & NVOLUME) { error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 0, NULL, fap, td, cred); } else { error = ncp_obtain_info(nmp, dnp->n_fid.f_parent, dnp->n_nmlen, dnp->n_name, fap, td, cred); } return error; } else if (len == 2 && name[0] == '.' && name[1] == '.') { printf("%s: knows NOTHING about '..'\n", __func__); return EIO; } else { error = ncp_obtain_info(nmp, dnp->n_fid.f_id, len, name, fap, td, cred); } return error; }
/* * mp - path - addr in user space of mount point (ie /usr or whatever) * data - addr in user space of mount params */ static int nwfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) { struct nwfs_args args; /* will hold data from mount request */ int error; struct nwmount *nmp = NULL; struct ncp_conn *conn = NULL; struct ncp_handle *handle = NULL; struct vnode *vp; char *pc,*pe; if (data == NULL) { nwfs_printf("missing data argument\n"); return 1; } if (mp->mnt_flag & MNT_UPDATE) { nwfs_printf("MNT_UPDATE not implemented"); return (EOPNOTSUPP); } error = copyin(data, (caddr_t)&args, sizeof(struct nwfs_args)); if (error) return (error); if (args.version != NWFS_VERSION) { nwfs_printf("mount version mismatch: kernel=%d, mount=%d\n",NWFS_VERSION,args.version); return (1); } error = ncp_conn_getbyref(args.connRef,curthread,cred,NCPM_EXECUTE,&conn); if (error) { nwfs_printf("invalid connection reference %d\n",args.connRef); return (error); } error = ncp_conn_gethandle(conn, NULL, &handle); if (error) { nwfs_printf("can't get connection handle\n"); return (error); } ncp_conn_unlock(conn,curthread); /* we keep the ref */ mp->mnt_stat.f_iosize = conn->buffer_size; /* We must malloc our own mount info */ nmp = kmalloc(sizeof(struct nwmount), M_NWFSDATA, M_WAITOK | M_USE_RESERVE | M_ZERO); mp->mnt_data = (qaddr_t)nmp; nmp->connh = handle; nmp->n_root = NULL; nmp->n_id = nwfsid++; nmp->m = args; nmp->m.file_mode = (nmp->m.file_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG; nmp->m.dir_mode = (nmp->m.dir_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR; if ((error = nwfs_initnls(nmp)) != 0) goto bad; pc = mp->mnt_stat.f_mntfromname; pe = pc+sizeof(mp->mnt_stat.f_mntfromname); bzero(pc, MNAMELEN); *(pc++) = '/'; pc = index(strncpy(pc, conn->li.server, pe-pc-2),0); if (pc < pe-1) { *(pc++) = ':'; pc=index(strncpy(pc, conn->li.user, pe-pc-2),0); if (pc < pe-1) { *(pc++) = '/'; strncpy(pc, nmp->m.mounted_vol, pe-pc-2); } } /* protect against invalid mount points */ nmp->m.mount_point[sizeof(nmp->m.mount_point)-1] = '\0'; vfs_add_vnodeops(mp, &nwfs_vnode_vops, &mp->mnt_vn_norm_ops); vfs_getnewfsid(mp); error = nwfs_root(mp, &vp); if (error) goto bad; /* * Lose the lock but keep the ref. */ vn_unlock(vp); NCPVODEBUG("rootvp.vrefcnt=%d\n",vp->v_sysref.refcnt); return error; bad: if (nmp) kfree(nmp, M_NWFSDATA); if (handle) ncp_conn_puthandle(handle, NULL, 0); return error; }
/* * mp - path - addr in user space of mount point (ie /usr or whatever) * data - addr in user space of mount params */ static int nwfs_mount(struct mount *mp) { struct nwfs_args args; /* will hold data from mount request */ int error; struct nwmount *nmp = NULL; struct ncp_conn *conn = NULL; struct ncp_handle *handle = NULL; struct vnode *vp; struct thread *td; char *pc,*pe; td = curthread; if (mp->mnt_flag & MNT_ROOTFS) return (EOPNOTSUPP); if (mp->mnt_flag & MNT_UPDATE) { nwfs_printf("MNT_UPDATE not implemented"); return (EOPNOTSUPP); } error = vfs_copyopt(mp->mnt_optnew, "nwfs_args", &args, sizeof args); if (error) return (error); if (args.version != NWFS_VERSION) { nwfs_printf("mount version mismatch: kernel=%d, mount=%d\n",NWFS_VERSION,args.version); return (1); } error = ncp_conn_getbyref(args.connRef, td , td->td_ucred,NCPM_EXECUTE,&conn); if (error) { nwfs_printf("invalid connection refernce %d\n",args.connRef); return (error); } error = ncp_conn_gethandle(conn, NULL, &handle); if (error) { nwfs_printf("can't get connection handle\n"); return (error); } ncp_conn_unlock(conn, td); /* we keep the ref */ mp->mnt_stat.f_iosize = conn->buffer_size; /* We must malloc our own mount info */ nmp = malloc(sizeof(struct nwmount),M_NWFSDATA, M_WAITOK | M_USE_RESERVE | M_ZERO); if (nmp == NULL) { nwfs_printf("could not alloc nwmount\n"); error = ENOMEM; goto bad; } mp->mnt_data = nmp; nmp->connh = handle; nmp->n_root = NULL; nmp->n_id = nwfsid++; nmp->m = args; nmp->m.file_mode = (nmp->m.file_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG; nmp->m.dir_mode = (nmp->m.dir_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR; if ((error = nwfs_initnls(nmp)) != 0) goto bad; pc = mp->mnt_stat.f_mntfromname; pe = pc+sizeof(mp->mnt_stat.f_mntfromname); bzero(pc, MNAMELEN); *(pc++) = '/'; pc = index(strncpy(pc, conn->li.server, pe-pc-2),0); if (pc < pe-1) { *(pc++) = ':'; pc=index(strncpy(pc, conn->li.user, pe-pc-2),0); if (pc < pe-1) { *(pc++) = '/'; strncpy(pc, nmp->m.mounted_vol, pe-pc-2); } } /* protect against invalid mount points */ nmp->m.mount_point[sizeof(nmp->m.mount_point)-1] = '\0'; vfs_getnewfsid(mp); error = nwfs_root(mp, LK_EXCLUSIVE, &vp); if (error) goto bad; /* * Lose the lock but keep the ref. */ VOP_UNLOCK(vp, 0); NCPVODEBUG("rootvp.vrefcnt=%d\n",vrefcnt(vp)); return error; bad: if (nmp) free(nmp, M_NWFSDATA); if (handle) ncp_conn_puthandle(handle, NULL, 0); return error; }