📄 nfs_vfsops.c
字号:
#ifndef lintstatic char *sccsid = "@(#)nfs_vfsops.c 4.5 (ULTRIX) 4/25/91";#endif lint/************************************************************************ * * * Copyright (c) 1986, 1987 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * Portions of this software have been licensed to * Digital Equipment Company, Maynard, MA. * Copyright (c) 1986 Sun Microsystems, Inc. ALL RIGHTS RESERVED. *//* * * Modification history: * * 08 Mar 91 -- dws * Initialize root credential in callrpc(). * * 28 Feb 91 -- dws * Cleaned up client view of fhandle. * * 27 Feb 91 -- chet * Fix filesystem timestamping. * * 9 Mar 89 -- chet * Use NFS_MAXDATA for local blocksize, not what server sends. * * 13 Dec 89 -- chet * Add attribute cache timeout values. * * 10 Dec 89 -- chet * Remove server permanent Arp table entry stuff in nfs_mount(). * * 25 Jul 89 -- chet * Add NFS type synchronous filesystems * * 13 Jun 89 -- condylis * Added locking around calls to getpdev(). * * 09 Feb 89 -- prs * Modified nfs_statfs to return file system stats in 1K * denominations. * * 12 Jan 88 Fred Glover * Add nfs_rlock function for sys-V file lock support. * * 12-11-87 Robin L. and Larry C. and Ricky P. * Added new kmalloc memory allocation to system. * * 29 Oct 87 -- chet * make check_mountp() error leg in nfs_mount * go through error code before return * * 24 Aug 87 -- logcher * Removed VROOT. Overlaps with existing gnode flag, and root * busy check is already performed in GFS. * * 20 Jul 87 -- logcher * Added bzero to nfs_mountroot for fhandle stuffing. * * 11 May 87 -- chet * Remove nfs_statfs() hack for hanging getmnt() stats. * * 28 Apr 87 -- chet * Removed meaningless mount table option flags (M_SYNC, M_FORCE). * Fixed spurious "bad arp" nfs_mount error message. * * 02-Mar-87 -- logcher * Merged in diskless changes, added support for specfs, * added ability to mount an NFS filesystem as the root filesystem */#include "../h/param.h"#include "../h/systm.h"#include "../h/user.h"#include "../h/uio.h"#include "../h/fs_types.h"#include "../h/mount.h"#include "../h/socket.h"#include "../h/fs_types.h"#include "../h/ioctl.h"#include "../h/smp_lock.h"#include "../net/net/if.h"#include "../net/netinet/in.h"#include "../net/rpc/types.h"#include "../net/rpc/xdr.h"#include "../net/rpc/auth.h"#include "../net/rpc/clnt.h"#include "../net/rpc/pmap_prot.h"#ifdef NFSDEBUG#define NFSSERVER#endif#include "../nfs/nfs.h"#include "../nfs/nfs_gfs.h"#include "../nfs/nfs_clnt.h"#include "../nfs/vfs.h"#include "../nfs/vnode.h"#include "../net/rpcsvc/mount.h"#include "../sas/mop.h"#ifdef NFSDEBUGextern int nfsdebug;#endifstruct vnode *makenfsnode();int nfsmntno;extern struct lock_t lk_mount_table;/* * nfs vfs operations. */struct mount *nfs_mount();int nfs_statfs();int nfs_match(), nfs_ginit(), nfs_inactive();int nfs_umount(), nfs_sbupdate();struct gnode *ufs_gget(), *nfs_namei();int nfs_glink(), nfs_unlink(), nfs_grmdir();struct gnode *nfs_gmkdir();struct gnode *nfs_makenode();int nfs_grename(), nfs_readdir();int nfs_rele();struct gnode *ufs_galloc();int nfs_syncgp(), ufs_gfree(), nfs_trunc();int nfs_rwgp(), nfs_stat();int nfs_lock(), nfs_unlock();int nfs_gupdat(), nfs_open();int nfs_close(), nfs_getval();int nfs_select(), nfs_greadlink(), nfs_gsymlink();struct fs_data *nfs_getfsdata();int ufs_fcntl(), nfs_gbmap();int ufs_seek();int nfs_rlock();extern nfs_strategy();struct mount_ops NFS_mount_ops = { nfs_umount, nfs_sbupdate, nfs_ginit, nfs_match, nfs_ginit, /* move to mount_ops */ nfs_inactive, nfs_getfsdata,};struct gnode_ops NFS_gnode_ops = { nfs_namei, nfs_glink, nfs_unlink, nfs_gmkdir, nfs_grmdir, nfs_makenode, nfs_grename, nfs_readdir, nfs_rele, nfs_syncgp, nfs_trunc, nfs_getval, nfs_rwgp, nfs_rlock, ufs_seek, /* seek */ nfs_stat, nfs_lock, nfs_unlock, nfs_gupdat, nfs_open, nfs_close, nfs_select, nfs_greadlink, nfs_gsymlink, 0, /* fcntl */ 0, nfs_gbmap};struct mount_ops *nfs_mount_ops = &NFS_mount_ops;struct gnode_ops *nfs_gnode_ops = &NFS_gnode_ops;/* * nfs_mount is called from the generic mount system call */struct mount *nfs_mount(special, path, flag, mp, ops)caddr_t special;caddr_t path;int flag;struct mount *mp;struct nfs_gfs_mount *ops;{ struct vnode *rootvp = NULL; /* root vnode */ struct vfs *vfsp; /* nfs vfs handle */ struct mntinfo *mi; /* mount info, pointed at by vfs */ struct vattr va; /* root vnode attributes */ struct nfsfattr na; /* root vnode attributes in nfs form */ struct nfs_gfs_mount nfs_gfs_mount; struct nfs_gfs_mount *ngp = &nfs_gfs_mount; struct statfs sb; /* server's file system stats */ fhandle_t fh; dev_t tdev;#ifdef NFSDEBUG dprint(nfsdebug, 4, "nfs_mount: special=%s, path=%s, flag=%d\n", special, path, flag); dprint(nfsdebug, 4, "nfs_mount: mp = 0x%x, ops = 0x%x\n", mp, ops);#endif /* * Copy NFS mount arguments out of userspace */ u.u_error = copyin((caddr_t)ops, (caddr_t)ngp, sizeof(nfs_gfs_mount)); if (u.u_error) goto error; /* * Set up data structures in fsdata spare area */ mi = MP_TO_MIP(mp); vfsp = MP_TO_VFSP(mp); mp->m_bufp = (struct buf *) (NODEV); /* to reserve this slot */ smp_lock(&lk_mount_table, LK_RETRY); if (!(tdev = getpdev())) { /* pseudo-device number */ smp_unlock(&lk_mount_table); u.u_error = EBUSY; goto error; } mp->m_dev = tdev; smp_unlock(&lk_mount_table); mp->iostrat = nfs_strategy; /* set it immediately */ mp->m_ops = nfs_mount_ops; mp->m_fstype = GT_NFS; mp->m_flags = (flag ? M_RONLY : 0); mp->m_flags |= (ngp->gfs_flags & (M_NOEXEC | M_NOSUID | M_NODEV | M_SYNC)); if (ngp->flags & NFSMNT_PGTHRESH) { int pg_thresh = ngp->pg_thresh * 1024; mp->m_fs_data->fd_pgthresh = clrnd(btoc((pg_thresh > MINPGTHRESH) ? pg_thresh : MINPGTHRESH)); } else { mp->m_fs_data->fd_pgthresh = clrnd(btoc(MINPGTHRESH * 8)); } u.u_error = copyin((caddr_t)ngp->fh, (caddr_t)&fh, sizeof(fh)); if (u.u_error) goto error; u.u_error = copyin((caddr_t)ngp->addr, (caddr_t)(&mi->mi_addr), sizeof(mi->mi_addr)); if (u.u_error) goto error; if (!(ngp->flags & NFSMNT_HOSTNAME)) /* XXX */ addr_to_str(&(mi->mi_addr), mi->mi_hostname); else { u.u_error = copyinstr(ngp->hostname, mi->mi_hostname, HOSTNAMESZ, (caddr_t)0); if (u.u_error) goto error; } if (ngp->optstr) { u.u_error = copyinstr(ngp->optstr, mi->mi_optstr, MNTMAXSTR, (caddr_t)0); if (u.u_error) goto error; }#ifdef NFSDEBUG dprint(nfsdebug, 4, "nfs_mount: saddr 0x%x, fh dev 0x%x gno %d\n", &(mi->mi_addr), fh.fh_fsid, fh.fh_fno);#endif /* * Create a mount record */ mi->mi_refct = 0; mi->mi_stsize = 0; mi->mi_hard = ((ngp->flags & NFSMNT_SOFT) == 0); mi->mi_int = ((ngp->flags & NFSMNT_INT) == NFSMNT_INT); mi->mi_noac = ((ngp->flags & NFSMNT_NOAC) == NFSMNT_NOAC); if (!mi->mi_noac) { mi->mi_acregmin = ngp->acregmin; mi->mi_acregmax = ngp->acregmax; mi->mi_acdirmin = ngp->acdirmin; mi->mi_acdirmax = ngp->acdirmax; } if (ngp->flags & NFSMNT_RETRANS) { mi->mi_retrans = ngp->retrans; if (ngp->retrans < 0) { u.u_error = EINVAL; goto error; } } else { mi->mi_retrans = NFS_RETRIES; } if (ngp->flags & NFSMNT_TIMEO) { mi->mi_timeo = ngp->timeo; if (ngp->timeo <= 0) { u.u_error = EINVAL; goto error; } } else { mi->mi_timeo = NFS_TIMEO; } mi->mi_mntno = nfsmntno++; mi->mi_printed = 0;#ifdef NFSDEBUG dprint(nfsdebug, 4, "nfs_mount: mi_addr 0x%x port %d addr 0x%x\n", &mi->mi_addr, mi->mi_addr.sin_port, (int)mi->mi_addr.sin_addr.s_addr);#endif /* * For now we just support AF_INET */ if (mi->mi_addr.sin_family != AF_INET) { u.u_error = EPFNOSUPPORT; goto error; } /* * Make a vfs struct for nfs. We do this here instead of below * because rootvp needs a vfs before we can do a getattr on it. */ VFS_INIT(vfsp, (caddr_t)mi); /* * Make the root vnode */ rootvp = makenfsnode(&fh, (struct nfsfattr *) 0, vfsp, mp); if(rootvp == NULL) { goto error; } /* * Get real attributes of the root vnode, and remake it. * While we're at it, get the transfer size for this filesystem. */ u.u_error = nfs_makeroot(&fh, &rootvp); if (u.u_error) { goto error; } mp->m_rootgp = (struct gnode *) rootvp; mi->mi_rootvp = rootvp; if(u.u_uid) { ((struct gnode *) rootvp)->g_uid = u.u_uid; ((struct gnode *) rootvp)->g_flag |= GCHG; } /* * Get server's filesystem stats. Use these to set transfer sizes */ mi->mi_tsize = min(NFS_MAXDATA, nfstsize()); if (ngp->flags & NFSMNT_RSIZE) { if (ngp->rsize <= 0) { u.u_error = EINVAL; goto error; } mi->mi_tsize = MIN(mi->mi_tsize, ngp->rsize); } if (ngp->flags & NFSMNT_WSIZE) { if (ngp->wsize <= 0) { u.u_error = EINVAL; goto error; } mi->mi_stsize = ngp->wsize; /* touched by nfs_getfsdata */ } (void) nfs_getfsdata(mp); if (u.u_error) goto error;#ifdef NFSDEBUG dprint(nfsdebug, 10, "nfs_mount: vfs %x: vnodecov = %x, data = %x\n", vfsp, vfsp->vfs_vnodecovered, vfsp->vfs_data); dprint(nfsdebug, 10, "rootvp %x: vfs %x\n", rootvp, rootvp->v_vfsp); dprint(nfsdebug, 4, "nfs_mount: hard %d timeo %d retries %d wsize %d rsize %d\n", mi->mi_hard, mi->mi_timeo, mi->mi_retrans, mi->mi_stsize, mi->mi_tsize); dprint(nfsdebug, 4, "nfs_mount: mp->m_flags = 0x%x\n", mp->m_flags); dprint(nfsdebug, 4, "nfs_mount: fd_otsize = %d, fd_mtsize=%d\n", mp->m_fs_data->fd_otsize, mp->m_fs_data->fd_mtsize);#endif /* * Should set read only here! */ mi->mi_bsize = NFS_MAXDATA; vfsp->vfs_bsize = mi->mi_bsize; mp->m_bsize = mi->mi_bsize;#ifdef NFSDEBUG dprint(nfsdebug, 4, "nfs_mount: vfs_bsize %d\n", vfsp->vfs_bsize);#endif dnlc_purge(); /* * check_mountp will verify local mount point exists and is * ok to mount on. */ if (!(check_mountp(mp, path))) goto error; return(mp);error:#ifdef NFSDEBUG dprint(nfsdebug, 4, "nfs_mount: returning error, %d\n", u.u_error);#endif if (rootvp) { VN_RELE(rootvp); } return((struct mount *)NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -