nwfs_vfsops.c revision 162647
1185573Srwatson/*- 2191273Srwatson * Copyright (c) 1999, 2000 Boris Popov 3162503Srwatson * All rights reserved. 4155131Srwatson * 5155131Srwatson * Redistribution and use in source and binary forms, with or without 6155131Srwatson * modification, are permitted provided that the following conditions 7155131Srwatson * are met: 8155131Srwatson * 1. Redistributions of source code must retain the above copyright 9155131Srwatson * notice, this list of conditions and the following disclaimer. 10155131Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11155131Srwatson * notice, this list of conditions and the following disclaimer in the 12155131Srwatson * documentation and/or other materials provided with the distribution. 13155131Srwatson * 3. All advertising materials mentioning features or use of this software 14185573Srwatson * must display the following acknowledgement: 15155131Srwatson * This product includes software developed by Boris Popov. 16155131Srwatson * 4. Neither the name of the author nor the names of any co-contributors 17155131Srwatson * may be used to endorse or promote products derived from this software 18155131Srwatson * without specific prior written permission. 19155131Srwatson * 20155131Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21155131Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23155131Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24155131Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25155131Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26155131Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27155131Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28155131Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29155131Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30155131Srwatson * SUCH DAMAGE. 31185573Srwatson * 32185573Srwatson * $FreeBSD: head/sys/fs/nwfs/nwfs_vfsops.c 162647 2006-09-26 04:12:49Z tegge $ 33155131Srwatson */ 34155131Srwatson 35189279Srwatson#include <sys/param.h> 36155131Srwatson#include <sys/systm.h> 37155131Srwatson#include <sys/proc.h> 38243750Srwatson#include <sys/kernel.h> 39186647Srwatson#include <sys/sysctl.h> 40155131Srwatson#include <sys/vnode.h> 41186647Srwatson#include <sys/mount.h> 42155131Srwatson#include <sys/stat.h> 43155131Srwatson#include <sys/malloc.h> 44155131Srwatson#include <sys/bio.h> 45162503Srwatson#include <sys/buf.h> 46162503Srwatson 47162503Srwatson#include <netncp/ncp.h> 48185573Srwatson#include <netncp/ncp_conn.h> 49185573Srwatson#include <netncp/ncp_subr.h> 50185573Srwatson#include <netncp/ncp_ncp.h> 51162503Srwatson#include <netncp/ncp_nls.h> 52191273Srwatson 53191273Srwatson#include <fs/nwfs/nwfs.h> 54155131Srwatson#include <fs/nwfs/nwfs_node.h> 55155131Srwatson#include <fs/nwfs/nwfs_subr.h> 56162503Srwatson 57155131Srwatsonint nwfs_debuglevel = 0; 58155131Srwatson 59155131Srwatsonstatic int nwfs_version = NWFS_VERSION; 60155131Srwatson 61155131SrwatsonSYSCTL_DECL(_vfs_nwfs); 62155131SrwatsonSYSCTL_NODE(_vfs, OID_AUTO, nwfs, CTLFLAG_RW, 0, "Netware filesystem"); 63155131SrwatsonSYSCTL_INT(_vfs_nwfs, OID_AUTO, version, CTLFLAG_RD, &nwfs_version, 0, ""); 64155131SrwatsonSYSCTL_INT(_vfs_nwfs, OID_AUTO, debuglevel, CTLFLAG_RW, &nwfs_debuglevel, 0, ""); 65186647Srwatson 66155131SrwatsonMODULE_DEPEND(nwfs, ncp, 1, 1, 1); 67186647SrwatsonMODULE_DEPEND(nwfs, libmchain, 1, 1, 1); 68155131Srwatson 69155131Srwatsonstatic vfs_cmount_t nwfs_cmount; 70189279Srwatsonstatic vfs_mount_t nwfs_mount; 71189279Srwatsonstatic vfs_quotactl_t nwfs_quotactl; 72189279Srwatsonstatic vfs_root_t nwfs_root; 73243750Srwatsonstatic vfs_statfs_t nwfs_statfs; 74243750Srwatsonstatic vfs_unmount_t nwfs_unmount; 75189279Srwatsonstatic vfs_init_t nwfs_init; 76189279Srwatsonstatic vfs_uninit_t nwfs_uninit; 77189279Srwatson 78189279Srwatsonstatic struct vfsops nwfs_vfsops = { 79189279Srwatson .vfs_init = nwfs_init, 80189279Srwatson .vfs_mount = nwfs_mount, 81189279Srwatson .vfs_cmount = nwfs_cmount, 82189279Srwatson .vfs_quotactl = nwfs_quotactl, 83189279Srwatson .vfs_root = nwfs_root, 84189279Srwatson .vfs_statfs = nwfs_statfs, 85189279Srwatson .vfs_sync = vfs_stdsync, 86189279Srwatson .vfs_uninit = nwfs_uninit, 87189279Srwatson .vfs_unmount = nwfs_unmount, 88189279Srwatson}; 89189279Srwatson 90189279Srwatson 91189279SrwatsonVFS_SET(nwfs_vfsops, nwfs, VFCF_NETWORK); 92189279Srwatson 93189279Srwatsonint nwfs_pbuf_freecnt = -1; /* start out unlimited */ 94189279Srwatsonstatic int nwfsid = 1; 95189279Srwatson 96155131Srwatsonstatic int 97155131Srwatsonnwfs_initnls(struct nwmount *nmp) { 98155131Srwatson char *pc, *pe; 99155131Srwatson int error = 0; 100155131Srwatson#define COPY_TABLE(t,d) { \ 101155131Srwatson if (t) { \ 102243750Srwatson error = copyin((t), pc, 256); \ 103155131Srwatson if (error) break; \ 104155131Srwatson } else \ 105155131Srwatson bcopy(d, pc, 256); \ 106155131Srwatson (t) = pc; pc += 256; \ 107155131Srwatson } 108155131Srwatson 109155131Srwatson nmp->m.nls.opt |= NWHP_NLS | NWHP_DOS; 110155131Srwatson if ((nmp->m.flags & NWFS_MOUNT_HAVE_NLS) == 0) { 111155131Srwatson nmp->m.nls.to_lower = ncp_defnls.to_lower; 112155131Srwatson nmp->m.nls.to_upper = ncp_defnls.to_upper; 113155131Srwatson nmp->m.nls.n2u = ncp_defnls.n2u; 114155131Srwatson nmp->m.nls.u2n = ncp_defnls.u2n; 115155131Srwatson return 0; 116155131Srwatson } 117155131Srwatson MALLOC(pe, char *, 256 * 4, M_NWFSDATA, M_WAITOK); 118155131Srwatson pc = pe; 119155131Srwatson do { 120155131Srwatson COPY_TABLE(nmp->m.nls.to_lower, ncp_defnls.to_lower); 121155131Srwatson COPY_TABLE(nmp->m.nls.to_upper, ncp_defnls.to_upper); 122155131Srwatson COPY_TABLE(nmp->m.nls.n2u, ncp_defnls.n2u); 123195740Srwatson COPY_TABLE(nmp->m.nls.u2n, ncp_defnls.u2n); 124195740Srwatson } while(0); 125195740Srwatson if (error) { 126195740Srwatson free(pe, M_NWFSDATA); 127155131Srwatson return error; 128195740Srwatson } 129195740Srwatson return 0; 130155131Srwatson} 131155131Srwatson 132155131Srwatsonstatic int nwfs_cmount(struct mntarg *ma, void *data, int flags, 133155131Srwatson struct thread *td) 134155131Srwatson{ 135155131Srwatson struct nwfs_args args; /* will hold data from mount request */ 136155131Srwatson int error; 137155131Srwatson 138155131Srwatson error = copyin(data, &args, sizeof(struct nwfs_args)); 139155131Srwatson if (error) 140155131Srwatson return (error); 141155131Srwatson 142155131Srwatson /* 143155131Srwatson * XXX: cheap cop-out here, args contains a structure I don't 144155131Srwatson * XXX: know how we should handle, and I don't see any immediate 145155131Srwatson * XXX: prospect of avoiding a mount_nwfs(8) binary anyway. 146155131Srwatson */ 147189279Srwatson ma = mount_arg(ma, "nwfs_args", &args, sizeof args); 148189279Srwatson 149189279Srwatson error = kernel_mount(ma, flags); 150189279Srwatson 151189279Srwatson return (error); 152189279Srwatson} 153189279Srwatson 154189279Srwatson/* 155189279Srwatson * mp - path - addr in user space of mount point (ie /usr or whatever) 156189279Srwatson * data - addr in user space of mount params 157189279Srwatson */ 158189279Srwatsonstatic int nwfs_mount(struct mount *mp, struct thread *td) 159189279Srwatson{ 160189279Srwatson struct nwfs_args args; /* will hold data from mount request */ 161189279Srwatson int error; 162189279Srwatson struct nwmount *nmp = NULL; 163189279Srwatson struct ncp_conn *conn = NULL; 164189279Srwatson struct ncp_handle *handle = NULL; 165189279Srwatson struct vnode *vp; 166189279Srwatson char *pc,*pe; 167189279Srwatson 168189279Srwatson if (mp->mnt_flag & MNT_ROOTFS) 169189279Srwatson return (EOPNOTSUPP); 170189279Srwatson if (mp->mnt_flag & MNT_UPDATE) { 171189279Srwatson nwfs_printf("MNT_UPDATE not implemented"); 172189279Srwatson return (EOPNOTSUPP); 173189279Srwatson } 174189279Srwatson error = vfs_copyopt(mp->mnt_optnew, "nwfs_args", &args, sizeof args); 175189279Srwatson if (error) 176189279Srwatson return (error); 177189279Srwatson if (args.version != NWFS_VERSION) { 178189279Srwatson nwfs_printf("mount version mismatch: kernel=%d, mount=%d\n",NWFS_VERSION,args.version); 179189279Srwatson return (1); 180189279Srwatson } 181189279Srwatson error = ncp_conn_getbyref(args.connRef, td , td->td_ucred,NCPM_EXECUTE,&conn); 182189279Srwatson if (error) { 183189279Srwatson nwfs_printf("invalid connection refernce %d\n",args.connRef); 184189279Srwatson return (error); 185243750Srwatson } 186189279Srwatson error = ncp_conn_gethandle(conn, NULL, &handle); 187189279Srwatson if (error) { 188189279Srwatson nwfs_printf("can't get connection handle\n"); 189189279Srwatson return (error); 190189279Srwatson } 191189279Srwatson ncp_conn_unlock(conn, td); /* we keep the ref */ 192189279Srwatson mp->mnt_stat.f_iosize = conn->buffer_size; 193189279Srwatson /* We must malloc our own mount info */ 194189279Srwatson MALLOC(nmp,struct nwmount *,sizeof(struct nwmount),M_NWFSDATA, 195189279Srwatson M_WAITOK | M_USE_RESERVE | M_ZERO); 196189279Srwatson if (nmp == NULL) { 197189279Srwatson nwfs_printf("could not alloc nwmount\n"); 198189279Srwatson error = ENOMEM; 199189279Srwatson goto bad; 200189279Srwatson } 201189279Srwatson mp->mnt_data = (qaddr_t)nmp; 202189279Srwatson nmp->connh = handle; 203189279Srwatson nmp->n_root = NULL; 204189279Srwatson nmp->n_id = nwfsid++; 205189279Srwatson nmp->m = args; 206189279Srwatson nmp->m.file_mode = (nmp->m.file_mode & 207189279Srwatson (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG; 208189279Srwatson nmp->m.dir_mode = (nmp->m.dir_mode & 209189279Srwatson (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR; 210189279Srwatson if ((error = nwfs_initnls(nmp)) != 0) goto bad; 211189279Srwatson pc = mp->mnt_stat.f_mntfromname; 212189279Srwatson pe = pc+sizeof(mp->mnt_stat.f_mntfromname); 213189279Srwatson bzero(pc, MNAMELEN); 214189279Srwatson *(pc++) = '/'; 215189279Srwatson pc = index(strncpy(pc, conn->li.server, pe-pc-2),0); 216189279Srwatson if (pc < pe-1) { 217189279Srwatson *(pc++) = ':'; 218189279Srwatson pc=index(strncpy(pc, conn->li.user, pe-pc-2),0); 219189279Srwatson if (pc < pe-1) { 220189279Srwatson *(pc++) = '/'; 221189279Srwatson strncpy(pc, nmp->m.mounted_vol, pe-pc-2); 222189279Srwatson } 223162503Srwatson } 224162503Srwatson /* protect against invalid mount points */ 225162503Srwatson nmp->m.mount_point[sizeof(nmp->m.mount_point)-1] = '\0'; 226162503Srwatson vfs_getnewfsid(mp); 227162503Srwatson error = nwfs_root(mp, LK_EXCLUSIVE, &vp, td); 228191273Srwatson if (error) 229162503Srwatson goto bad; 230189279Srwatson /* 231189279Srwatson * Lose the lock but keep the ref. 232162503Srwatson */ 233162503Srwatson VOP_UNLOCK(vp, 0, curthread); 234162503Srwatson NCPVODEBUG("rootvp.vrefcnt=%d\n",vrefcnt(vp)); 235162503Srwatson return error; 236162503Srwatsonbad: 237189279Srwatson if (nmp) 238189279Srwatson free(nmp, M_NWFSDATA); 239189279Srwatson if (handle) 240162503Srwatson ncp_conn_puthandle(handle, NULL, 0); 241189279Srwatson return error; 242189279Srwatson} 243162503Srwatson 244189279Srwatson/* Unmount the filesystem described by mp. */ 245162503Srwatsonstatic int 246189279Srwatsonnwfs_unmount(struct mount *mp, int mntflags, struct thread *td) 247189279Srwatson{ 248162503Srwatson struct nwmount *nmp = VFSTONWFS(mp); 249162503Srwatson struct ncp_conn *conn; 250162503Srwatson int error, flags; 251162503Srwatson 252162503Srwatson NCPVODEBUG("nwfs_unmount: flags=%04x\n",mntflags); 253162503Srwatson flags = 0; 254162503Srwatson if (mntflags & MNT_FORCE) 255162503Srwatson flags |= FORCECLOSE; 256191273Srwatson /* There is 1 extra root vnode reference from nwfs_mount(). */ 257162503Srwatson error = vflush(mp, 1, flags, td); 258162503Srwatson if (error) 259162503Srwatson return (error); 260189279Srwatson conn = NWFSTOCONN(nmp); 261162503Srwatson ncp_conn_puthandle(nmp->connh,NULL,0); 262162503Srwatson if (ncp_conn_lock(conn, td, td->td_ucred,NCPM_WRITE | NCPM_EXECUTE) == 0) { 263162503Srwatson if(ncp_conn_free(conn)) 264162503Srwatson ncp_conn_unlock(conn, td); 265162503Srwatson } 266162503Srwatson mp->mnt_data = (qaddr_t)0; 267162503Srwatson if (nmp->m.flags & NWFS_MOUNT_HAVE_NLS) 268162503Srwatson free(nmp->m.nls.to_lower, M_NWFSDATA); 269189279Srwatson free(nmp, M_NWFSDATA); 270189279Srwatson MNT_ILOCK(mp); 271189279Srwatson mp->mnt_flag &= ~MNT_LOCAL; 272189279Srwatson MNT_IUNLOCK(mp); 273189279Srwatson return (error); 274189279Srwatson} 275189279Srwatson 276189279Srwatson/* Return locked vnode to root of a filesystem */ 277189279Srwatsonstatic int 278189279Srwatsonnwfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) { 279189279Srwatson struct vnode *vp; 280162503Srwatson struct nwmount *nmp; 281162503Srwatson struct nwnode *np; 282162503Srwatson struct ncp_conn *conn; 283162503Srwatson struct nw_entry_info fattr; 284162503Srwatson struct ucred *cred = td->td_ucred; 285162503Srwatson int error, nsf, opt; 286162503Srwatson u_char vol; 287162503Srwatson 288162503Srwatson nmp = VFSTONWFS(mp); 289162503Srwatson conn = NWFSTOCONN(nmp); 290155131Srwatson if (nmp->n_root) { 291155131Srwatson *vpp = NWTOV(nmp->n_root); 292162503Srwatson while (vget(*vpp, LK_EXCLUSIVE, curthread) != 0) 293162503Srwatson ; 294162503Srwatson return 0; 295191273Srwatson } 296191273Srwatson error = ncp_lookup_volume(conn, nmp->m.mounted_vol, &vol, 297162503Srwatson &nmp->n_rootent.f_id, td, cred); 298162503Srwatson if (error) 299191273Srwatson return ENOENT; 300191273Srwatson nmp->n_volume = vol; 301191273Srwatson error = ncp_get_namespaces(conn, vol, &nsf, td, cred); 302191273Srwatson if (error) 303191273Srwatson return ENOENT; 304191273Srwatson if (nsf & NW_NSB_OS2) { 305191273Srwatson NCPVODEBUG("volume %s has os2 namespace\n",nmp->m.mounted_vol); 306191273Srwatson if ((nmp->m.flags & NWFS_MOUNT_NO_OS2) == 0) { 307191273Srwatson nmp->name_space = NW_NS_OS2; 308191273Srwatson nmp->m.nls.opt &= ~NWHP_DOS; 309191273Srwatson } 310191273Srwatson } 311191273Srwatson opt = nmp->m.nls.opt; 312191273Srwatson nsf = opt & (NWHP_UPPER | NWHP_LOWER); 313191273Srwatson if (opt & NWHP_DOS) { 314162503Srwatson if (nsf == (NWHP_UPPER | NWHP_LOWER)) { 315191273Srwatson nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER); 316162503Srwatson } else if (nsf == 0) { 317162503Srwatson nmp->m.nls.opt |= NWHP_LOWER; 318155131Srwatson } 319155131Srwatson } else { 320155131Srwatson if (nsf == (NWHP_UPPER | NWHP_LOWER)) { 321155131Srwatson nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER); 322186647Srwatson } 323155131Srwatson } 324186647Srwatson if (nmp->m.root_path[0]) { 325162503Srwatson nmp->m.root_path[0]--; 326186647Srwatson error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, 327155131Srwatson -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred); 328186647Srwatson if (error) { 329155131Srwatson NCPFATAL("Invalid root path specified\n"); 330155131Srwatson return ENOENT; 331155131Srwatson } 332162503Srwatson nmp->n_rootent.f_parent = fattr.dirEntNum; 333155131Srwatson nmp->m.root_path[0]++; 334155131Srwatson error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, 335155131Srwatson -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred); 336155131Srwatson if (error) { 337155131Srwatson NCPFATAL("Invalid root path specified\n"); 338186647Srwatson return ENOENT; 339155131Srwatson } 340186647Srwatson nmp->n_rootent.f_id = fattr.dirEntNum; 341155131Srwatson } else { 342155131Srwatson error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, 343155131Srwatson 0, NULL, &fattr, td, cred); 344155131Srwatson if (error) { 345155131Srwatson NCPFATAL("Can't obtain volume info\n"); 346186647Srwatson return ENOENT; 347155131Srwatson } 348186647Srwatson fattr.nameLen = strlen(strcpy(fattr.entryName, "#.ROOT")); 349155131Srwatson nmp->n_rootent.f_parent = nmp->n_rootent.f_id; 350155131Srwatson } 351155131Srwatson error = nwfs_nget(mp, nmp->n_rootent, &fattr, NULL, &vp); 352155131Srwatson if (error) 353155131Srwatson return (error); 354155131Srwatson vp->v_vflag |= VV_ROOT; 355155131Srwatson np = VTONW(vp); 356155131Srwatson if (nmp->m.root_path[0] == 0) 357155131Srwatson np->n_flag |= NVOLUME; 358155131Srwatson nmp->n_root = np; 359155131Srwatson/* error = VOP_GETATTR(vp, &vattr, cred, td); 360155131Srwatson if (error) { 361162503Srwatson vput(vp); 362162503Srwatson NCPFATAL("Can't get root directory entry\n"); 363155131Srwatson return error; 364186647Srwatson }*/ 365162503Srwatson *vpp = vp; 366186647Srwatson return (0); 367155131Srwatson} 368155131Srwatson 369155131Srwatson/* 370155131Srwatson * Do operations associated with quotas, not supported 371155131Srwatson */ 372155131Srwatson/* ARGSUSED */ 373155131Srwatsonstatic int 374186647Srwatsonnwfs_quotactl(mp, cmd, uid, arg, td) 375155131Srwatson struct mount *mp; 376186647Srwatson int cmd; 377155131Srwatson uid_t uid; 378155131Srwatson void *arg; 379162503Srwatson struct thread *td; 380186647Srwatson{ 381162503Srwatson NCPVODEBUG("return EOPNOTSUPP\n"); 382186647Srwatson return (EOPNOTSUPP); 383155131Srwatson} 384162503Srwatson 385185573Srwatson/*ARGSUSED*/ 386186647Srwatsonint 387162503Srwatsonnwfs_init(struct vfsconf *vfsp) 388186647Srwatson{ 389155131Srwatson nwfs_hash_init(); 390162503Srwatson nwfs_pbuf_freecnt = nswbuf / 2 + 1; 391185573Srwatson NCPVODEBUG("always happy to load!\n"); 392186647Srwatson return (0); 393162503Srwatson} 394186647Srwatson 395155131Srwatson/*ARGSUSED*/ 396155131Srwatsonint 397155131Srwatsonnwfs_uninit(struct vfsconf *vfsp) 398155131Srwatson{ 399243750Srwatson 400243750Srwatson nwfs_hash_free(); 401243750Srwatson NCPVODEBUG("unloaded\n"); 402243750Srwatson return (0); 403243750Srwatson} 404243750Srwatson 405243750Srwatson/* 406243750Srwatson * nwfs_statfs call 407243750Srwatson */ 408243750Srwatsonint 409243750Srwatsonnwfs_statfs(mp, sbp, td) 410243750Srwatson struct mount *mp; 411243750Srwatson struct statfs *sbp; 412243750Srwatson struct thread *td; 413243750Srwatson{ 414243750Srwatson struct nwmount *nmp = VFSTONWFS(mp); 415243750Srwatson int error = 0, secsize; 416243750Srwatson struct nwnode *np = nmp->n_root; 417243750Srwatson struct ncp_volume_info vi; 418243750Srwatson 419243750Srwatson if (np == NULL) return EINVAL; 420243750Srwatson error = ncp_get_volume_info_with_number(NWFSTOCONN(nmp), 421243750Srwatson nmp->n_volume, &vi, td, td->td_ucred); 422243750Srwatson if (error) return error; 423243750Srwatson secsize = 512; /* XXX how to get real value ??? */ 424243750Srwatson /* fundamental filesystem block size */ 425243750Srwatson sbp->f_bsize = vi.sectors_per_block*secsize; 426243750Srwatson /* optimal transfer block size */ 427243750Srwatson sbp->f_iosize = NWFSTOCONN(nmp)->buffer_size; 428243750Srwatson /* total data blocks in filesystem */ 429243750Srwatson sbp->f_blocks= vi.total_blocks; 430243750Srwatson /* free blocks in fs */ 431243750Srwatson sbp->f_bfree = vi.free_blocks + vi.purgeable_blocks; 432243750Srwatson /* free blocks avail to non-superuser */ 433243750Srwatson sbp->f_bavail= vi.free_blocks+vi.purgeable_blocks; 434243750Srwatson /* total file nodes in filesystem */ 435243750Srwatson sbp->f_files = vi.total_dir_entries; 436162503Srwatson /* free file nodes in fs */ 437155131Srwatson sbp->f_ffree = vi.available_dir_entries; 438155131Srwatson sbp->f_flags = 0; /* copy of mount exported flags */ 439155131Srwatson return 0; 440155131Srwatson} 441155131Srwatson