📄 freebsd-3.2.il-kernel.patch
字号:
+ + /*+ * Flush and invalidate all dirty buffers. If another process is already+ * doing the flush, just wait for completion.+ */+ int+ u9fs_vinvalbuf(vp, flags, cred, p, intrflg)+ struct vnode *vp;+ int flags;+ struct ucred *cred;+ struct proc *p;+ int intrflg;+ {+ register struct u9fsnode *np = VTOU9FS(vp);+ struct u9fsmount *nmp = VFSTOU9FS(vp->v_mount);+ int error = 0, slpflag, slptimeo;+ + if (vp->v_flag & VXLOCK) {+ return (0);+ }+ + if ((nmp->nm_flag & U9FSMNT_INT) == 0)+ intrflg = 0;+ if (intrflg) {+ slpflag = PCATCH;+ slptimeo = 2 * hz;+ } else {+ slpflag = 0;+ slptimeo = 0;+ }+ /*+ * First wait for any other process doing a flush to complete.+ */+ while (np->n_flag & NFLUSHINPROG) {+ np->n_flag |= NFLUSHWANT;+ error = tsleep((caddr_t)&np->n_flag, PRIBIO + 2, "u9fsvinval",+ slptimeo);+ if (error && intrflg && u9fs_sigintr(nmp, p))+ return (EINTR);+ }+ + /*+ * Now, flush as required.+ */+ np->n_flag |= NFLUSHINPROG;+ error = vinvalbuf(vp, flags, cred, p, slpflag, 0);+ while (error) {+ if (intrflg && u9fs_sigintr(nmp, p)) {+ np->n_flag &= ~NFLUSHINPROG;+ if (np->n_flag & NFLUSHWANT) {+ np->n_flag &= ~NFLUSHWANT;+ wakeup((caddr_t)&np->n_flag);+ }+ return (EINTR);+ }+ error = vinvalbuf(vp, flags, cred, p, 0, slptimeo);+ }+ np->n_flag &= ~(NMODIFIED | NFLUSHINPROG);+ if (np->n_flag & NFLUSHWANT) {+ np->n_flag &= ~NFLUSHWANT;+ wakeup((caddr_t)&np->n_flag);+ }+ return (0);+ }+ diff -N -c -r /usr/src/sys/9fs/9fs_node.c ./9fs/9fs_node.c*** /usr/src/sys/9fs/9fs_node.c Wed Dec 31 19:00:00 1969--- ./9fs/9fs_node.c Thu Nov 25 15:36:49 1999****************** 0 ****--- 1,132 ----+ #include <sys/param.h>+ #include <sys/sockio.h>+ #include <sys/proc.h>+ #include <sys/vnode.h>+ #include <sys/kernel.h>+ #include <sys/sysctl.h>+ #include <sys/malloc.h>+ #include <sys/mount.h>+ #include <sys/mbuf.h>+ #include <sys/socket.h>+ #include <sys/socketvar.h>+ #include <sys/systm.h>+ #include <sys/protosw.h>+ #include <sys/syslog.h>+ + #include <netinet/in.h>+ #include <netinet/tcp.h>+ + #include <vm/vm.h>+ #include <vm/vm_extern.h>+ #include <vm/vm_zone.h>+ + #include <net/if.h>+ #include <net/route.h>+ #include <netinet/in.h>+ + #include <9fs/bitstring.h>+ #include <9fs/9p.h>+ #include <9fs/9auth.h>+ #include <9fs/9fs.h>+ + vm_zone_t u9fsnode_zone;+ static LIST_HEAD(u9fsnodehashhead, u9fsnode) *u9fsnodehashtbl;+ static u_long u9fsnodehash;+ MALLOC_DEFINE(M_U9FSHASH, "U9FS hash", "U9FS hash tables");+ + /*+ * Initialize hash links for u9fsnodes+ * and build u9fsnode free list.+ */+ void+ u9fs_nhinit()+ {+ u9fsnode_zone = zinit("U9FSNODE", sizeof(struct u9fsnode), 0, 0, 1);+ u9fsnodehashtbl = phashinit(desiredvnodes, M_U9FSHASH, &u9fsnodehash);+ }+ + /*+ * Look up a vnode/u9fsnode by file handle.+ * Callers must check for mount points!!+ * In all cases, a pointer to a+ * u9fsnode structure is returned.+ */+ static int u9fs_node_hash_lock;+ + int+ u9fs_nget(mntp, fh, npp, p)+ struct mount *mntp;+ register u9fsfh_t fh;+ struct u9fsnode **npp;+ struct proc * p;+ {+ struct u9fsnode *np;+ struct u9fsnodehashhead *nhpp;+ register struct vnode *vp;+ struct vnode *nvp;+ int error;+ + nhpp = U9FSNOHASH(fh);+ loop:+ for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {+ if (mntp != U9FSTOV(np)->v_mount || fh != np->n_qid.path )+ continue;+ vp = U9FSTOV(np);+ if (vget(vp, LK_EXCLUSIVE, p))+ goto loop;+ *npp = np;+ return(0);+ }+ /*+ * Obtain a lock to prevent a race condition if the getnewvnode()+ * or MALLOC() below happens to block.+ */+ if (u9fs_node_hash_lock) {+ while (u9fs_node_hash_lock) {+ u9fs_node_hash_lock = -1;+ tsleep(&u9fs_node_hash_lock, PVM, "u9fsngt", 0);+ }+ goto loop;+ }+ u9fs_node_hash_lock = 1;+ + /*+ * allocate before getnewvnode since doing so afterward+ * might cause a bogus v_data pointer to get dereferenced+ * elsewhere if zalloc should block.+ */+ np = zalloc(u9fsnode_zone);+ + error = getnewvnode(VT_U9FS, mntp, u9fs_vnodeop_p, &nvp);+ if (error) {+ if (u9fs_node_hash_lock < 0)+ wakeup(&u9fs_node_hash_lock);+ u9fs_node_hash_lock = 0;+ *npp = 0;+ zfree(u9fsnode_zone, np);+ return (error);+ }+ vp = nvp;+ bzero((caddr_t)np, sizeof *np);+ vp->v_data = np;+ np->n_vnode = vp;+ /*+ * Insert the u9fsnode in the hash queue for its new file handle+ */+ LIST_INSERT_HEAD(nhpp, np, n_hash);+ np->n_qid.path = fh;+ np->n_qid.vers = 0; /* not in cache yet */+ np->n_fid = 0; /* should be set by the caller */+ *npp = np;+ + if (u9fs_node_hash_lock < 0)+ wakeup(&u9fs_node_hash_lock);+ u9fs_node_hash_lock = 0;+ + /*+ * Lock the new u9fsnode.+ */+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);+ + return (0);+ }diff -N -c -r /usr/src/sys/9fs/9fs_socket.c ./9fs/9fs_socket.c*** /usr/src/sys/9fs/9fs_socket.c Wed Dec 31 19:00:00 1969--- ./9fs/9fs_socket.c Thu Nov 25 15:48:46 1999****************** 0 ****--- 1,503 ----+ #include <sys/param.h>+ #include <sys/sockio.h>+ #include <sys/proc.h>+ #include <sys/vnode.h>+ #include <sys/kernel.h>+ #include <sys/sysctl.h>+ #include <sys/malloc.h>+ #include <sys/mount.h>+ #include <sys/mbuf.h>+ #include <sys/socket.h>+ #include <sys/socketvar.h>+ #include <sys/systm.h>+ #include <sys/protosw.h>+ #include <sys/syslog.h>+ + #include <netinet/in.h>+ #include <netinet/tcp.h>+ + #include <vm/vm.h>+ #include <vm/vm_extern.h>+ #include <vm/vm_zone.h>+ + #include <net/if.h>+ #include <net/route.h>+ #include <netinet/in.h>+ + #include <9fs/bitstring.h>+ #include <9fs/9p.h>+ #include <9fs/9auth.h>+ #include <9fs/9fs.h>+ + static int u9fs_reply __P((struct u9fsreq * req));+ static int u9fs_send __P((struct socket * so, struct mbuf * mreq, struct u9fsreq * req));+ static int u9fs_receive __P((struct socket * so, struct mbuf **mrep, struct u9fsreq * req));+ + static int u9fs_sndlock __P((int *flagp, int *statep, struct u9fsreq *rep));+ static void u9fs_sndunlock __P((int *flagp, int *statep));+ static int u9fs_rcvlock __P((struct u9fsreq *req));+ static void u9fs_rcvunlock __P((int *flagp, int *statep));+ + int+ u9fs_connect(struct socket ** sop, struct sockaddr * saddr, int sotype, int soproto, struct proc * p)+ {+ register struct socket * so;+ int error, s;+ + *sop = 0;+ error = socreate(saddr->sa_family, sop, sotype, soproto, p);+ if( error )+ return error;+ so = *sop;+ error = soconnect(so, saddr, p);+ if( error )+ return error;+ + /*+ * Wait for the connection to complete. Cribbed from the+ * connect system call but with the wait timing out so+ * that interruptible mounts don't hang here for a long time.+ */+ s = splnet();+ while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)+ (void) tsleep((caddr_t)&so->so_timeo, PSOCK,+ "u9fscon", 2 * hz);+ + if (so->so_error) {+ error = so->so_error;+ so->so_error = 0;+ splx(s);+ return error;+ }+ splx(s);+ + return (0);+ }+ + int u9fs_connect_9auth(struct u9fsmount * nmp, struct u9fs_args * argp, struct socket ** sop)+ {+ int error;+ struct proc * p = & proc0;+ struct sockaddr *nam;+ + error = getsockaddr(&nam, (caddr_t)argp->authaddr, argp->authaddrlen);+ if( error )+ return error;+ error = u9fs_connect(sop, nam, argp->authsotype, + argp->authsoproto, p);+ if( error == 0 )+ return 0;+ + u9fs_disconnect(*sop);+ *sop = 0;+ return error;+ }+ + /*+ * Initialize sockets and congestion for a new U9FS connection.+ * We do not free the sockaddr if error.+ */+ int+ u9fs_connect_9fs(nmp)+ register struct u9fsmount *nmp;+ {+ register struct socket *so;+ int error, rcvreserve, sndreserve;+ struct proc *p = &proc0; /* only used for socreate and sobind */+ + error = u9fs_connect(&nmp->nm_so, nmp->nm_nam, nmp->nm_sotype, + nmp->nm_soproto, p);+ if (error)+ goto bad;+ so = nmp->nm_so;+ nmp->nm_soflags = so->so_proto->pr_flags;+ + if (nmp->nm_flag & (U9FSMNT_SOFT | U9FSMNT_INT)) {+ so->so_rcv.sb_timeo = (5 * hz);+ so->so_snd.sb_timeo = (5 * hz);+ } else {+ so->so_rcv.sb_timeo = 0;+ so->so_snd.sb_timeo = 0;+ }+ + /* XXX: i dont understand this, only one outstanding request? */+ if (nmp->nm_sotype == SOCK_SEQPACKET) {+ sndreserve = (nmp->nm_wsize) * 2;+ rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize)) * 2;+ } else {+ if (nmp->nm_sotype != SOCK_STREAM)+ panic("u9fscon sotype");+ if (so->so_proto->pr_flags & PR_CONNREQUIRED) {+ struct sockopt sopt;+ int val;+ + bzero(&sopt, sizeof sopt);+ sopt.sopt_level = SOL_SOCKET;+ sopt.sopt_name = SO_KEEPALIVE;+ sopt.sopt_val = &val;+ sopt.sopt_valsize = sizeof val;+ val = 1;+ sosetopt(so, &sopt);+ }+ if (so->so_proto->pr_protocol == IPPROTO_TCP) {+ struct sockopt sopt;+ int val;+ + bzero(&sopt, sizeof sopt);+ sopt.sopt_level = IPPROTO_TCP;+ sopt.sopt_name = TCP_NODELAY;+ sopt.sopt_val = &val;+ sopt.sopt_valsize = sizeof val;+ val = 1;+ sosetopt(so, &sopt);+ }+ sndreserve = (nmp->nm_wsize) * 2;+ rcvreserve = (nmp->nm_rsize) * 2;+ }+ error = soreserve(so, sndreserve, rcvreserve);+ if (error)+ goto bad;+ so->so_rcv.sb_flags |= SB_NOINTR;+ so->so_snd.sb_flags |= SB_NOINTR;+ + /* Initialize other non-zero congestion variables */+ nmp->nm_sent = 0;+ return (0);+ + bad:+ u9fs_disconnect(nmp->nm_so);+ nmp->nm_so = 0;+ return (error);+ }+ + /*+ * U9FS disconnect. Clean up and unlink.+ */+ void+ u9fs_disconnect(struct socket * so)+ {+ soshutdown(so, 2);+ soclose(so);+ }+ + /*+ * Lock a socket against others.+ * Necessary for STREAM sockets to ensure you get an entire rpc request/reply+ * and also to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -