You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(42) |
Sep
(42) |
Oct
(63) |
Nov
(79) |
Dec
(21) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(36) |
Feb
(36) |
Mar
(46) |
Apr
(2) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(23) |
Nov
(18) |
Dec
|
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(22) |
Dec
(41) |
2005 |
Jan
(15) |
Feb
(52) |
Mar
(57) |
Apr
(48) |
May
(48) |
Jun
(40) |
Jul
(4) |
Aug
(5) |
Sep
(6) |
Oct
|
Nov
(2) |
Dec
(3) |
2006 |
Jan
(8) |
Feb
(6) |
Mar
(11) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
2007 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
From: Eric V. H. <er...@us...> - 2009-08-17 18:31:06
|
Update of /cvsroot/v9fs/doc/rfc In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv11386 Modified Files: README Log Message: Update README to point to github as the authoritative source. Index: README =================================================================== RCS file: /cvsroot/v9fs/doc/rfc/README,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** README 12 Nov 2004 17:49:33 -0000 1.1.1.1 --- README 17 Aug 2009 18:30:55 -0000 1.2 *************** *** 1,9 **** ! This is for development of standards-track RFCs for 9P. At the present ! 3 RFC drafts are planned: ! ! 9P1 - documenting classic 9P ! 9P2000 - current 9P2000 standard ! 9P2000.u - unix extensions to 9P2000 ! ! People interested in helping write these suckers should look at ! RFC2223 (Instructions to RFC Authors) and RFC2360 (Best Current Practices). --- 1,2 ---- ! OBSOLETE: For updates to the protocol PLEASE reference ! http://github.com/ericvh/9p-rfc |
From: Eric V. H. <er...@us...> - 2009-08-17 18:30:09
|
Update of /cvsroot/v9fs/doc/rfc In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv11112 Modified Files: 9p2000.u.html 9p2000.u.nr 9p2000.u.txt 9p2000.u.xml Log Message: Updates from Abhishek to make RFC match current implementation Index: 9p2000.u.html =================================================================== RCS file: /cvsroot/v9fs/doc/rfc/9p2000.u.html,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** 9p2000.u.html 22 Nov 2005 14:27:05 -0000 1.3 --- 9p2000.u.html 17 Aug 2009 18:29:55 -0000 1.4 *************** *** 1,3 **** - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="en"><head><title>Plan 9 Remote Resource Protocol Unix Extension</title> --- 1,2 ---- *************** *** 5,138 **** <meta name="description" content="Plan 9 Remote Resource Protocol Unix Extension"> <meta name="keywords" content="Plan 9, 9P2000, 9P2000.u, v9fs, 9P"> ! <meta name="generator" content="xml2rfc v1.30 (http://xml.resource.org/)"> ! <style type='text/css'> ! <!-- ! body { ! font-family: verdana, charcoal, helvetica, arial, sans-serif; ! margin: 2em; ! font-size: small ; color: #000000 ; background-color: #ffffff ; } ! .title { color: #990000; font-size: x-large ; ! font-weight: bold; text-align: right; ! font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif; ! background-color: transparent; } ! .filename { color: #666666; font-size: 18px; line-height: 28px; ! font-weight: bold; text-align: right; ! font-family: helvetica, arial, sans-serif; ! background-color: transparent; } ! td.rfcbug { background-color: #000000 ; width: 30px ; height: 30px ; ! text-align: justify; vertical-align: middle ; padding-top: 2px ; } ! td.rfcbug span.RFC { color: #666666; font-weight: bold; text-decoration: none; ! background-color: #000000 ; ! font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif; ! font-size: x-small ; } ! td.rfcbug span.hotText { color: #ffffff; font-weight: normal; text-decoration: none; ! text-align: center ; ! font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif; ! font-size: x-small ; background-color: #000000; } ! /* info code from SantaKlauss at http://www.madaboutstyle.com/tooltip2.html */ ! div#counter{margin-top: 100px} ! ! a.info{ ! position:relative; /*this is the key*/ ! z-index:24; ! text-decoration:none} ! ! a.info:hover{z-index:25; background-color:#990000 ; color: #ffffff ;} ! a.info span{display: none} ! a.info:hover span.info{ /*the span will display just on :hover state*/ ! display:block; ! position:absolute; ! font-size: smaller ; ! top:2em; left:2em; width:15em; ! padding: 2px ; ! border:1px solid #333333; ! background-color:#eeeeee; color:#990000; ! text-align: left ;} ! A { font-weight: bold; } ! A:link { color: #990000; background-color: transparent ; } ! A:visited { color: #333333; background-color: transparent ; } ! A:active { color: #333333; background-color: transparent ; } ! p { margin-left: 2em; margin-right: 2em; } ! p.copyright { font-size: x-small ; } ! p.toc { font-size: small ; font-weight: bold ; margin-left: 3em ;} ! table.toc { margin: 0 0 0 3em; padding: 0; border: 0; vertical-align: text-top; } ! td.toc { font-size: small; font-weight: bold; vertical-align: text-top; } ! span.emph { font-style: italic; } ! span.strong { font-weight: bold; } ! span.verb, span.vbare { font-family: "Courier New", Courier, monospace ; } ! span.vemph { font-style: italic; font-family: "Courier New", Courier, monospace ; } ! span.vstrong { font-weight: bold; font-family: "Courier New", Courier, monospace ; } ! span.vdeluxe { font-weight: bold; font-style: italic; font-family: "Courier New", Courier, monospace ; } ! ol.text { margin-left: 2em; margin-right: 2em; } ! ul.text { margin-left: 2em; margin-right: 2em; } ! li { margin-left: 3em; } ! pre { margin-left: 3em; color: #333333; background-color: transparent; ! font-family: "Courier New", Courier, monospace ; font-size: small ; ! text-align: left; } ! h3 { color: #333333; font-size: medium ; ! font-family: helvetica, arial, sans-serif ; ! background-color: transparent; } ! h4 { font-size: small; font-family: helvetica, arial, sans-serif ; } ! ! table.bug { width: 30px ; height: 15px ; } ! td.bug { color: #ffffff ; background-color: #990000 ; ! text-align: center ; width: 30px ; height: 15px ; ! } ! td.bug A.link2 { color: #ffffff ; font-weight: bold; ! text-decoration: none; ! font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif; ! font-size: x-small ; background-color: transparent } ! ! td.header { color: #ffffff; font-size: x-small ; ! font-family: arial, helvetica, sans-serif; vertical-align: top; ! background-color: #666666 ; width: 33% ; } ! td.author { font-weight: bold; margin-left: 4em; font-size: x-small ; } ! td.author-text { font-size: x-small; } ! table.full { vertical-align: top ; border-collapse: collapse ; ! border-style: solid solid solid solid ; ! border-color: black black black black ; ! font-size: small ; text-align: center ; } ! table.headers, table.none { vertical-align: top ; border-collapse: collapse ; ! border-style: none; ! font-size: small ; text-align: center ; } ! table.full th { font-weight: bold ; ! border-style: solid ; ! border-color: black black black black ; } ! table.headers th { font-weight: bold ; ! border-style: none none solid none; ! border-color: black black black black ; } ! table.none th { font-weight: bold ; ! border-style: none; } ! table.full td { ! border-style: solid solid solid solid ; ! border-color: #333333 #333333 #333333 #333333 ; } ! table.headers td, table.none td { border-style: none; } ! hr { height: 1px } ! --> ! </style> </head> <body> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> <table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1"> <tr><td class="header">Network Working Group</td><td class="header">E. Van Hensbergen</td></tr> <tr><td class="header">Internet-Draft</td><td class="header">Plan 9 Fans</td></tr> <tr><td class="header">Updates:</td><td class="header">March 2005</td></tr> ! <tr><td class="header"><a href='ftp://ftp.isi.edu/in-notes/rfcexperimental-draft-9P2000-protocol.txt'>experimental-draft-9P2000-protocol</a></td><td class="header"> </td></tr> ! <tr><td class="header"><a href='ftp://ftp.isi.edu/in-notes/rfc(if approved).txt'>(if approved)</a></td><td class="header"> </td></tr> <tr><td class="header">Expires: September 2, 2005</td><td class="header"> </td></tr> </table></td></tr></table> ! <div align="right"><span class="title"><br />Plan 9 Remote Resource Protocol Unix Extension</span></div> ! <div align="right"><span class="title"><br />experimental-draft-9P2000-unix-extension</span></div> <h3>Status of this Memo</h3> --- 4,155 ---- <meta name="description" content="Plan 9 Remote Resource Protocol Unix Extension"> <meta name="keywords" content="Plan 9, 9P2000, 9P2000.u, v9fs, 9P"> ! <meta name="generator" content="xml2rfc v1.33 (http://xml.resource.org/)"> ! <style type='text/css'><!-- ! body { ! font-family: verdana, charcoal, helvetica, arial, sans-serif; ! font-size: small; color: #000; background-color: #FFF; ! margin: 2em; ! } ! h1, h2, h3, h4, h5, h6 { ! font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif; ! font-weight: bold; font-style: normal; ! } ! h1 { color: #900; background-color: transparent; text-align: right; } ! h3 { color: #333; background-color: transparent; } ! td.RFCbug { ! font-size: x-small; text-decoration: none; ! width: 30px; height: 30px; padding-top: 2px; ! text-align: justify; vertical-align: middle; ! background-color: #000; ! } ! td.RFCbug span.RFC { ! font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif; ! font-weight: bold; color: #666; ! } ! td.RFCbug span.hotText { ! font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif; ! font-weight: normal; text-align: center; color: #FFF; ! } ! table.TOCbug { width: 30px; height: 15px; } ! td.TOCbug { ! text-align: center; width: 30px; height: 15px; ! color: #FFF; background-color: #900; ! } ! td.TOCbug a { ! font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif; ! font-weight: bold; font-size: x-small; text-decoration: none; ! color: #FFF; background-color: transparent; ! } ! td.header { ! font-family: arial, helvetica, sans-serif; font-size: x-small; ! vertical-align: top; width: 33%; ! color: #FFF; background-color: #666; ! } ! td.author { font-weight: bold; font-size: x-small; margin-left: 4em; } ! td.author-text { font-size: x-small; } ! /* info code from SantaKlauss at http://www.madaboutstyle.com/tooltip2.html */ ! a.info { ! /* This is the key. */ ! position: relative; ! z-index: 24; ! text-decoration: none; ! } ! a.info:hover { ! z-index: 25; ! color: #FFF; background-color: #900; ! } ! a.info span { display: none; } ! a.info:hover span.info { ! /* The span will display just on :hover state. */ ! display: block; ! position: absolute; ! font-size: smaller; ! top: 2em; left: -5em; width: 15em; ! padding: 2px; border: 1px solid #333; ! color: #900; background-color: #EEE; ! text-align: left; ! } ! a { font-weight: bold; } ! a:link { color: #900; background-color: transparent; } ! a:visited { color: #633; background-color: transparent; } ! a:active { color: #633; background-color: transparent; } ! p { margin-left: 2em; margin-right: 2em; } ! p.copyright { font-size: x-small; } ! p.toc { font-size: small; font-weight: bold; margin-left: 3em; } ! table.toc { margin: 0 0 0 3em; padding: 0; border: 0; vertical-align: text-top; } ! td.toc { font-size: small; font-weight: bold; vertical-align: text-top; } ! ol.text { margin-left: 2em; margin-right: 2em; } ! ul.text { margin-left: 2em; margin-right: 2em; } ! li { margin-left: 3em; } ! /* RFC-2629 <spanx>s and <artwork>s. */ ! em { font-style: italic; } ! strong { font-weight: bold; } ! dfn { font-weight: bold; font-style: normal; } ! cite { font-weight: normal; font-style: normal; } ! tt { color: #036; } ! tt, pre, pre dfn, pre em, pre cite, pre span { ! font-family: "Courier New", Courier, monospace; font-size: small; } + pre { + text-align: left; padding: 4px; + color: #000; background-color: #CCC; + } + pre dfn { color: #900; } + pre em { color: #66F; background-color: #FFC; font-weight: normal; } + pre .key { color: #33C; font-weight: bold; } + pre .id { color: #900; } + pre .str { color: #000; background-color: #CFF; } + pre .val { color: #066; } + pre .rep { color: #909; } + pre .oth { color: #000; background-color: #FCF; } + pre .err { background-color: #FCC; } ! /* RFC-2629 <texttable>s. */ ! table.all, table.full, table.headers, table.none { ! font-size: small; text-align: center; border-width: 2px; ! vertical-align: top; border-collapse: collapse; ! } ! table.all, table.full { border-style: solid; border-color: black; } ! table.headers, table.none { border-style: none; } ! th { ! font-weight: bold; border-color: black; ! border-width: 2px 2px 3px 2px; ! } ! table.all th, table.full th { border-style: solid; } ! table.headers th { border-style: none none solid none; } ! table.none th { border-style: none; } ! table.all td { ! border-style: solid; border-color: #333; ! border-width: 1px 2px; ! } ! table.full td, table.headers td, table.none td { border-style: none; } ! hr { height: 1px; } ! hr.insert { ! width: 80%; border-style: none; border-width: 0; ! color: #CCC; background-color: #CCC; ! } ! --></style> </head> <body> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> <table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1"> <tr><td class="header">Network Working Group</td><td class="header">E. Van Hensbergen</td></tr> <tr><td class="header">Internet-Draft</td><td class="header">Plan 9 Fans</td></tr> <tr><td class="header">Updates:</td><td class="header">March 2005</td></tr> ! <tr><td class="header"> <a href='http://tools.ietf.org/html/rfcexperimental-draft-9P2000-protocol'>experimental-draft-9P2000-protocol</a></td><td class="header"> </td></tr> ! <tr><td class="header">(if approved)</td><td class="header"> </td></tr> ! <tr><td class="header">Intended status: Experimental</td><td class="header"> </td></tr> <tr><td class="header">Expires: September 2, 2005</td><td class="header"> </td></tr> </table></td></tr></table> ! <h1><br />Plan 9 Remote Resource Protocol Unix Extension<br />experimental-draft-9P2000-unix-extension</h1> <h3>Status of this Memo</h3> *************** *** 224,241 **** error - return an error<br /> <a href="#anchor16">7.3.</a> ! open, create - prepare a fid for I/O on an existing or new file<br /> <a href="#anchor17">7.4.</a> stat, wstat - inquire or change file attributes<br /> ! <a href="#anchor18">8.</a> Security Considerations<br /> ! <a href="#anchor19">9.</a> Protocol Definition Differences<br /> <a href="#rfc.references1">10.</a> References<br /> ! <a href="#anchor21">Appendix A.</a> Acknowledgements<br /> ! <a href="#anchor22">Appendix B.</a> Copyright<br /> ! <a href="#anchor23">Appendix C.</a> Lucent Public License Version 1.02<br /> <a href="#rfc.authors">§</a> --- 241,260 ---- error - return an error<br /> <a href="#anchor16">7.3.</a> ! auth/attach - messages to establish a connection<br /> <a href="#anchor17">7.4.</a> + open, create - prepare a fid for I/O on an existing or new file<br /> + <a href="#anchor18">7.5.</a> stat, wstat - inquire or change file attributes<br /> ! <a href="#anchor19">8.</a> Security Considerations<br /> ! <a href="#anchor20">9.</a> Protocol Definition Differences<br /> <a href="#rfc.references1">10.</a> References<br /> ! <a href="#anchor22">Appendix A.</a> Acknowledgements<br /> ! <a href="#anchor23">Appendix B.</a> Copyright<br /> ! <a href="#anchor24">Appendix C.</a> Lucent Public License Version 1.02<br /> <a href="#rfc.authors">§</a> *************** *** 245,259 **** <a name="anchor1"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.1"></a><h3>1. Requirements notation</h3> <p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as ! described in <a class="info" href="#RFC2119">[RFC2119]<span> (</span><span class="info">Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” March 1997.</span><span>)</span></a>. </p> <a name="intro"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2"></a><h3>2. Introduction</h3> <p> --- 264,280 ---- <a name="anchor1"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.1"></a><h3>1. ! Requirements notation</h3> <p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as ! described in <a class='info' href='#RFC2119'>[RFC2119]<span> (</span><span class='info'>Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” March 1997.</span><span>)</span></a>. </p> <a name="intro"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2"></a><h3>2. ! Introduction</h3> <p> *************** *** 275,294 **** </p> <a name="anchor2"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1"></a><h3>2.1. Overview of Differences</h3> <a name="anchor3"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.1"></a><h3>2.1.1. Numeric Versus String IDs</h3> <p> ! Under Plan 9, user names as well as groups are represented by strings, while ! on Unix they are represented by unique numbers. This is complicated by Linux ! making it exceedingly difficult to map these numeric identifiers to their ! string values in the kernel. Many of the available UNIX network file systems ! avoid this issue and simply use numeric identifiers over the wire, hoping they ! map to the remote system. NFSv4 has provisions for sending string group ! and user info over the wire and then contacting a user-space daemon which ! attempts to provide a valid mapping. </p> --- 296,317 ---- </p> <a name="anchor2"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1"></a><h3>2.1. ! Overview of Differences</h3> <a name="anchor3"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.1"></a><h3>2.1.1. ! Numeric Versus String IDs</h3> <p> ! Under Plan 9 <a class='info' href='#PLAN9'>[PLAN9]<span> (</span><span class='info'>Lucent Technologies, “Plan 9 Home Page,” .</span><span>)</span></a>, user names as well as groups are ! represented by strings, while on Unix they are represented by unique numbers. ! This is complicated by Linux making it exceedingly difficult to map these ! numeric identifiers to their string values in the kernel. Many of the ! available UNIX network file systems avoid this issue and simply use numeric ! identifiers over the wire, hoping they map to the remote system. NFSv4 has ! provisions for sending string group and user info over the wire and then ! contacting a user-space daemon which attempts to provide a valid mapping. </p> *************** *** 304,309 **** </p> <a name="anchor4"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.2"></a><h3>2.1.2. Error Strings Versus Error Codes</h3> <p> --- 327,333 ---- </p> <a name="anchor4"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.2"></a><h3>2.1.2. ! Error Strings Versus Error Codes</h3> <p> *************** *** 328,344 **** </p> <a name="anchor5"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.3"></a><h3>2.1.3. Permission Modes</h3> <p> ! Plan 9 has a different user security model, so there is no such concept ! as set-uid or set-gid permissions. There is also no equivilent for the ! sticky bit. Luckily, Plan 9 has plenty of space in higher permission mode ! bit space for such extensions. </p> <a name="anchor6"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.4"></a><h3>2.1.4. Special Files and Links</h3> <p> --- 352,370 ---- </p> <a name="anchor5"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.3"></a><h3>2.1.3. ! Permission Modes</h3> <p> ! Plan 9 has a different user security model <a class='info' href='#P9SEC'>[P9SEC]<span> (</span><span class='info'>Cox, R., Grosse, E., Pike, R., Presotto, D., and S. Quinlan, “Security in Plan 9,” 2002.</span><span>)</span></a>, so there ! is no such concept as set-uid or set-gid permissions. There is also no ! equivalent for the sticky bit. Luckily, Plan 9 has plenty of space in ! higher permission mode bit space for such extensions. </p> <a name="anchor6"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.4"></a><h3>2.1.4. ! Special Files and Links</h3> <p> *************** *** 369,374 **** </p> <a name="anchor7"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.5"></a><h3>2.1.5. ioctl</h3> <p> --- 395,401 ---- </p> <a name="anchor7"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.5"></a><h3>2.1.5. ! ioctl</h3> <p> *************** *** 383,388 **** </p> <a name="anchor8"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.6"></a><h3>2.1.6. Extended Attributes</h3> <p> --- 410,416 ---- </p> <a name="anchor8"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.1.6"></a><h3>2.1.6. ! Extended Attributes</h3> <p> *************** *** 394,399 **** </p> <a name="msgs"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.2.2"></a><h3>2.2. Changed Messages</h3> <p> --- 422,428 ---- </p> <a name="msgs"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.2.2"></a><h3>2.2. ! Changed Messages</h3> <p> *************** *** 411,415 **** <br /> ! size[4] Rerror tag[2] ename[s] errno[2] </p> --- 440,444 ---- <br /> ! size[4] Rerror tag[2] ename[s] errno[4] </p> *************** *** 417,421 **** <br /> ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] </p> --- 446,470 ---- <br /> ! size[4] Tauth tag[2] afid[4] uname[s] aname[s] ! ! </p> ! <p> ! size[4] Rauth tag[2] aqid[13] ! ! </p> ! <p> ! <br /> ! ! size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] ! ! </p> ! <p> ! size[4] Rattach tag[2] qid[13] ! ! </p> ! <p> ! <br /> ! ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] extension[s] </p> *************** *** 448,481 **** </p> <a name="anchor9"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.3"></a><h3>3. Protocol Data Types</h3> <a name="anchor10"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.3.1"></a><h3>3.1. Changed Basic Data Types</h3> <p> TODO: cover changed data types in our protocol synopsis </p> <a name="anchor11"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.3.2"></a><h3>3.2. Changed Structured Data Types</h3> <p> TODO: cover changed structs (like stat) that the protocol uses </p> <a name="anchor12"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.4"></a><h3>4. Changed File Attributes</h3> <p>TODO: discuss changes </p> <a name="anchor13"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.5"></a><h3>5. Versioning</h3> <p>TODO: describe protocol versioning in detail (steal from Protocol section) </p> <a name="anchor14"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.6"></a><h3>6. Error Definitions</h3> <p>TODO: enumerate new standard file system error strings and describe --- 497,536 ---- </p> <a name="anchor9"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.3"></a><h3>3. ! Protocol Data Types</h3> <a name="anchor10"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.3.1"></a><h3>3.1. ! Changed Basic Data Types</h3> <p> TODO: cover changed data types in our protocol synopsis </p> <a name="anchor11"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.3.2"></a><h3>3.2. ! Changed Structured Data Types</h3> <p> TODO: cover changed structs (like stat) that the protocol uses </p> <a name="anchor12"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.4"></a><h3>4. ! Changed File Attributes</h3> <p>TODO: discuss changes </p> <a name="anchor13"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.5"></a><h3>5. ! Versioning</h3> <p>TODO: describe protocol versioning in detail (steal from Protocol section) </p> <a name="anchor14"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.6"></a><h3>6. ! Error Definitions</h3> <p>TODO: enumerate new standard file system error strings and describe *************** *** 483,492 **** </p> <a name="protocol"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.7"></a><h3>7. Changed Protocol Operations</h3> <a name="version"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.7.1"></a><h3>7.1. version - negotiate protocol version</h3> <p> --- 538,549 ---- </p> <a name="protocol"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.7"></a><h3>7. ! Changed Protocol Operations</h3> <a name="version"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.7.1"></a><h3>7.1. ! version - negotiate protocol version</h3> <p> *************** *** 542,547 **** </p> <a name="anchor15"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.7.2"></a><h3>7.2. error - return an error</h3> <p> --- 599,605 ---- </p> <a name="anchor15"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.7.2"></a><h3>7.2. ! error - return an error</h3> <p> *************** *** 553,557 **** <blockquote class="text"> <p> ! size[4] Rerror tag[2] ename[s] errno[2] </p> --- 611,615 ---- <blockquote class="text"> <p> ! size[4] Rerror tag[2] ename[s] errno[4] </p> *************** *** 589,594 **** </p> <a name="anchor16"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.7.3"></a><h3>7.3. open, create - prepare a fid for I/O on an existing or new file</h3> <p> --- 647,695 ---- </p> <a name="anchor16"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.7.3"></a><h3>7.3. ! auth/attach - messages to establish a connection</h3> ! ! <p> ! SYNOPSIS ! ! </p> ! <p> ! </p> ! <blockquote class="text"> ! <p>size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] n_uname[4] ! </p> ! <p>size[4] Rattach tag[2] qid[13] ! </p> ! <p>size[4] Tauth tag[2] afid[4] uname[s] aname[s] n_uname[4] ! </p> ! <p>size[4] Rauth tag[2] aqid[13] ! </p> ! </blockquote><p> ! ! </p> ! <p> ! DESCRIPTION ! ! </p> ! <p> ! </p> ! <blockquote class="text"> ! <p> ! A numeric uname field has been added to the attach and auth messages ! in order to provide hints to map a string to a numeric id if such ! a facility is not available. ! ! The numeric uname should be given preference over the uname string ! unless n_uname is unspecified (~0). ! ! </p> ! </blockquote><p> ! ! </p> ! <a name="anchor17"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.7.4"></a><h3>7.4. ! open, create - prepare a fid for I/O on an existing or new file</h3> <p> *************** *** 600,604 **** <blockquote class="text"> <p> ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] </p> --- 701,705 ---- <blockquote class="text"> <p> ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] extension[s] </p> *************** *** 622,626 **** In addition to creating directories with DMDIR, 9P2000.u allows the creation of symlinks (DMSYMLINK), devices (DMDEVICE), ! named pipes (DMNAMEPIPE), and sockets (DMSOCKET). </p> --- 723,731 ---- In addition to creating directories with DMDIR, 9P2000.u allows the creation of symlinks (DMSYMLINK), devices (DMDEVICE), ! named pipes (DMNAMEPIPE), and sockets (DMSOCKET). extension[s] ! is a string describing special files, depending on the mode bit. ! For DSYMLINK files, the string is the target of the link. For ! DMDEVICE files, the string is "b 1 2" for a block device with ! major 1, minor 2. For normal files, this string is empty. </p> *************** *** 628,634 **** </p> ! <a name="anchor17"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.7.4"></a><h3>7.4. stat, wstat - inquire or change file attributes</h3> <p> --- 733,740 ---- </p> ! <a name="anchor18"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.7.5"></a><h3>7.5. ! stat, wstat - inquire or change file attributes</h3> <p> *************** *** 813,827 **** </p> ! <a name="anchor18"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.8"></a><h3>8. Security Considerations</h3> <p>TODO: Talk about specific security considerations of 9P under UNIX, specifically about the different auth models </p> ! <a name="anchor19"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.9"></a><h3>9. Protocol Definition Differences</h3> ! <pre> /* permissions */ enum { --- 919,935 ---- </p> ! <a name="anchor19"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.8"></a><h3>8. ! Security Considerations</h3> <p>TODO: Talk about specific security considerations of 9P under UNIX, specifically about the different auth models </p> ! <a name="anchor20"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.9"></a><h3>9. ! Protocol Definition Differences</h3> ! <div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre> /* permissions */ enum { *************** *** 848,852 **** QTMOUNT = 0x10, QTAUTH = 0x08, ! QTTMP = 0x04, QTLINK = 0x02, QTFILE = 0x00, --- 956,960 ---- QTMOUNT = 0x10, QTAUTH = 0x08, ! QTTMP = 0x04, QTLINK = 0x02, QTFILE = 0x00, *************** *** 878,884 **** uint32_t errno; /* 9p2000.u extension */ }; ! </pre> <a name="rfc.references1"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> <h3>10. References</h3> <table width="99%" border="0"> --- 986,992 ---- uint32_t errno; /* 9p2000.u extension */ }; ! </pre></div> <a name="rfc.references1"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> <h3>10. References</h3> <table width="99%" border="0"> *************** *** 888,897 **** <td class="author-text">Lucent Technologies, “<a href="http://plan9.bell-labs.com/plan9">Plan 9 Home Page</a>.”</td></tr> <tr><td class="author-text" valign="top"><a name="RFC2119">[RFC2119]</a></td> ! <td class="author-text"><a href="mailto:so...@ha...">Bradner, S.</a>, “<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">Key words for use in RFCs to Indicate Requirement Levels</a>,” BCP 14, RFC 2119, March 1997 (<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">TXT</a>, <a href="http://xml.resource.org/public/rfc/html/rfc2119.html">HTML</a>, <a href="http://xml.resource.org/public/rfc/xml/rfc2119.xml">XML</a>).</td></tr> </table> ! <a name="anchor21"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.A"></a><h3>Appendix A. Acknowledgements</h3> <p> --- 996,1006 ---- <td class="author-text">Lucent Technologies, “<a href="http://plan9.bell-labs.com/plan9">Plan 9 Home Page</a>.”</td></tr> <tr><td class="author-text" valign="top"><a name="RFC2119">[RFC2119]</a></td> ! <td class="author-text"><a href="mailto:so...@ha...">Bradner, S.</a>, “<a href="http://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a>,” BCP 14, RFC 2119, March 1997 (<a href="ftp://ftp.isi.edu/in-notes/rfc2119.txt">TXT</a>, <a href="http://xml.resource.org/public/rfc/html/rfc2119.html">HTML</a>, <a href="http://xml.resource.org/public/rfc/xml/rfc2119.xml">XML</a>).</td></tr> </table> ! <a name="anchor22"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.A"></a><h3>Appendix A. ! Acknowledgements</h3> <p> *************** *** 948,954 **** </p> ! <a name="anchor22"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.B"></a><h3>Appendix B. Copyright</h3> <p> --- 1057,1064 ---- </p> ! <a name="anchor23"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.B"></a><h3>Appendix B. ! Copyright</h3> <p> *************** *** 963,969 **** </p> ! <a name="anchor23"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> ! <a name="rfc.section.C"></a><h3>Appendix C. Lucent Public License Version 1.02</h3> <p> --- 1073,1080 ---- </p> ! <a name="anchor24"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> ! <a name="rfc.section.C"></a><h3>Appendix C. ! Lucent Public License Version 1.02</h3> <p> *************** *** 1305,1309 **** </p> <a name="rfc.authors"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table> <h3>Author's Address</h3> <table width="99%" border="0" cellpadding="0" cellspacing="0"> --- 1416,1420 ---- </p> <a name="rfc.authors"></a><br /><hr /> ! <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> <h3>Author's Address</h3> <table width="99%" border="0" cellpadding="0" cellspacing="0"> *************** *** 1318,1320 **** </table> </body></html> - --- 1429,1430 ---- Index: 9p2000.u.nr =================================================================== RCS file: /cvsroot/v9fs/doc/rfc/9p2000.u.nr,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** 9p2000.u.nr 22 Nov 2005 14:27:05 -0000 1.3 --- 9p2000.u.nr 17 Aug 2009 18:29:55 -0000 1.4 *************** *** 1,4 **** ! ! .\" automatically generated by xml2rfc v1.30 on 2005-11-22T14:26:03Z .\" .pl 10.0i --- 1,3 ---- ! .\" automatically generated by xml2rfc v1.33 on 2009-08-15T22:59:50Z .\" .pl 10.0i *************** *** 23,27 **** Updates: March 2005 \%experimental-draft-9P2000-protocol ! (if approved) Expires: September 2, 2005 --- 22,27 ---- Updates: March 2005 \%experimental-draft-9P2000-protocol ! (if\0approved) ! Intended status: Experimental Expires: September 2, 2005 *************** *** 58,62 **** This \%Internet-Draft will expire on September 2, 2005. ! .ti 0 Abstract --- 58,62 ---- This \%Internet-Draft will expire on September 2, 2005. ! .bp .ti 0 Abstract *************** *** 73,115 **** UNIX environments connecting to Plan 9 file servers and UNIX environments connecting to other UNIX environments. The extensions - .bp include support for symbolic links, additional modes, and special files (such as pipes and devices). Also included are hints to better support mapping of numeric \%user-ids, \%group-ids, and error codes. ! ! .in 0 Table of Contents .nf ! 1. Requirements notation . . . . . . . . . . . . . . . . . . . . 3 ! 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 ! 2.1. Overview of Differences . . . . . . . . . . . . . . . . . 4 ! 2.1.1. Numeric Versus String IDs . . . . . . . . . . . . . . 4 ! 2.1.2. Error Strings Versus Error Codes . . . . . . . . . . . 4 ! 2.1.3. Permission Modes . . . . . . . . . . . . . . . . . . . 5 ! 2.1.4. Special Files and Links . . . . . . . . . . . . . . . 5 ! 2.1.5. ioctl . . . . . . . . . . . . . . . . . . . . . . . . 5 ! 2.1.6. Extended Attributes . . . . . . . . . . . . . . . . . 6 ! 2.2. Changed Messages . . . . . . . . . . . . . . . . . . . . . 6 ! 3. Protocol Data Types . . . . . . . . . . . . . . . . . . . . . 7 ! 3.1. Changed Basic Data Types . . . . . . . . . . . . . . . . . 7 ! 3.2. Changed Structured Data Types . . . . . . . . . . . . . . 7 ! 4. Changed File Attributes . . . . . . . . . . . . . . . . . . . 8 ! 5. Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . 9 ! 6. Error Definitions . . . . . . . . . . . . . . . . . . . . . . 10 ! 7. Changed Protocol Operations . . . . . . . . . . . . . . . . . 11 ! 7.1. version \%- negotiate protocol version . . . . . . . . . . . 11 ! 7.2. error \%- return an error . . . . . . . . . . . . . . . . . 11 ! 7.3. open, create \%- prepare a fid for I/O on an existing or ! new file . . . . . . . . . . . . . . . . . . . . . . . . . 12 ! 7.4. stat, wstat \%- inquire or change file attributes . . . . . 12 ! 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 ! 9. Protocol Definition Differences . . . . . . . . . . . . . . . 16 ! 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 17 ! Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 18 ! Appendix B. Copyright . . . . . . . . . . . . . . . . . . . . . . 19 ! Appendix C. Lucent Public License Version 1.02 . . . . . . . . . 20 ! Author\'s Address . . . . . . . . . . . . . . . . . . . . . . . . . 26 .bp .fi --- 73,114 ---- UNIX environments connecting to Plan 9 file servers and UNIX environments connecting to other UNIX environments. The extensions include support for symbolic links, additional modes, and special files (such as pipes and devices). Also included are hints to better support mapping of numeric \%user-ids, \%group-ids, and error codes. ! .bp .in 0 Table of Contents .nf ! 1. Requirements notation . . . . . . . . . . . . . . . . . . . . 4 ! 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 5 ! 2.1. Overview of Differences . . . . . . . . . . . . . . . . . 5 ! 2.1.1. Numeric Versus String IDs . . . . . . . . . . . . . . 5 ! 2.1.2. Error Strings Versus Error Codes . . . . . . . . . . . 5 ! 2.1.3. Permission Modes . . . . . . . . . . . . . . . . . . . 6 ! 2.1.4. Special Files and Links . . . . . . . . . . . . . . . 6 ! 2.1.5. ioctl . . . . . . . . . . . . . . . . . . . . . . . . 6 ! 2.1.6. Extended Attributes . . . . . . . . . . . . . . . . . 7 ! 2.2. Changed Messages . . . . . . . . . . . . . . . . . . . . . 7 ! 3. Protocol Data Types . . . . . . . . . . . . . . . . . . . . . 8 ! 3.1. Changed Basic Data Types . . . . . . . . . . . . . . . . . 8 ! 3.2. Changed Structured Data Types . . . . . . . . . . . . . . 8 ! 4. Changed File Attributes . . . . . . . . . . . . . . . . . . . 9 ! 5. Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . 10 ! 6. Error Definitions . . . . . . . . . . . . . . . . . . . . . . 11 ! 7. Changed Protocol Operations . . . . . . . . . . . . . . . . . 12 ! 7.1. version \%- negotiate protocol version . . . . . . . . . . . 12 ! 7.2. error \%- return an error . . . . . . . . . . . . . . . . . 12 ! 7.3. auth/attach \%- messages to establish a connection . . . . . 13 ! 7.4. open, create \%- prepare a fid for I/O on an existing or ! new file . . . . . . . . . . . . . . . . . . . . . . . . . 13 ! 7.5. stat, wstat \%- inquire or change file attributes . . . . . 14 ! 8. Security Considerations . . . . . . . . . . . . . . . . . . . 16 ! 9. Protocol Definition Differences . . . . . . . . . . . . . . . 17 ! 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 19 ! Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 20 ! Appendix B. Copyright . . . . . . . . . . . . . . . . . . . . . . 21 ! Appendix C. Lucent Public License Version 1.02 . . . . . . . . . 22 ! Author\'s Address . . . . . . . . . . . . . . . . . . . . . . . . . 28 .bp .fi *************** *** 153,157 **** .in 3 ! Under Plan 9, user names as well as groups are represented by strings, while on Unix they are represented by unique numbers. This is complicated by Linux making it exceedingly difficult to map these --- 152,156 ---- .in 3 ! Under Plan 9 [PLAN9], user names as well as groups are represented by strings, while on Unix they are represented by unique numbers. This is complicated by Linux making it exceedingly difficult to map these *************** *** 199,205 **** .in 3 ! Plan 9 has a different user security model, so there is no such ! concept as \%set-uid or \%set-gid permissions. There is also no ! equivilent for the sticky bit. Luckily, Plan 9 has plenty of space in higher permission mode bit space for such extensions. --- 198,204 ---- .in 3 ! Plan 9 has a different user security model [P9SEC], so there is no ! such concept as \%set-uid or \%set-gid permissions. There is also no ! equivalent for the sticky bit. Luckily, Plan 9 has plenty of space in higher permission mode bit space for such extensions. *************** *** 270,278 **** .ti 6 .br ! size[4] Rerror tag[2] ename[s] errno[2] .ti 6 .br ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] .ti 6 --- 269,291 ---- .ti 6 .br ! size[4] Rerror tag[2] ename[s] errno[4] .ti 6 .br ! size[4] Tauth tag[2] afid[4] uname[s] aname[s] ! ! .ti 6 ! size[4] Rauth tag[2] aqid[13] ! ! .ti 6 ! .br ! size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] ! ! .ti 6 ! size[4] Rattach tag[2] qid[13] ! ! .ti 6 ! .br ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] extension[s] .ti 6 *************** *** 394,398 **** .in 6 .ti 6 ! size[4] Rerror tag[2] ename[s] errno[2] .in 3 --- 407,411 ---- .in 6 .ti 6 ! size[4] Rerror tag[2] ename[s] errno[4] .in 3 *************** *** 419,423 **** .in 6 .ti 0 ! 7.3. open, create \%- prepare a fid for I/O on an existing or new file .in 3 --- 432,436 ---- .in 6 .ti 0 ! 7.3. auth/attach \%- messages to establish a connection .in 3 *************** *** 426,430 **** .in 6 .ti 6 ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] .ti 6 --- 439,475 ---- .in 6 .ti 6 ! size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] n_uname[4] ! ! .ti 6 ! size[4] Rattach tag[2] qid[13] ! ! .ti 6 ! size[4] Tauth tag[2] afid[4] uname[s] aname[s] n_uname[4] ! ! .ti 6 ! size[4] Rauth tag[2] aqid[13] ! ! .in 3 ! DESCRIPTION ! ! .in 6 ! .ti 6 ! A numeric uname field has been added to the attach and auth ! messages in order to provide hints to map a string to a numeric id ! if such a facility is not available. The numeric uname should be ! given preference over the uname string unless n_uname is ! unspecified (~0). ! ! .in 3 ! .in 6 ! .ti 0 ! 7.4. open, create \%- prepare a fid for I/O on an existing or new file ! .in 3 ! ! SYNOPSIS ! ! .in 6 ! .ti 6 ! size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] extension[s] .ti 6 *************** *** 440,449 **** addition to creating directories with DMDIR, 9P2000.u allows the creation of symlinks (DMSYMLINK), devices (DMDEVICE), named pipes ! (DMNAMEPIPE), and sockets (DMSOCKET). .in 3 .in 6 .ti 0 ! 7.4. stat, wstat \%- inquire or change file attributes .in 3 --- 485,499 ---- addition to creating directories with DMDIR, 9P2000.u allows the creation of symlinks (DMSYMLINK), devices (DMDEVICE), named pipes ! (DMNAMEPIPE), and sockets (DMSOCKET). extension[s] is a string ! describing special files, depending on the mode bit. For DSYMLINK ! files, the string is the target of the link. For DMDEVICE files, ! the string is "b 1 2" for a block device with major 1, minor 2. ! For normal files, this string is empty. .in 3 + .bp .in 6 .ti 0 ! 7.5. stat, wstat \%- inquire or change file attributes .in 3 *************** *** 484,488 **** .br for kernel use ! .bp .ti 9 dev[4]\0 --- 534,538 ---- .br for kernel use ! .ti 9 dev[4]\0 *************** *** 521,525 **** .br last modification time ! .ti 9 length[8]\0 --- 571,575 ---- .br last modification time ! .bp .ti 9 length[8]\0 *************** *** 558,562 **** .br numeric id of the user who owns the file ! .bp .ti 9 n_gid[4]\0 --- 608,612 ---- .br numeric id of the user who owns the file ! .ti 9 n_gid[4]\0 *************** *** 656,660 **** }; ! .fi .in 5 --- 706,710 ---- }; ! .bp .fi .in 5 *************** *** 1010,1012 **** Email: 9f...@cs... URI: \%http://plan9.bell-labs.com/plan9 - --- 1060,1061 ---- Index: 9p2000.u.txt =================================================================== RCS file: /cvsroot/v9fs/doc/rfc/9p2000.u.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** 9p2000.u.txt 22 Nov 2005 14:27:05 -0000 1.3 --- 9p2000.u.txt 17 Aug 2009 18:29:55 -0000 1.4 *************** *** 7,10 **** --- 7,11 ---- experimental-draft-9P2000-protocol (if approved) + Intended status: Experimental Expires: September 2, 2005 *************** *** 37,40 **** --- 38,61 ---- This Internet-Draft will expire on September 2, 2005. + + + + + + + + + + + + + + + + Van Hensbergen Expires September 2, 2005 [Page 1] + + Internet-Draft 9P2000.u March 2005 + + Abstract *************** *** 50,96 **** UNIX environments connecting to Plan 9 file servers and UNIX environments connecting to other UNIX environments. The extensions ! Van Hensbergen Expires September 2, 2005 [Page 1] Internet-Draft 9P2000.u March 2005 - include support for symbolic links, additional modes, and special - files (such as pipes and devices). Also included are hints to better - support mapping of numeric user-ids, group-ids, and error codes. - Table of Contents ! 1. Requirements notation . . . . . . . . . . . . . . . . . . . . 3 ! 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 ! 2.1 Overview of Differences . . . . . . . . . . . . . . . . . 4 ! 2.1.1 Numeric Versus String IDs . . . . . . . . . . . . . . 4 ! 2.1.2 Error Strings Versus Error Codes . . . . . . . . . . . 4 ! 2.1.3 Permission Modes . . . . . . . . . . . . . . . . . . . 5 ! 2.1.4 Special Files and Links . . . . . . . . . . . . . . . 5 ! 2.1.5 ioctl . . . . . . . . . . . . . . . . . . . . . . . . 5 ! 2.1.6 Extended Attributes . . . . . . . . . . . . . . . . . 6 ! 2.2 Changed Messages . . . . . . . . . . . . . . . . . . . . . 6 ! 3. Protocol Data Types . . . . . . . . . . . . . . . . . . . . . 7 ! 3.1 Changed Basic Data Types . . . . . . . . . . . . . . . . . 7 ! 3.2 Changed Structured Data Types . . . . . . . . . . . . . . 7 ! 4. Changed File Attributes . . . . . . . . . . . . . . . . . . . 8 ! 5. Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . 9 ! 6. Error Definitions . . . . . . . . . . . . . . . . . . . . . . 10 ! 7. Changed Protocol Operations . . . . . . . . . . . . . . . . . 11 ! 7.1 version - negotiate protocol version . . . . . . . . . . . 11 ! 7.2 error - return an error . . . . . . . . . . . . . . . . . 11 ! 7.3 open, create - prepare a fid for I/O on an existing or ! new file . . . . . . . . . . . . . . . . . . . . . . . . . 12 ! 7.4 stat, wstat - inquire or change file attributes . . . . . 12 ! 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 ! 9. Protocol Definition Differences . . . . . . . . . . . . . . . 16 ! 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 17 ! Author's Address . . . . . . . . . . . . . . . . . . . . . . . 17 ! A. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 18 ! B. Copyright . . . . . . . . . . . . . . . . . . . . . . . . . . 19 ! C. Lucent Public License Version 1.02 . . . . . . . . . . . . . . 20 --- 71,149 ---- UNIX environments connecting to Plan 9 file servers and UNIX environments connecting to other UNIX environments. The extensions + include support for symbolic links, additional modes, and special + files (such as pipes and devices). Also included are hints to better + support mapping of numeric user-ids, group-ids, and error codes. ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! Van Hensbergen Expires September 2, 2005 [Page 2] Internet-Draft 9P2000.u March 2005 Table of Contents ! 1. Requirements notation . . . . . . . . . . . . . . . . . . . . 4 ! 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 5 ! 2.1. Overview of Differences . . . . . . . . . . . . . . . . . 5 ! 2.1.1. Numeric Versus String IDs . . . . . . . . . . . . . . 5 ! 2.1.2. Error Strings Versus Error Codes . . . . . . . . . . . 5 ! 2.1.3. Permission Modes . . . . . . . . . . . . . . . . . . . 6 ! 2.1.4. Special Files and Links . . . . . . . . . . . . . . . 6 ! 2.1.5. ioctl . . . . . . . . . . . . . . . . . . . . . . . . 6 ! 2.1.6. Extended Attributes . . . . . . . . . . . . . . . . . 7 ! 2.2. Changed Messages . . . . . . . . . . . . . . . . . . . . . 7 ! 3. Protocol Data Types . . . . . . . . . . . . . . . . . . . . . 8 ! 3.1. Changed Basic Data Types . . . . . . . . . . . . . . . . . 8 ! 3.2. Changed Structured Data Types . . . . . . . . . . . . . . 8 ! 4. Changed File Attributes . . . . . . . . . . . . . . . . . . . 9 ! 5. Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . 10 ! 6. Error Definitions . . . . . . . . . . . . . . . . . . . . . . 11 ! 7. Changed Protocol Operations . . . . . . . . . . . . . . . . . 12 ! 7.1. version - negotiate protocol version . . . . . . . . . . . 12 ! 7.2. error - return an error . . . . . . . . . . . . . . . . . 12 ! 7.3. auth/attach - messages to establish a connection . . . . . 13 ! 7.4. open, create - prepare a fid for I/O on an existing or ! new file . . . . . . . . . . . . . . . . . . . . . . . . . 13 ! 7.5. stat, wstat - inquire or change file attributes . . . . . 14 ! 8. Security Considerations . . . . . . . . . . . . . . . . . . . 16 ! 9. Protocol Definition Differences . . . . . . . . . . . . . . . 17 ! 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 19 ! Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 20 ! Appendix B. Copyright . . . . . . . . . . . . . . . . . . . . . . 21 ! Appendix C. Lucent Public License Version 1.02 . . . . . . . . . 22 ! Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 28 *************** *** 109,113 **** ! Van Hensbergen Expires September 2, 2... [truncated message content] |
From: <er...@gm...> - 2007-01-18 17:26:22
|
testing... |
Update of /cvsroot/v9fs/app/dbench In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv26804/dbench Added Files: COPYING INSTALL Makefile.in README autogen.sh child.c client.txt config.h.in configure configure.in dbench.1 dbench.c dbench.h fileio.c install-sh io.c mkproto.pl proto.h snprintf.c sockio.c socklib.c system.c tbench_srv.c util.c Log Message: Add dbench to regression/benchmarking tools --- NEW FILE: tbench_srv.c --- /* dbench version 2 Copyright (C) Andrew Tridgell 1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dbench.h" char *tcp_options = TCP_OPTIONS; static void server(int fd) { char buf[70000]; unsigned *ibuf = (unsigned *)buf; uint32_t n; signal(SIGPIPE, SIG_IGN); printf("^"); fflush(stdout); while (1) { if (read_sock(fd, buf, 4) != 4) break; n = ntohl(ibuf[0]); if (n+4 >= sizeof(buf)) { printf("overflow in server!\n"); exit(1); } if (read_sock(fd, buf+4, n) != (int)n) break; n = ntohl(ibuf[1]); ibuf[0] = htonl(n); if (write_sock(fd, buf, n+4) != (int)(n+4)) break; } exit(0); } static void listener(void) { int sock; sock = open_socket_in(SOCK_STREAM, TCP_PORT); if (listen(sock, 20) == -1) { fprintf(stderr,"listen failed\n"); exit(1); } printf("waiting for connections\n"); signal(SIGCHLD, SIG_IGN); while (1) { struct sockaddr addr; int in_addrlen = sizeof(addr); int fd; while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) ; fd = accept(sock,&addr,&in_addrlen); if (fd != -1) { if (fork() == 0) server(fd); close(fd); } } } static void usage(void) { printf("usage: tbench_srv [OPTIONS]\n" "options:\n" " -t options set socket options\n"); exit(1); } static void process_opts(int argc, char **argv) { int c; while ((c = getopt(argc, argv, "t:")) != -1) { switch (c) { case 't': tcp_options = optarg; break; default: usage(); } } } int main(int argc, char *argv[]) { process_opts(argc, argv); listener(); return 0; } --- NEW FILE: mkproto.pl --- #!/usr/bin/perl use strict; # don't use warnings module as it is not portable enough # use warnings; my $header_name = '_PROTO_H_'; if ($ARGV[0] eq '-h') { shift @ARGV; $header_name = shift @ARGV; } sub print_header { print "#ifndef $header_name\n"; print "#define $header_name\n\n"; print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */\n\n"; } sub print_footer { printf "\n#endif /* %s */\n", $header_name; } sub handle_loadparm { my $line = shift; if ($line =~ /^FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|BOOL|CHAR|INTEGER|LIST)\((\w+),.*\)/o) { my $scope = $1; my $type = $2; my $name = $3; my %tmap = ( "BOOL" => "BOOL ", "CONST_STRING" => "const char *", "STRING" => "const char *", "INTEGER" => "int ", "CHAR" => "char ", "LIST" => "const char **", ); my %smap = ( "GLOBAL" => "void", "LOCAL" => "int " ); print "$tmap{$type}$name($smap{$scope});\n"; } } sub process_file($) { my $filename = shift; open(FH, "< $filename") || die "Failed to open $filename"; print "\n/* The following definitions come from $filename */\n\n"; while (my $line = <FH>) { # these are ordered for maximum speed next if ($line =~ /^\s/); next unless ($line =~ /\(/); next if ($line =~ /^\/|[;]/); next unless ( $line =~ / ^void|^BOOL|^int|^struct|^char|^const|^\w+_[tT]\s|^uint|^unsigned|^long| ^NTSTATUS|^ADS_STATUS|^enum\s.*\(|^DATA_BLOB|^WERROR|^XFILE|^FILE|^DIR| ^double|^TDB_CONTEXT|^TDB_DATA|^TALLOC_CTX|^NTTIME|^FN_|^REG_KEY|^REG_HANDLE|^REG_VAL| ^GtkWidget|^GType|^smb_ucs2_t /xo); next if ($line =~ /^int\s*main/); if ($line =~ /^FN_/) { handle_loadparm($line); next; } if ( $line =~ /\(.*\)\s*$/o ) { chomp $line; print "$line;\n"; next; } print $line; while ($line = <FH>) { if ($line =~ /\)\s*$/o) { chomp $line; print "$line;\n"; last; } print $line; } } close(FH); } sub process_files { foreach my $filename (@ARGV) { process_file($filename); } } print_header(); process_files(); print_footer(); --- NEW FILE: sockio.c --- /* dbench version 2 Copyright (C) Andrew Tridgell 1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dbench.h" #define MAX_FILES 1000 static char buf[70000]; char *server = "localhost"; static int sock; /* emulate a single SMB packet exchange */ static void do_packets(int send_size, int recv_size) { uint32 *ubuf = (uint32 *)buf; ubuf[0] = htonl(send_size-4); ubuf[1] = htonl(recv_size-4); if (write_sock(sock, buf, send_size) != send_size) { printf("error writing %d bytes\n", (int)send_size); exit(1); } if (read_sock(sock, buf, 4) != 4) { printf("error reading header\n"); exit(1); } if (ntohl(ubuf[0]) != (unsigned)(recv_size-4)) { printf("lost sync (%d %d)\n", (int)recv_size-4, (int)ntohl(ubuf[0])); exit(1); } if (recv(sock, buf, recv_size-4, MSG_WAITALL|MSG_TRUNC) != recv_size-4) { printf("error reading %d bytes\n", (int)recv_size-4); exit(1); } if (ntohl(ubuf[0]) != (unsigned)(recv_size-4)) { printf("lost sync (%d %d)\n", (int)recv_size-4, (int)ntohl(ubuf[0])); } } void nb_setup(struct child_struct *child) { extern char *tcp_options; sock = open_socket_out(server, TCP_PORT); if (sock == -1) { printf("client %d failed to start\n", child->id); exit(1); } set_socket_options(sock, tcp_options); do_packets(8, 8); } void nb_unlink(struct child_struct *child, char *fname, int attr, const char *status) { (void)child; (void)attr; (void)status; do_packets(39+2+strlen(fname)*2+2, 39); } void nb_mkdir(struct child_struct *child, char *dname, const char *status) { (void)child; (void)status; do_packets(39+2+strlen(dname)*2+2, 39); } void nb_rmdir(struct child_struct *child, char *fname, const char *status) { (void)child; (void)status; do_packets(39+2+strlen(fname)*2+2, 39); } void nb_createx(struct child_struct *child, const char *fname, uint32_t create_options, uint32_t create_disposition, int fnum, const char *status) { (void)child; (void)create_options; (void)create_disposition; (void)fnum; (void)status; do_packets(70+2+strlen(fname)*2+2, 39+12*4); } void nb_writex(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status) { (void)child; (void)handle; (void)offset; (void)ret_size; (void)status; do_packets(39+20+size, 39+16); child->bytes += size; } void nb_readx(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status) { (void)child; (void)handle; (void)offset; (void)size; (void)status; do_packets(39+20, 39+20+ret_size); child->bytes += ret_size; } void nb_close(struct child_struct *child, int handle, const char *status) { (void)child; (void)handle; (void)status; do_packets(39+8, 39); } void nb_rename(struct child_struct *child, char *old, char *new, const char *status) { (void)child; (void)status; do_packets(39+8+2*strlen(old)+2*strlen(new), 39); } void nb_flush(struct child_struct *child, int handle, const char *status) { (void)child; (void)handle; (void)status; do_packets(39+2, 39); } void nb_qpathinfo(struct child_struct *child, const char *fname, int level, const char *status) { (void)child; (void)level; (void)status; do_packets(39+16+2*strlen(fname), 39+32); } void nb_qfileinfo(struct child_struct *child, int handle, int level, const char *status) { (void)child; (void)level; (void)handle; (void)status; do_packets(39+20, 39+32); } void nb_qfsinfo(struct child_struct *child, int level, const char *status) { (void)child; (void)level; (void)status; do_packets(39+20, 39+32); } void nb_findfirst(struct child_struct *child, char *fname, int level, int maxcnt, int count, const char *status) { (void)child; (void)level; (void)maxcnt; (void)status; do_packets(39+20+strlen(fname)*2, 39+90*count); } void nb_cleanup(struct child_struct *child) { (void)child; } void nb_deltree(struct child_struct *child, char *dname) { (void)child; (void)dname; } void nb_sfileinfo(struct child_struct *child, int handle, int level, const char *status) { (void)child; (void)handle; (void)level; (void)status; do_packets(39+32, 39+8); } void nb_lockx(struct child_struct *child, int handle, uint32_t offset, int size, const char *status) { (void)child; (void)handle; (void)offset; (void)size; (void)status; do_packets(39+12, 39); } void nb_unlockx(struct child_struct *child, int handle, uint32_t offset, int size, const char *status) { (void)child; (void)handle; (void)offset; (void)size; (void)status; do_packets(39+12, 39); } void nb_sleep(struct child_struct *child, int usec, const char *status) { (void)child; (void)usec; (void)status; usleep(usec); } --- NEW FILE: configure.in --- dnl Process this file with autoconf to produce a configure script. AC_INIT() AC_PREREQ(2.52) AC_MSG_NOTICE([Configuring dbench]) AC_CONFIG_HEADER(config.h) dnl Checks for programs. AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_DEFINE([_GNU_SOURCE], 1, [Define _GNU_SOURCE so that we get all necessary prototypes]) # If GCC, turn on warnings. if test "x$GCC" = "xyes" then CFLAGS="$CFLAGS -Wall -W" else CFLAGS="$CFLAGS -O" fi AC_HEADER_DIRENT AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(ctype.h strings.h stdlib.h string.h sys/vfs.h sys/statvfs.h stdint.h) AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h) AC_CHECK_HEADERS(sys/mount.h) AC_CHECK_FUNCS(fdatasync) # Check if we have libattr AC_SEARCH_LIBS(getxattr, [attr]) AC_SEARCH_LIBS(socket, [socket]) AC_SEARCH_LIBS(gethostbyname, [nsl]) AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr) AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr) AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr) # Check if we have attr_get AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove) AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef) # Check if we have extattr AC_CHECK_FUNCS(extattr_delete_fd extattr_delete_file extattr_delete_link) AC_CHECK_FUNCS(extattr_get_fd extattr_get_file extattr_get_link) AC_CHECK_FUNCS(extattr_list_fd extattr_list_file extattr_list_link) AC_CHECK_FUNCS(extattr_set_fd extattr_set_file extattr_set_link) AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf) if test x"$ac_cv_func_fgetxattr" = x"yes" -o \ x"$ac_cv_func_attr_getf" = x"yes" -o \ x"$ac_cv_func_extattr_get_fd" = x"yes"; then AC_DEFINE(HAVE_EA_SUPPORT, 1, [Whether we have EA support]) fi AC_CACHE_CHECK([for va_copy],dbench_cv_HAVE_VA_COPY,[ AC_TRY_LINK([#include <stdarg.h> va_list ap1,ap2;], [va_copy(ap1,ap2);], dbench_cv_HAVE_VA_COPY=yes,dbench_cv_HAVE_VA_COPY=no)]) if test x"$dbench_cv_HAVE_VA_COPY" = x"yes"; then AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available]) fi if test x"$dbench_cv_HAVE_VA_COPY" != x"yes"; then AC_CACHE_CHECK([for __va_copy],dbench_cv_HAVE___VA_COPY,[ AC_TRY_LINK([#include <stdarg.h> va_list ap1,ap2;], [__va_copy(ap1,ap2);], dbench_cv_HAVE___VA_COPY=yes,dbench_cv_HAVE___VA_COPY=no)]) if test x"$dbench_cv_HAVE___VA_COPY" = x"yes"; then AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available]) fi fi AC_CONFIG_FILES([Makefile]) AC_OUTPUT --- NEW FILE: Makefile.in --- VERSION=3.04 srcdir=@srcdir@ VPATH=@srcdir@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ mandir=@mandir@ datadir=@datadir@ INSTALLCMD=@INSTALL@ LIBS=@LIBS@ CC=@CC@ CFLAGS=@CFLAGS@ -I. -DVERSION=\"$(VERSION)\" -DDATADIR=\"$(datadir)\" EXEEXT=@EXEEXT@ DB_OBJS = fileio.o util.o dbench.o child.o system.o snprintf.o TB_OBJS = sockio.o util.o dbench.o child.o socklib.o snprintf.o SRV_OBJS = util.o tbench_srv.o socklib.o all: dbench tbench tbench_srv dbench: $(DB_OBJS) $(CC) -o $@ $(DB_OBJS) $(LIBS) tbench: $(TB_OBJS) $(CC) -o $@ $(TB_OBJS) $(LIBS) tbench_srv: $(SRV_OBJS) $(CC) -o $@ $(SRV_OBJS) $(LIBS) # Careful here: don't install client.txt over itself. install: all ${INSTALLCMD} -d $(bindir) $(datadir) $(mandir) ${INSTALLCMD} dbench tbench tbench_srv $(bindir) ${INSTALLCMD} client.txt $(datadir) ${INSTALLCMD} -m644 dbench.1 $(mandir) ln -sf dbench.1 $(mandir)/tbench.1 ln -sf dbench.1 $(mandir)/tbench_srv.1 clean: rm -f *.o *~ dbench tbench tbench_srv proto: ./mkproto.pl *.c > proto.h --- NEW FILE: util.c --- /* dbench version 2 Copyright (C) Andrew Tridgell 1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dbench.h" #ifndef SHM_W #define SHM_W 0000200 #endif #ifndef SHM_R #define SHM_R 0000400 #endif /* return a pointer to a anonymous shared memory segment of size "size" which will persist across fork() but will disappear when all processes exit The memory is not zeroed This function uses system5 shared memory. It takes advantage of a property that the memory is not destroyed if it is attached when the id is removed */ void *shm_setup(int size) { int shmid; void *ret; shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W); if (shmid == -1) { printf("can't get private shared memory of %d bytes: %s\n", size, strerror(errno)); exit(1); } ret = (void *)shmat(shmid, 0, 0); if (!ret || ret == (void *)-1) { printf("can't attach to shared memory\n"); return NULL; } /* the following releases the ipc, but note that this process and all its children will still have access to the memory, its just that the shmid is no longer valid for other shm calls. This means we don't leave behind lots of shm segments after we exit See Stevens "advanced programming in unix env" for details */ shmctl(shmid, IPC_RMID, 0); memset(ret, 0, size); return ret; } /**************************************************************************** similar to string_sub() but allows for any character to be substituted. Use with caution! ****************************************************************************/ void all_string_sub(char *s,const char *pattern,const char *insert) { char *p; size_t ls,lp,li; if (!insert || !pattern || !s) return; ls = strlen(s); lp = strlen(pattern); li = strlen(insert); if (!*pattern) return; while (lp <= ls && (p = strstr(s,pattern))) { memmove(p+li,p+lp,ls + 1 - (((int)(p-s)) + lp)); memcpy(p, insert, li); s = p + li; ls += (li-lp); } } /**************************************************************************** Get the next token from a string, return False if none found handles double-quotes. Based on a routine by GJ...@VI.... Extensively modified by And...@an... ****************************************************************************/ BOOL next_token(char **ptr,char *buff,char *sep) { static char *last_ptr=NULL; char *s; BOOL quoted; if (!ptr) ptr = &last_ptr; if (!ptr) return(False); s = *ptr; /* default to simple separators */ if (!sep) sep = " \t\n\r"; /* find the first non sep char */ while(*s && strchr(sep,*s)) s++; /* nothing left? */ if (! *s) return(False); /* copy over the token */ for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++) { if (*s == '\"') quoted = !quoted; else *buff++ = *s; } *ptr = (*s) ? s+1 : s; *buff = 0; last_ptr = *ptr; return(True); } /* return a timeval for the current time */ struct timeval timeval_current(void) { struct timeval tv; gettimeofday(&tv, NULL); return tv; } /* return the number of seconds elapsed since a given time */ double timeval_elapsed(struct timeval *tv) { struct timeval tv2 = timeval_current(); return (tv2.tv_sec - tv->tv_sec) + (tv2.tv_usec - tv->tv_usec)*1.0e-6; } /* return the number of seconds elapsed since a given time */ double timeval_elapsed2(struct timeval *tv1, struct timeval *tv2) { return (tv2->tv_sec - tv1->tv_sec) + (tv2->tv_usec - tv1->tv_usec)*1.0e-6; } --- NEW FILE: INSTALL --- Quick guide to installing/running dbench & co: 1) Run 'make' in the source directory 2) cd into the directory in which you wish to run the benchmark 3) either copy client.txt into that directory, or specify it's path with -c 4) run the appropriate benchmark program --- NEW FILE: client.txt --- Deltree "\clients\client1" NT_STATUS_OK Mkdir "\clients" NT_STATUS_OK NTCreateX "\clients\client1" 0x1 0x2 16385 NT_STATUS_OK Close 16385 NT_STATUS_OK NTCreateX "\clients\client1\mixfile" 0x40 0x1 9935 NT_STATUS_OBJECT_NAME_NOT_FOUND QUERY_PATH_INFORMATION "\clients\client1\~dmtmp" 1004 NT_STATUS_OBJECT_NAME_NOT_FOUND FIND_FIRST "\clients\client1\FILLER.*" 260 1366 0 NT_STATUS_NO_SUCH_FILE NTCreateX "\clients\client1\~dmtmp" 0x1 0x2 9937 NT_STATUS_OK Close 9937 NT_STATUS_OK NTCreateX "\clients\client1\filler.000" 0x40 0x2 9938 NT_STATUS_OK QUERY_FS_INFORMATION 1 NT_STATUS_OK WriteX 9938 65534 1 1 NT_STATUS_OK QUERY_FILE_INFORMATION 9938 258 NT_STATUS_OK WriteX 9938 0 65536 65536 NT_STATUS_OK WriteX 9938 65536 65536 65536 NT_STATUS_OK WriteX 9938 131072 65536 65536 NT_STATUS_OK WriteX 9938 196608 65536 65536 NT_STATUS_OK WriteX 9938 262144 65536 65536 NT_STATUS_OK WriteX 9938 327680 65536 65536 NT_STATUS_OK [...458305 lines suppressed...] FIND_FIRST "\clients\client1\~dmtmp\SEED\*" 260 1366 5 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\*" 260 1366 11 NT_STATUS_OK NTCreateX "\clients\client1\mixfile" 0x40 0x5 13985 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\*" 260 1366 11 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\WORD\*" 260 1366 5 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\EXCEL\*" 260 1366 4 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\PWRPNT\*" 260 1366 7 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\COREL\*" 260 1366 13 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\WORDPRO\*" 260 1366 5 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\PM\*" 260 1366 5 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\PARADOX\*" 260 1366 22 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\ACCESS\*" 260 1366 3 NT_STATUS_OK FIND_FIRST "\clients\client1\~dmtmp\SEED\*" 260 1366 5 NT_STATUS_OK FIND_FIRST "\clients\client1\FILLER.*" 260 1366 5 NT_STATUS_OK WriteX 13985 3 1 1 NT_STATUS_OK QUERY_FILE_INFORMATION 13985 258 NT_STATUS_OK WriteX 13985 0 4 4 NT_STATUS_OK WriteX 13985 4 8 8 NT_STATUS_OK Close 13985 NT_STATUS_OK Deltree "\clients\client1" NT_STATUS_OK --- NEW FILE: dbench.h --- /* dbench version 2 Copyright (C) Andrew Tridgell 1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <ctype.h> #include <dirent.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/socket.h> #include <fcntl.h> #include <time.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/mman.h> #ifdef HAVE_SYS_VFS_H #include <sys/vfs.h> #endif #ifdef HAVE_SYS_STATVFS_H #include <sys/statvfs.h> #endif #include <sys/param.h> #ifdef HAVE_SYS_MOUNT_H #include <sys/mount.h> #endif #include <utime.h> #include <errno.h> #include <strings.h> #ifdef HAVE_STDINT_H #include <stdint.h> #endif #include <netinet/in.h> #include <netinet/tcp.h> #include <netdb.h> #if HAVE_ATTR_XATTR_H #include <attr/xattr.h> #elif HAVE_SYS_XATTR_H #include <sys/xattr.h> #elif HAVE_SYS_ATTRIBUTES_H #include <sys/attributes.h> #endif #ifdef HAVE_SYS_EXTATTR_H #include <sys/extattr.h> #endif #ifdef HAVE_SYS_UIO_H #include <sys/uio.h> #endif #ifndef MSG_WAITALL #define MSG_WAITALL 0x100 #endif #define PRINT_FREQ 1 #ifndef MIN #define MIN(x,y) ((x)<(y)?(x):(y)) #endif #define TCP_PORT 7003 #define TCP_OPTIONS "TCP_NODELAY SO_REUSEADDR" #define BOOL int #define True 1 #define False 0 #define uint32 unsigned struct child_struct { int id; int nprocs; int status; int failed; int line; int done; int cleanup; const char *directory; double bytes; double bytes_done_warmup; }; /* CreateDisposition field. */ #define FILE_SUPERSEDE 0 #define FILE_OPEN 1 #define FILE_CREATE 2 #define FILE_OPEN_IF 3 #define FILE_OVERWRITE 4 #define FILE_OVERWRITE_IF 5 /* CreateOptions field. */ #define FILE_DIRECTORY_FILE 0x0001 #define FILE_WRITE_THROUGH 0x0002 #define FILE_SEQUENTIAL_ONLY 0x0004 #define FILE_NON_DIRECTORY_FILE 0x0040 #define FILE_NO_EA_KNOWLEDGE 0x0200 #define FILE_EIGHT_DOT_THREE_ONLY 0x0400 #define FILE_RANDOM_ACCESS 0x0800 #define FILE_DELETE_ON_CLOSE 0x1000 #ifndef O_DIRECTORY #define O_DIRECTORY 0200000 #endif #include "proto.h" --- NEW FILE: dbench.c --- /* Copyright (C) by Andrew Tridgell <tr...@sa...> 1999, 2001 Copyright (C) 2001 by Martin Pool <mb...@sa...> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* TODO: We could try allowing for different flavours of synchronous operation: data sync and so on. Linux apparently doesn't make any distinction, however, and for practical purposes it probably doesn't matter. On NFSv4 it might be interesting, since the client can choose what kind it wants for each OPEN operation. */ #include "dbench.h" int sync_open = 0, sync_dirs = 0; char *tcp_options = TCP_OPTIONS; static int timelimit = 600, warmup; static const char *directory = "."; static char *loadfile = DATADIR "/client.txt"; static struct timeval tv_start; static struct timeval tv_end; #if HAVE_EA_SUPPORT int ea_enable=0; #endif static FILE *open_loadfile(void) { FILE *f; if ((f = fopen(loadfile, "rt")) != NULL) return f; fprintf(stderr, "dbench: error opening '%s': %s\n", loadfile, strerror(errno)); return NULL; } static struct child_struct *children; static void sigcont(int sig) { (void)sig; } static void sig_alarm(int sig) { double total_bytes = 0; int total_lines = 0; int i; int nprocs = children[0].nprocs; int in_warmup = 0; double t; static int in_cleanup; (void)sig; for (i=0;i<nprocs;i++) { total_bytes += children[i].bytes - children[i].bytes_done_warmup; if (children[i].bytes == 0) { in_warmup = 1; } total_lines += children[i].line; } t = timeval_elapsed(&tv_start); if (!in_warmup && warmup>0 && t > warmup) { tv_start = timeval_current(); warmup = 0; for (i=0;i<nprocs;i++) { children[i].bytes_done_warmup = children[i].bytes; } goto next; } if (t < warmup) { in_warmup = 1; } else if (!in_warmup && !in_cleanup && t > timelimit) { for (i=0;i<nprocs;i++) { children[i].done = 1; } tv_end = timeval_current(); in_cleanup = 1; } if (t < 1) { goto next; } if (in_warmup) { printf("%4d %8d %7.2f MB/sec warmup %3.0f sec \n", nprocs, total_lines/nprocs, 1.0e-6 * total_bytes / t, t); } else if (in_cleanup) { printf("%4d %8d %7.2f MB/sec cleanup %3.0f sec \n", nprocs, total_lines/nprocs, 1.0e-6 * total_bytes / t, t); } else { printf("%4d %8d %7.2f MB/sec execute %3.0f sec \n", nprocs, total_lines/nprocs, 1.0e-6 * total_bytes / t, t); } fflush(stdout); next: signal(SIGALRM, sig_alarm); alarm(PRINT_FREQ); } /* this creates the specified number of child processes and runs fn() in all of them */ static void create_procs(int nprocs, void (*fn)(struct child_struct *, const char *)) { int i, status; int synccount; struct timeval tv; FILE *load; load = open_loadfile(); if (load == NULL) { exit(1); } signal(SIGCONT, sigcont); synccount = 0; if (nprocs < 1) { fprintf(stderr, "create %d procs? you must be kidding.\n", nprocs); return; } children = shm_setup(sizeof(struct child_struct)*nprocs); if (!children) { printf("Failed to setup shared memory\n"); return; } memset(children, 0, sizeof(*children)*nprocs); for (i=0;i<nprocs;i++) { children[i].id = i; children[i].nprocs = nprocs; children[i].cleanup = 0; children[i].directory = directory; } for (i=0;i<nprocs;i++) { if (fork() == 0) { setlinebuf(stdout); nb_setup(&children[i]); children[i].status = getpid(); pause(); fn(&children[i], loadfile); _exit(0); } } tv = timeval_current(); do { synccount = 0; for (i=0;i<nprocs;i++) { if (children[i].status) synccount++; } if (synccount == nprocs) break; usleep(100000); } while (timeval_elapsed(&tv) < 30); if (synccount != nprocs) { printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount); return; } printf("%d clients started\n", nprocs); kill(0, SIGCONT); tv_start = timeval_current(); signal(SIGALRM, sig_alarm); alarm(PRINT_FREQ); for (i=0;i<nprocs;) { if (waitpid(0, &status, 0) == -1) continue; if (WEXITSTATUS(status) != 0) { printf("Child failed with status %d\n", WEXITSTATUS(status)); exit(1); } i++; } alarm(0); sig_alarm(SIGALRM); printf("\n"); } static void show_usage(void) { printf("usage: dbench [OPTIONS] nprocs\n" \ "usage: tbench [OPTIONS] nprocs <server>\n" \ "options:\n" \ " -v show version\n" \ " -t timelimit run time in seconds (default 600)\n" \ " -D directory base directory to run in\n" \ " -c loadfile set location of the loadfile\n" \ " -s synchronous file IO\n" \ " -S synchronous directories (mkdir, unlink...)\n" \ " -x enable EA support\n" \ " -T options set socket options for tbench\n"); exit(1); } static int process_opts(int argc, char **argv, int *nprocs) { int c; extern int sync_open; extern char *server; while ((c = getopt(argc, argv, "vc:sST:t:xD:")) != -1) switch (c) { case 'c': loadfile = optarg; break; case 's': sync_open = 1; break; case 'S': sync_dirs = 1; break; case 'T': tcp_options = optarg; break; case 't': timelimit = atoi(optarg); break; case 'D': directory = optarg; break; case 'v': exit(0); break; case 'x': #if HAVE_EA_SUPPORT ea_enable = 1; #else printf("EA suppport not compiled in\n"); exit(1); #endif break; case '?': if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return 0; default: abort (); } if (!argv[optind]) return 0; *nprocs = atoi(argv[optind++]); if (argv[optind]) server = argv[optind++]; return 1; } int main(int argc, char *argv[]) { int nprocs; double total_bytes = 0; double t; int i; printf("dbench version %s - Copyright Andrew Tridgell 1999-2004\n\n", VERSION); if (!process_opts(argc, argv, &nprocs)) show_usage(); warmup = timelimit / 5; printf("Running for %d seconds with load '%s' and minimum warmup %d secs\n", timelimit, loadfile, warmup); create_procs(nprocs, child_run); for (i=0;i<nprocs;i++) { total_bytes += children[i].bytes - children[i].bytes_done_warmup; } t = timeval_elapsed2(&tv_start, &tv_end); printf("Throughput %g MB/sec%s%s %d procs\n", 1.0e-6 * total_bytes / t, sync_open ? " (sync open)" : "", sync_dirs ? " (sync dirs)" : "", nprocs); return 0; } --- NEW FILE: proto.h --- #ifndef _PROTO_H_ #define _PROTO_H_ /* This file is automatically generated with "make proto". DO NOT EDIT */ /* The following definitions come from child.c */ void child_run(struct child_struct *child, const char *loadfile); /* The following definitions come from dbench.c */ /* The following definitions come from fileio.c */ void nb_setup(struct child_struct *child); void nb_unlink(struct child_struct *child, char *fname, int attr, const char *status); void nb_mkdir(struct child_struct *child, char *dname, const char *status); void nb_rmdir(struct child_struct *child, char *fname, const char *status); void nb_createx(struct child_struct *child, const char *fname, uint32_t create_options, uint32_t create_disposition, int fnum, const char *status); void nb_writex(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status); void nb_readx(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status); void nb_close(struct child_struct *child, int handle, const char *status); void nb_rename(struct child_struct *child, char *old, char *new, const char *status); void nb_flush(struct child_struct *child, int handle, const char *status); void nb_qpathinfo(struct child_struct *child, const char *fname, int level, const char *status); void nb_qfileinfo(struct child_struct *child, int handle, int level, const char *status); void nb_qfsinfo(struct child_struct *child, int level, const char *status); void nb_findfirst(struct child_struct *child, char *fname, int level, int maxcnt, int count, const char *status); void nb_cleanup(struct child_struct *child); void nb_deltree(struct child_struct *child, char *dname); void nb_sfileinfo(struct child_struct *child, int handle, int level, const char *status); void nb_lockx(struct child_struct *child, int handle, uint32_t offset, int size, const char *status); void nb_unlockx(struct child_struct *child, int handle, uint32_t offset, int size, const char *status); void nb_sleep(struct child_struct *child, int usec, const char *status); /* The following definitions come from io.c */ void do_unlink(char *fname); void expand_file(int fd, int size); void do_open(char *fname, int handle, int size); void do_write(int handle, int size, int offset); void do_read(int handle, int size, int offset); void do_close(int handle); void do_mkdir(char *fname); void do_rmdir(char *fname); void do_rename(char *old, char *new); void do_stat(char *fname, int size); void do_create(char *fname, int size); /* The following definitions come from sockio.c */ void nb_setup(struct child_struct *child); void nb_unlink(struct child_struct *child, char *fname, int attr, const char *status); void nb_mkdir(struct child_struct *child, char *dname, const char *status); void nb_rmdir(struct child_struct *child, char *fname, const char *status); void nb_createx(struct child_struct *child, const char *fname, uint32_t create_options, uint32_t create_disposition, int fnum, const char *status); void nb_writex(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status); void nb_readx(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status); void nb_close(struct child_struct *child, int handle, const char *status); void nb_rename(struct child_struct *child, char *old, char *new, const char *status); void nb_flush(struct child_struct *child, int handle, const char *status); void nb_qpathinfo(struct child_struct *child, const char *fname, int level, const char *status); void nb_qfileinfo(struct child_struct *child, int handle, int level, const char *status); void nb_qfsinfo(struct child_struct *child, int level, const char *status); void nb_findfirst(struct child_struct *child, char *fname, int level, int maxcnt, int count, const char *status); void nb_cleanup(struct child_struct *child); void nb_deltree(struct child_struct *child, char *dname); void nb_sfileinfo(struct child_struct *child, int handle, int level, const char *status); void nb_lockx(struct child_struct *child, int handle, uint32_t offset, int size, const char *status); void nb_unlockx(struct child_struct *child, int handle, uint32_t offset, int size, const char *status); void nb_sleep(struct child_struct *child, int usec, const char *status); /* The following definitions come from socklib.c */ int open_socket_in(int type, int port); int open_socket_out(char *host, int port); void set_socket_options(int fd, char *options); int read_sock(int s, char *buf, int size); int write_sock(int s, char *buf, int size); /* The following definitions come from system.c */ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size); ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size); int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags); /* The following definitions come from tbench_srv.c */ /* The following definitions come from util.c */ void *shm_setup(int size); void all_string_sub(char *s,const char *pattern,const char *insert); BOOL next_token(char **ptr,char *buff,char *sep); struct timeval timeval_current(void); double timeval_elapsed(struct timeval *tv); double timeval_elapsed2(struct timeval *tv1, struct timeval *tv2); #endif /* _PROTO_H_ */ --- NEW FILE: README --- Emulating Netbench ================== Netbench is a terrible benchmark, but it's an "industry standard" and it's what is used in the press to rate windows fileservers like Samba and WindowsNT. The big problem with netbench for the open source community is that very few people who work on open source software have the facilities to run it properly. You need a lab with between 60 and 150 windows PC, all on switched fast ethernet and a really grunty server (say a quad xeon with 1GB ram and hardware raid). Then you need some way to nurse all those machines along so they will run a very fussy benchmark suite without crashing. Not easy and very expensive. Only one person in the open source community that I know of has access to such a lab (Jeremy Allison at SGI). In order for the development methodologies of the open source community to work we need to be able to run this benchmark in an environment that a bunch of us have access to. We need the source to the benchmark so we can see what it does. We need to be able to split it into pieces to look for individual bottlenecks. In short, we need to open up netbench to the masses. To do this I have written three tools, dbench, tbench and smbtorture. All three read a load description file called client.txt that was derived from a network sniffer dump of a real netbench run. client.txt is about 4MB and describes the 90 thousand operations that a netbench client does in a typical netbench run. They parse client.txt and use it to produce the same load without having to buy a huge lab. They can simulate any number of simultaneous clients. client.txt must either be in the working directory, or specified on the command line with the -c option. dbench ------ dbench produces only the filesystem load. It does all the same IO calls that the smbd server in Samba would produce when confronted with a netbench run. It does no networking calls. You can get dbench from ftp://samba.org/pub/tridge/dbench/ You run it as "dbench N" where N is the number of clients to simulate. It gives out three numbers like this (this is from a 144 client run on a quad xeon box): Throughput 40.6701 MB/sec (NB=50.8376 MB/sec 406.701 MBit/sec) the first is the true throughput as seen by dbench. The second and third numbers are "netbench scaled" numbers that give the throughput that would be seen by Win9X boxes after taking into account the client file cacheing performed by oplocks. They are given in both MB/sec and MBit/sec as different netbench reports use different scales. tbench ------ tbench produces only the TCP and process load. It does the same socket calls that smbd would do under a netbench load. It does no filesystem calls. The idea behind tbench is to eliminate smbd from the netbench test, as though the smbd code could be made infinately fast. The throughput results of tbench tell us how fast a netbench run could go if we eliminated all filesystem IO and SMB packet processing. tbench is built as part of the dbench package. To run tbench first run tbench_srv on the server. Then run "tbench N SERVER" on the client. N is the number of clients to simulate and SERVER is the hostname of the server. The results are given in the same format as dbench. smbtorture ---------- smbtorture is the stress tester from the Samba suite. I've recently added a stress test that allows you to simulate the full netbench benchmark, including all network traffic and filesystem IO. To run smbtorture you first need to install Samba version 2.0.X. The binary distrubtions at ftp://ftp.samba.org/pub/samba/bin-pkgs/redhat/ would do fine if you don't want to compile it yourself. Then setup a netbench share on the fastest disk you have, making sure you have at least 25MB free per simulated client. The simplest smb.conf would look something like this: [global] security = share [netbench] path = /data/netbench read only = no guest ok = yes Then you need smbtorture. You can either grab a precompiled i386 Redhat5.2 binary from ftp://samba.org/pub/tridge/dbench/smbtorture.gz or you can follow the instructions at http://samba.org/cvs.html to download the SAMBA_2_0 branch of the Samba cvs tree and use "make smbtorture" to build it. Finally, you'll need client.txt from ftp://samba.org/pub/tridge/dbench/dbench.tgz in the same directory that you run smbtorture from. To run it you do this: smbtorture //localhost/netbench -U% -N 32 NBW95 that will run a 32 client load. You can, of course, also run smbtorture against a dfferent SMB server (such as a NT server) to give comparitive results for any client load that the server can handle. Even better is to run smbtorture on one machine and smbd on another, connected by a very fast network (such as gigabit ethernet). That will stop the smbtorture code itself from loading the server and will also test the network driver instead of the loopback driver. results ------- To give you an idea of what to expect here are some results on a quad xeon machine running Linux 2.2.9 with 1GB of memory (it has 4GB but Linux only uses 1GB by default). The machine also has a 45GB hardware raid system and a Alteon AceNIC gigabit network card. The results below are in netbench MB/sec (the NB= number in the result). Multiply by 8 to get the MBit/sec numbers that Mindcraft used in their graphs. The first column is the number of simulated clients, the second is the result. With dbench I get: 16 118 32 103 48 81 64 74 80 67 96 57 112 57 128 54 With tbench on loopback I get: 16 31 32 30 48 29 64 29 80 28 With tbench running across the gigabit network (using a dual processor Origin200 as the client) I get: 16 29 32 29 48 29 64 29 With smbtorture running over loopback I get: 16 18 32 18 48 18 64 17 80 16 With smbtorture running across the gigabit network (using a dual processor Origin200 as the client) I get: 16 16 32 20 48 21 64 20 80 19 With smbtorture running across the gigabit network but with smbd modified so that write_file() and read_file() are null operations (which eliminates the file IO) I get: 16 17 32 22 48 24 64 24 80 24 The above results show that, at least for this hardware configuration, the problem isn't the filesystem code or the raid drivers. More tests will be needed to find out exactly what the problem is but it looks like a TCP scaling problem. comparison with NT ------------------ Hopefully Jeremy will be able to run smbtorture against NT on the same hardwre sometime in the next week so we have direct numbers for comparison, but from looking at the mindcraft numbers under netbench we would expect NT to get about the following: 16 8 32 14 48 21 64 27 80 31 so we do well by comparison with small client loads but fall behind quite a lot with large loads. Note that the numbers in the mindcraft report for Linux/Samba are quite a long way behind what I give above because mindcraft did a hopeless job of tuning Linux/Samba. comparison with netbench ------------------------ An initial comparison with real netbench results shows that smbtorture does produce very similar throughput numbers. They aren't exactly the same but they are similar enough for us to target our tuning efforts and expect to see improvements reflected in real netbench runs. When we find something that looks promising we can get Jeremy to run a real netbench test. a quick hack ------------ the tbench results really pointed at the problem being the Linux TCP stack. I made a quick (and very unsafe!) hack to Samba and the Linux kernel to see if I could remove the lock_kernel() in sys_sendto() and sys_recvfrom() for smbd processes by passing a MSG_NOLOCK flag in send() and recv(). That gave an enormous improvement in the loopback tbench results: 16 31->51 32 30->49 48 29->47 64 29->46 80 28->44 and in the loopback smbtorture results I also saw a big improvement: 16 18->26 32 18->27 48 18->26 64 17->25 80 16->24 that's a 50% improvement. I suspect the numbers will be higher with a real netbench run as it won't have the overhead of running 80 smbtorture clients on the same box as the server. realistic load? --------------- One question some people may ask is whether the above represents a realistic load on a fileserver. It doesn't. Nearly 90% of the read/write IO operations in netbench are writes whereas in a "normal" office load reads dominate. Also, the load is *much* higher than a normal office PC would put on a server. There aren't many office PCs that write over a hundred megabytes of data to a server in a few minutes, unless maybe they are copying a CD. That doesn't mean the benchmark is useless, it just means you shouldn't use this for purchasing decisions unless you really understand the results and how they relate to your environment. license ------- smbtorture and dbench are released under the terms of the GNU Public License version 2 or later. Andrew Tridgell tr...@sa... --- NEW FILE: socklib.c --- /* dbench version 2 Copyright (C) Andrew Tridgell 1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dbench.h" /**************************************************************************** open a socket of the specified type, port and address for incoming data ****************************************************************************/ int open_socket_in(int type, int port) { struct sockaddr_in sock; int res; int one=1; extern char *tcp_options; memset((char *)&sock,0, sizeof(sock)); sock.sin_port = htons(port); sock.sin_family = AF_INET; sock.sin_addr.s_addr = 0; res = socket(AF_INET, type, 0); if (res == -1) { fprintf(stderr, "socket failed\n"); return -1; } setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); /* now we've got a socket - we need to bind it */ if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) { return(-1); } set_socket_options(res, tcp_options); return res; } /* open a socket to a tcp remote host with the specified port based on code from Warren */ int open_socket_out(char *host, int port) { int type = SOCK_STREAM; struct sockaddr_in sock_out; int res; struct hostent *hp; extern char *tcp_options; res = socket(PF_INET, type, 0); if (res == -1) { return -1; } hp = gethostbyname(host); if (!hp) { fprintf(stderr,"unknown host: %s\n", host); return -1; } memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length); sock_out.sin_port = htons(port); sock_out.sin_family = PF_INET; set_socket_options(res, tcp_options); if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) { close(res); fprintf(stderr,"failed to connect to %s - %s\n", host, strerror(errno)); return -1; } return res; } enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; static const struct { char *name; int level; int option; int value; int opttype; } socket_options[] = { {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, #ifdef TCP_NODELAY {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, #endif #ifdef IPTOS_LOWDELAY {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, #endif #ifdef IPTOS_THROUGHPUT {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, #endif #ifdef SO_SNDBUF {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, #endif #ifdef SO_RCVBUF {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, #endif #ifdef SO_SNDLOWAT {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, #endif #ifdef SO_RCVLOWAT {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, #endif #ifdef SO_SNDTIMEO {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, #endif #ifdef SO_RCVTIMEO {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, #endif {NULL,0,0,0,0}}; /**************************************************************************** set user socket options ****************************************************************************/ void set_socket_options(int fd, char *options) { char tok[200]; while (next_token(&options,tok," \t,")) { int ret=0,i; int value = 1; char *p; BOOL got_value = False; if ((p = strchr(tok,'='))) { *p = 0; value = atoi(p+1); got_value = True; } for (i=0;socket_options[i].name;i++) if (strcasecmp(socket_options[i].name,tok)==0) break; if (!socket_options[i].name) { fprintf(stderr, "Unknown socket option %s\n",tok); continue; } switch (socket_options[i].opttype) { case OPT_BOOL: case OPT_INT: ret = setsockopt(fd,socket_options[i].level, socket_options[i].option,(char *)&value,sizeof(int)); break; case OPT_ON: if (got_value) fprintf(stderr,"syntax error - %s does not take a value\n",tok); { int on = socket_options[i].value; ret = setsockopt(fd,socket_options[i].level, socket_options[i].option,(char *)&on,sizeof(int)); } break; } if (ret != 0) fprintf(stderr, "Failed to set socket option %s\n",tok); } } int read_sock(int s, char *buf, int size) { int total=0; while (size) { int r = recv(s, buf, size, MSG_WAITALL); if (r <= 0) { if (r == -1) perror("recv"); break; } buf += r; size -= r; total += r; } return total; } int write_sock(int s, char *buf, int size) { int total=0; while (size) { int r = send(s, buf, size, 0); if (r <= 0) { if (r == -1) perror("send"); break; } buf += r; size -= r; total += r; } return total; } --- NEW FILE: fileio.c --- /* dbench version 2 Copyright (C) 1999 by Andrew Tridgell <tr...@sa...> Copyright (C) 2001 by Martin Pool <mb...@sa...> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dbench.h" #define MAX_FILES 200 char *server = NULL; extern int sync_open, sync_dirs; static struct { char *name; int fd; int handle; } ftable[MAX_FILES]; static int find_handle(struct child_struct *child, int handle) { int i; for (i=0;i<MAX_FILES;i++) { if (ftable[i].handle == handle) return i; } printf("(%d) ERROR: handle %d was not found\n", child->line, handle); exit(1); } /* Find the directory holding a file, and flush it to disk. We do this in -S mode after a directory-modifying mode, to simulate the way knfsd tries to flush directories. MKDIR and similar operations are meant to be synchronous on NFSv2. */ static void sync_parent(char *fname) { char *copy_name; int dir_fd; char *slash; if (strchr(fname, '/')) { copy_name = strdup(fname); slash = strrchr(copy_name, '/'); *slash = '\0'; } else { copy_name = strdup("."); } dir_fd = open(copy_name, O_RDONLY); if (dir_fd == -1) { printf("open directory \"%s\" for sync failed: %s\n", copy_name, strerror(errno)); } else { #if defined(HAVE_FDATASYNC) if (fdatasync(dir_fd) == -1) { #else if (fsync(dir_fd) == -1) { #endif printf("datasync directory \"%s\" failed: %s\n", copy_name, strerror(errno)); } if (close(dir_fd) == -1) { printf("close directory failed: %s\n", strerror(errno)); } } free(copy_name); } static void xattr_fd_read_hook(int fd) { #if HAVE_EA_SUPPORT extern int ea_enable; char buf[44]; if (ea_enable) { memset(buf, 0, sizeof(buf)); sys_fgetxattr(fd, "user.DosAttrib", buf, sizeof(buf)); } #else (void)fd; #endif } static void xattr_fname_read_hook(const char *fname) { #if HAVE_EA_SUPPORT extern int ea_enable; if (ea_enable) { char buf[44]; sys_getxattr(fname, "user.DosAttrib", buf, sizeof(buf)); } #else (void)fname; #endif } static void xattr_fd_write_hook(int fd) { #if HAVE_EA_SUPPORT extern int ea_enable; if (ea_enable) { struct timeval tv; char buf[44]; sys_fgetxattr(fd, "user.DosAttrib", buf, sizeof(buf)); memset(buf, 0, sizeof(buf)); /* give some probability of sharing */ if (random() % 10 < 2) { *(time_t *)buf = time(NULL); } else { gettimeofday(&tv, NULL); memcpy(buf, &tv, sizeof(tv)); } if (sys_fsetxattr(fd, "user.DosAttrib", buf, sizeof(buf), 0) != 0) { printf("fsetxattr failed - %s\n", strerror(errno)); exit(1); } } #else (void)fd; #endif } static int expected_status(const char *status) { if (strcmp(status, "NT_STATUS_OK") == 0) return 0; return -1; } /* simulate pvfs_resolve_name() */ static void resolve_name(const char *name) { struct stat st; char *dname, *fname; DIR *dir; char *p; struct dirent *d; if (stat(name, &st) == 0) { xattr_fname_read_hook(name); return; } dname = strdup(name); p = strrchr(dname, '/'); if (!p) return; *p = 0; fname = p+1; dir = opendir(dname); if (!dir) { free(dname); return; } while ((d = readdir(dir))) { if (strcasecmp(fname, d->d_name) == 0) break; } closedir(dir); free(dname); } static void failed(struct child_struct *child) { child->failed = 1; printf("ERROR: child %d failed\n", child->id); exit(1); } void nb_setup(struct child_struct *child) { (void)child; } void nb_unlink(struct child_struct *child, char *fname, int attr, const char *status) { (void)attr; resolve_name(fname); if (unlink(fname) != expected_status(status)) { printf("(%d) unlink %s failed (%s) - expected %s\n", child->line, fname, strerror(errno), status); failed(child); } if (sync_dirs) sync_parent(fname); } void nb_mkdir(struct child_struct *child, char *dname, const char *status) { (void)child; (void)status; resolve_name(dname); mkdir(dname, 0777); } void nb_rmdir(struct child_struct *child, char *fname, const char *status) { resolve_name(fname); if (rmdir(fname) != expected_status(status)) { printf("(%d) rmdir %s failed (%s) - expected %s\n", child->line, fname, strerror(errno), status); failed(child); } if (sync_dirs) sync_parent(fname); } void nb_createx(struct child_struct *child, const char *fname, uint32_t create_options, uint32_t create_disposition, int fnum, const char *status) { int fd, i; int flags = O_RDWR; struct stat st; resolve_name(fname); if (sync_open) flags |= O_SYNC; if (create_disposition == FILE_CREATE) { flags |= O_CREAT; } if (create_disposition == FILE_OVERWRITE || create_disposition == FILE_OVERWRITE_IF) { flags |= O_CREAT | O_TRUNC; } if (create_options & FILE_DIRECTORY_FILE) { /* not strictly correct, but close enough */ mkdir(fname, 0700); } if (create_options & FILE_DIRECTORY_FILE) flags = O_RDONLY|O_DIRECTORY; fd = open(fname, flags, 0600); if (fd == -1) { if (strcmp(status, "NT_STATUS_OK") == 0) { printf("(%d) open %s failed for handle %d (%s)\n", child->line, fname, fnum, strerror(errno)); } return; } if (strcmp(status, "NT_STATUS_OK") != 0) { printf("(%d) open %s succeeded for handle %d\n", child->line, fname, fnum); close(fd); return; } for (i=0;i<MAX_FILES;i++) { if (ftable[i].handle == 0) break; } if (i == MAX_FILES) { printf("file table full for %s\n", fname); exit(1); } ftable[i].name = strdup(fname); ftable[i].handle = fnum; ftable[i].fd = fd; fstat(fd, &st); if (!S_ISDIR(st.st_mode)) { xattr_fd_write_hook(fd); } } void nb_writex(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status) { int i = find_handle(child, handle); void *buf; (void)status; buf = calloc(size, 1); if (pwrite(ftable[i].fd, buf, size, offset) != ret_size) { printf("write failed on handle %d\n", handle); exit(1); } free(buf); child->bytes += size; } void nb_readx(struct child_struct *child, int handle, int offset, int size, int ret_size, const char *status) { int i = find_handle(child, handle); void *buf; (void)status; buf = malloc(size); if (pread(ftable[i].fd, buf, size, offset) != ret_size) { printf("read failed on handle %d\n", handle); } free(buf); child->bytes += size; } void nb_close(struct child_struct *child, int handle, const char *status) { int i = find_handle(child, handle); (void)status; close(ftable[i].fd); ftable[i].handle = 0; if (ftable[i].name) free(ftable[i].name); ftable[i].name = NULL; } void nb_rename(struct child_struct *child, char *old, char *new, const char *status) { resolve_name(old); resolve_name(new); if (rename(old, new) != expected_status(status)) { printf("rename %s %s failed (%s) - expected %s\n", old, new, strerror(errno), status); failed(child); } if (sync_dirs) sync_parent(new); } void nb_flush(struct child_struct *child, int handle, const char *status) { (void)status; find_handle(child, handle); /* noop */ } void nb_qpathinfo(struct child_struct *child, const char *fname, int level, const char *status) { (void)child; (void)level; (void)status; resolve_name(fname); } void nb_qfileinfo(struct child_struct *child, int handle, int level, const char *status) { struct stat st; int i = find_handle(child, handle); (void)child; (void)level; (void)status; fstat(ftable[i].fd, &st); xattr_fd_read_hook(ftable[i].fd); } void nb_qfsinfo(struct child_struct *child, int level, const char *status) { struct statvfs st; (void)level; (void)status; statvfs(child->directory, &st); } void nb_findfirst(struct child_struct *child, char *fname, int level, int maxcnt, int count, const char *status) { DIR *dir; struct dirent *d; char *p; (void)child; (void)level; (void)count; (void)status; resolve_name(fname); if (strpbrk(fname, "<>*?\"") == NULL) { return; } p = strrchr(fname, '/'); if (!p) return; *p = 0; dir = opendir(fname); if (!dir) return; while (maxcnt && (d = readdir(dir))) maxcnt--; closedir(dir); } void nb_cleanup(struct child_struct *child) { char *dname; asprintf(&dname, "%s/clients/client%d", child->directory, child->id); nb_deltree(child, dname); free(dname); asprintf(&dname, "%s%s", child->directory, "/clients"); rmdir(dname); free(dname); } void nb_deltree(struct child_struct *child, char *dname) { char *path; (void)child; asprintf(&path, "/bin/rm -rf %s", dname); system(path); free(path); } void nb_sfileinfo(struct child_struct *child, int handle, int level, const char *status) { int i = find_handle(child, handle); struct utimbuf tm; struct stat st; (void)child; (void)handle; (void)level; (void)status; xattr_fd_read_hook(ftable[i].fd); fstat(ftable[i].fd, &st); tm.actime = st.st_atime - 10; tm.modtime = st.st_mtime - 12; utime(ftable[i].name, &tm); if (!S_ISDIR(st.st_mode)) { xattr_fd_write_hook(ftable[i].fd); } } void nb_lockx(struct child_struct *child, int handle, uint32_t offset, int size, const char *status) { int i = find_handle(child, ... [truncated message content] |
From: Eric V. H. <er...@us...> - 2006-09-19 01:57:26
|
Update of /cvsroot/v9fs/app/dbench In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv26773/dbench Log Message: Directory /cvsroot/v9fs/app/dbench added to the repository |
From: Eric V. H. <er...@us...> - 2006-03-17 19:13:48
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17723 Modified Files: v9fs.c vfs_inode.c Log Message: Sync w/git Index: v9fs.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.c,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -d -r2.5 -r2.6 *** v9fs.c 12 Mar 2006 20:18:53 -0000 2.5 --- v9fs.c 17 Mar 2006 19:13:42 -0000 2.6 *************** *** 456,463 **** { int ret; v9fs_error_init(); ! printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); ret = v9fs_mux_global_init(); --- 456,468 ---- { int ret; + void *mcore; + + mcore = NULL; + if (THIS_MODULE) + mcore = THIS_MODULE->module_core; v9fs_error_init(); ! printk(KERN_INFO "Installing v9fs 9P2000 file system support %p\n", mcore); ret = v9fs_mux_global_init(); Index: vfs_inode.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_inode.c,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -d -r2.7 -r2.8 *** vfs_inode.c 12 Mar 2006 20:55:26 -0000 2.7 --- vfs_inode.c 17 Mar 2006 19:13:42 -0000 2.8 *************** *** 620,623 **** --- 620,624 ---- sb = dir->i_sb; v9ses = v9fs_inode2v9ses(dir); + dentry->d_op = &v9fs_dentry_operations; dirfid = v9fs_fid_lookup(dentry->d_parent); *************** *** 688,693 **** fid->qid = fcall->params.rstat.stat.qid; - - dentry->d_op = &v9fs_dentry_operations; v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); --- 689,692 ---- *************** *** 1285,1288 **** --- 1284,1289 ---- name = __getname(); + if (!name) + return -EINVAL; /* build extension */ if (S_ISBLK(mode)) |
From: Eric V. H. <er...@us...> - 2006-03-16 23:19:11
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28670 Modified Files: 9p.h fcprint.c trans_fd.c Log Message: Sync with standalone git branch. Index: trans_fd.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/trans_fd.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** trans_fd.c 12 Mar 2006 20:18:53 -0000 1.3 --- trans_fd.c 16 Mar 2006 23:19:06 -0000 1.4 *************** *** 95,98 **** --- 95,99 ---- dprintk(DEBUG_ERROR, "blocking write ...\n"); + oldfs = get_fs(); set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ *************** *** 249,254 **** strcpy(sun_server.sun_path, addr); sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); ! ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, ! sizeof(struct sockaddr_un) - 1, 0); if (ret < 0) { eprintk(KERN_ERR, --- 250,255 ---- strcpy(sun_server.sun_path, addr); sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); ! ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, ! sizeof(struct sockaddr_un) - 1, 0); if (ret < 0) { eprintk(KERN_ERR, *************** *** 273,277 **** return; ! ts = xchg(&trans->priv, NULL); if (!ts) --- 274,278 ---- return; ! ts = xchg(&trans->priv, NULL); if (!ts) Index: fcprint.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/fcprint.c,v retrieving revision 2.1 retrieving revision 2.2 diff -C2 -d -r2.1 -r2.2 *** fcprint.c 12 Mar 2006 20:55:26 -0000 2.1 --- fcprint.c 16 Mar 2006 23:19:06 -0000 2.2 *************** *** 45,62 **** if (q->type & V9FS_QTAPPEND) b[n++] = 'a'; - if (q->type & V9FS_QTEXCL) - b[n++] = 'x'; if (q->type & V9FS_QTAUTH) b[n++] = 'A'; if (q->type & V9FS_QTTMP) b[n++] = 't'; if (q->type & V9FS_QTSYMLINK) - b[n++] = 'l'; - if (q->type & V9FS_QTLINK) b[n++] = 'L'; b[n] = '\0'; ! return snprintf(buf, buflen, "(%.16llx %x %s)", (long long int)q->path, ! q->version, b); } --- 45,60 ---- if (q->type & V9FS_QTAPPEND) b[n++] = 'a'; if (q->type & V9FS_QTAUTH) b[n++] = 'A'; + if (q->type & V9FS_QTEXCL) + b[n++] = 'l'; if (q->type & V9FS_QTTMP) b[n++] = 't'; if (q->type & V9FS_QTSYMLINK) b[n++] = 'L'; b[n] = '\0'; ! return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path, ! q->version, b); } *************** *** 74,77 **** --- 72,79 ---- if (perm & V9FS_DMAUTH) b[n++] = 'A'; + if (perm & V9FS_DMEXCL) + b[n++] = 'l'; + if (perm & V9FS_DMTMP) + b[n++] = 't'; if (perm & V9FS_DMDEVICE) b[n++] = 'D'; *************** *** 82,121 **** if (perm & V9FS_DMSYMLINK) b[n++] = 'L'; ! if (perm & V9FS_DMEXCL) ! b[n++] = 'l'; ! if (n > 0) ! b[n++] = '+'; ! b[n] = 0; ! return snprintf(buf, buflen, "%s%03o", b, perm&077); } ! int v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) { int n; ! n = snprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len, st->name.str, st->uid.len, st->uid.str); if (extended) ! n += snprintf(buf+n, buflen-n, "(%d)", st->n_uid); ! n += snprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str); if (extended) ! n += snprintf(buf+n, buflen-n, "(%d)", st->n_gid); ! n += snprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str); if (extended) ! n += snprintf(buf+n, buflen-n, "(%d)", st->n_muid); ! ! n += snprintf(buf+n, buflen-n, " q "); n += v9fs_printqid(buf+n, buflen-n, &st->qid); ! n += snprintf(buf+n, buflen-n, " m "); n += v9fs_printperm(buf+n, buflen-n, st->mode); ! n += snprintf(buf+n, buflen-n, " at %d mt %d l %lld", ! st->atime, st->mtime, (long long int)st->length); if (extended) ! n += snprintf(buf+n, buflen-n, " ext '%.*s'", st->extension.len, st->extension.str); --- 84,119 ---- if (perm & V9FS_DMSYMLINK) b[n++] = 'L'; ! b[n] = '\0'; ! return scnprintf(buf, buflen, "%s%03o", b, perm&077); } ! static int v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) { int n; ! n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len, st->name.str, st->uid.len, st->uid.str); if (extended) ! n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid); ! n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str); if (extended) ! n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid); ! n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str); if (extended) ! n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); ! ! n += scnprintf(buf+n, buflen-n, " q "); n += v9fs_printqid(buf+n, buflen-n, &st->qid); ! n += scnprintf(buf+n, buflen-n, " m "); n += v9fs_printperm(buf+n, buflen-n, st->mode); ! n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", ! st->atime, st->mtime, (long long int) st->length); if (extended) ! n += scnprintf(buf+n, buflen-n, " ext '%.*s'", st->extension.len, st->extension.str); *************** *** 123,127 **** } ! int v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) { --- 121,125 ---- } ! static int v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) { *************** *** 130,142 **** i = n = 0; while (i < datalen) { ! n += snprintf(buf + n, buflen - n, "%02x", data[i]); if (i%4 == 3) ! n += snprintf(buf + n, buflen - n, " "); if (i%32 == 31) ! n += snprintf(buf + n, buflen - n, "\n"); i++; } ! n += snprintf(buf + n, buflen - n, "\n"); return n; --- 128,140 ---- i = n = 0; while (i < datalen) { ! n += scnprintf(buf + n, buflen - n, "%02x", data[i]); if (i%4 == 3) ! n += scnprintf(buf + n, buflen - n, " "); if (i%32 == 31) ! n += scnprintf(buf + n, buflen - n, "\n"); i++; } ! n += scnprintf(buf + n, buflen - n, "\n"); return n; *************** *** 155,159 **** if (!fc) ! return snprintf(buf, buflen, "<NULL>"); type = fc->id; --- 153,157 ---- if (!fc) ! return scnprintf(buf, buflen, "<NULL>"); type = fc->id; *************** *** 163,167 **** switch (type) { case TVERSION: ! ret += snprintf(buf+ret, buflen-ret, "Tversion tag %u msize %u version '%.*s'", tag, fc->params.tversion.msize, fc->params.tversion.version.len, --- 161,165 ---- switch (type) { case TVERSION: ! ret += scnprintf(buf+ret, buflen-ret, "Tversion tag %u msize %u version '%.*s'", tag, fc->params.tversion.msize, fc->params.tversion.version.len, *************** *** 170,175 **** case RVERSION: ! ret += snprintf(buf+ret, buflen-ret, ! "Rversion tag %u msize %u version '%.*s'", tag, fc->params.rversion.msize, fc->params.rversion.version.len, fc->params.rversion.version.str); --- 168,173 ---- case RVERSION: ! ret += scnprintf(buf+ret, buflen-ret, ! "Rversion tag %u msize %u version '%.*s'", tag, fc->params.rversion.msize, fc->params.rversion.version.len, fc->params.rversion.version.str); *************** *** 177,196 **** case TAUTH: ! ret += snprintf(buf+ret, buflen-ret, ! "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, fc->params.tauth.afid, fc->params.tauth.uname.len, ! fc->params.tauth.uname.str, fc->params.tauth.aname.len, fc->params.tauth.aname.str); break; case RAUTH: ! ret += snprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); break; case TATTACH: ! ret += snprintf(buf+ret, buflen-ret, "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", ! tag, fc->params.tattach.fid, fc->params.tattach.afid, fc->params.tattach.uname.len, fc->params.tattach.uname.str, fc->params.tattach.aname.len, fc->params.tattach.aname.str); --- 175,194 ---- case TAUTH: ! ret += scnprintf(buf+ret, buflen-ret, ! "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, fc->params.tauth.afid, fc->params.tauth.uname.len, ! fc->params.tauth.uname.str, fc->params.tauth.aname.len, fc->params.tauth.aname.str); break; case RAUTH: ! ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); break; case TATTACH: ! ret += scnprintf(buf+ret, buflen-ret, "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", ! tag, fc->params.tattach.fid, fc->params.tattach.afid, fc->params.tattach.uname.len, fc->params.tattach.uname.str, fc->params.tattach.aname.len, fc->params.tattach.aname.str); *************** *** 198,230 **** case RATTACH: ! ret += snprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); break; case RERROR: ! ret += snprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", ! tag, fc->params.rerror.error.len, fc->params.rerror.error.str); if (extended) ! ret += snprintf(buf+ret, buflen-ret, " ecode %d\n", fc->params.rerror.errno); break; case TFLUSH: ! ret += snprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", tag, fc->params.tflush.oldtag); break; case RFLUSH: ! ret += snprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); break; case TWALK: ! ret += snprintf(buf+ret, buflen-ret, ! "Twalk tag %u fid %d newfid %d nwname %d", tag, ! fc->params.twalk.fid, fc->params.twalk.newfid, fc->params.twalk.nwname); for(i = 0; i < fc->params.twalk.nwname; i++) ! ret += snprintf(buf+ret, buflen-ret," '%.*s'", fc->params.twalk.wnames[i].len, fc->params.twalk.wnames[i].str); --- 196,228 ---- case RATTACH: ! ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); break; case RERROR: ! ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", ! tag, fc->params.rerror.error.len, fc->params.rerror.error.str); if (extended) ! ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", fc->params.rerror.errno); break; case TFLUSH: ! ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", tag, fc->params.tflush.oldtag); break; case RFLUSH: ! ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); break; case TWALK: ! ret += scnprintf(buf+ret, buflen-ret, ! "Twalk tag %u fid %d newfid %d nwname %d", tag, ! fc->params.twalk.fid, fc->params.twalk.newfid, fc->params.twalk.nwname); for(i = 0; i < fc->params.twalk.nwname; i++) ! ret += scnprintf(buf+ret, buflen-ret," '%.*s'", fc->params.twalk.wnames[i].len, fc->params.twalk.wnames[i].str); *************** *** 232,346 **** case RWALK: ! ret += snprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", tag, fc->params.rwalk.nwqid); for(i = 0; i < fc->params.rwalk.nwqid; i++) ! ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rwalk.wqids[i]); break; ! case TOPEN: ! ret += snprintf(buf+ret, buflen-ret, "Topen tag %u fid %d mode %d", tag, fc->params.topen.fid, fc->params.topen.mode); break; ! case ROPEN: ! ret += snprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); ! ret += snprintf(buf+ret, buflen-ret," iounit %d", fc->params.ropen.iounit); break; ! case TCREATE: ! ret += snprintf(buf+ret, buflen-ret, ! "Tcreate tag %u fid %d name '%.*s' perm ", tag, fc->params.tcreate.fid, fc->params.tcreate.name.len, fc->params.tcreate.name.str); ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm); ! ret += snprintf(buf+ret, buflen-ret, " mode %d", fc->params.tcreate.mode); break; ! case RCREATE: ! ret += snprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid); ! ret += snprintf(buf+ret, buflen-ret, " iounit %d", fc->params.rcreate.iounit); break; ! case TREAD: ! ret += snprintf(buf+ret, buflen-ret, ! "Tread tag %u fid %d offset %lld count %u", tag, ! fc->params.tread.fid, ! (long long int)fc->params.tread.offset, fc->params.tread.count); break; ! case RREAD: ! ret += snprintf(buf+ret, buflen-ret, ! "Rread tag %u count %u data ", tag, fc->params.rread.count); ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, fc->params.rread.count); break; ! case TWRITE: ! ret += snprintf(buf+ret, buflen-ret, ! "Twrite tag %u fid %d offset %lld count %u data ", ! tag, fc->params.twrite.fid, ! (long long int)fc->params.twrite.offset, fc->params.twrite.count); ! ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, fc->params.twrite.count); break; ! case RWRITE: ! ret += snprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", tag, fc->params.rwrite.count); break; ! case TCLUNK: ! ret += snprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", tag, fc->params.tclunk.fid); break; ! case RCLUNK: ! ret += snprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); break; ! case TREMOVE: ! ret += snprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", tag, fc->params.tremove.fid); break; ! case RREMOVE: ! ret += snprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); break; ! case TSTAT: ! ret += snprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", tag, fc->params.tstat.fid); break; ! case RSTAT: ! ret += snprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, extended); break; ! case TWSTAT: ! ret += snprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", tag, fc->params.twstat.fid); ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, extended); break; ! case RWSTAT: ! ret += snprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); break; default: ! ret += snprintf(buf+ret, buflen-ret, "unknown type %d", type); break; } --- 230,344 ---- case RWALK: ! ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", tag, fc->params.rwalk.nwqid); for(i = 0; i < fc->params.rwalk.nwqid; i++) ! ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rwalk.wqids[i]); break; ! case TOPEN: ! ret += scnprintf(buf+ret, buflen-ret, "Topen tag %u fid %d mode %d", tag, fc->params.topen.fid, fc->params.topen.mode); break; ! case ROPEN: ! ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); ! ret += scnprintf(buf+ret, buflen-ret," iounit %d", fc->params.ropen.iounit); break; ! case TCREATE: ! ret += scnprintf(buf+ret, buflen-ret, ! "Tcreate tag %u fid %d name '%.*s' perm ", tag, fc->params.tcreate.fid, fc->params.tcreate.name.len, fc->params.tcreate.name.str); ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm); ! ret += scnprintf(buf+ret, buflen-ret, " mode %d", fc->params.tcreate.mode); break; ! case RCREATE: ! ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid); ! ret += scnprintf(buf+ret, buflen-ret, " iounit %d", fc->params.rcreate.iounit); break; ! case TREAD: ! ret += scnprintf(buf+ret, buflen-ret, ! "Tread tag %u fid %d offset %lld count %u", tag, ! fc->params.tread.fid, ! (long long int) fc->params.tread.offset, fc->params.tread.count); break; ! case RREAD: ! ret += scnprintf(buf+ret, buflen-ret, ! "Rread tag %u count %u data ", tag, fc->params.rread.count); ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, fc->params.rread.count); break; ! case TWRITE: ! ret += scnprintf(buf+ret, buflen-ret, ! "Twrite tag %u fid %d offset %lld count %u data ", ! tag, fc->params.twrite.fid, ! (long long int) fc->params.twrite.offset, fc->params.twrite.count); ! ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, fc->params.twrite.count); break; ! case RWRITE: ! ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", tag, fc->params.rwrite.count); break; ! case TCLUNK: ! ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", tag, fc->params.tclunk.fid); break; ! case RCLUNK: ! ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); break; ! case TREMOVE: ! ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", tag, fc->params.tremove.fid); break; ! case RREMOVE: ! ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); break; ! case TSTAT: ! ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", tag, fc->params.tstat.fid); break; ! case RSTAT: ! ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, extended); break; ! case TWSTAT: ! ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", tag, fc->params.twstat.fid); ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, extended); break; ! case RWSTAT: ! ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); break; default: ! ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type); break; } Index: 9p.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.h,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** 9p.h 12 Mar 2006 20:18:50 -0000 2.4 --- 9p.h 16 Mar 2006 23:19:05 -0000 2.5 *************** *** 376,379 **** struct v9fs_fcall **rcall); int v9fs_printfcall(char *, int, struct v9fs_fcall *, int); - int v9fs_dumpdata(char *, int, u8 *, int); - int v9fs_printstat(char *, int, struct v9fs_stat *, int); --- 376,377 ---- |
From: Eric V. H. <er...@us...> - 2006-03-12 21:02:51
|
Update of /cvsroot/v9fs/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5697 Modified Files: README Log Message: Updated parameters Index: README =================================================================== RCS file: /cvsroot/v9fs/tests/README,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** README 20 May 2005 19:45:55 -0000 1.1.1.1 --- README 12 Mar 2006 21:02:46 -0000 1.2 *************** *** 1,5 **** Eric's Typical Regressions: cd /var/tmp ! fsx -N 100 -R -W -d testfile ! postmark # and then just type run bonnie -s 1 --- 1,5 ---- Eric's Typical Regressions: cd /var/tmp ! fsx -N 100 -W -d testfile ! echo run | postmark bonnie -s 1 |
From: Eric V. H. <er...@us...> - 2006-03-12 20:55:34
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1736 Modified Files: vfs_dir.c vfs_file.c vfs_inode.c Added Files: fcprint.c Log Message: Sync up snapshot with git tree. Index: vfs_file.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_file.c,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -d -r2.5 -r2.6 *** vfs_file.c 12 Mar 2006 20:18:53 -0000 2.5 --- vfs_file.c 12 Mar 2006 20:55:26 -0000 2.6 *************** *** 72,76 **** eprintk(KERN_WARNING, "newfid fails!\n"); return -ENOSPC; ! } err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); --- 72,76 ---- eprintk(KERN_WARNING, "newfid fails!\n"); return -ENOSPC; ! } err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); *************** *** 84,91 **** dprintk(DEBUG_ERROR, "out of memory\n"); goto clunk_fid; ! } ! /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ ! /* translate open mode appropriately */ omode = v9fs_uflags2omode(file->f_flags); err = v9fs_t_open(v9ses, fid, omode, &fcall); --- 84,91 ---- dprintk(DEBUG_ERROR, "out of memory\n"); goto clunk_fid; ! } ! /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ ! /* translate open mode appropriately */ omode = v9fs_uflags2omode(file->f_flags); err = v9fs_t_open(v9ses, fid, omode, &fcall); Index: vfs_dir.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_dir.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** vfs_dir.c 2 Mar 2006 21:30:17 -0000 2.4 --- vfs_dir.c 12 Mar 2006 20:55:26 -0000 2.5 *************** *** 203,207 **** } - d_drop(filp->f_dentry); return 0; } --- 203,206 ---- Index: vfs_inode.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_inode.c,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -d -r2.6 -r2.7 *** vfs_inode.c 12 Mar 2006 20:18:53 -0000 2.6 --- vfs_inode.c 12 Mar 2006 20:55:26 -0000 2.7 *************** *** 497,504 **** d_instantiate(dentry, inode); if (nd && nd->flags & LOOKUP_OPEN) { - #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) - return -ENOTSUPP; - #else struct v9fs_fid *ffid; struct file *filp; --- 497,502 ---- d_instantiate(dentry, inode); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) if (nd && nd->flags & LOOKUP_OPEN) { struct v9fs_fid *ffid; struct file *filp; *************** *** 520,525 **** ffid->filp = filp; filp->private_data = ffid; - #endif } return 0; --- 518,523 ---- ffid->filp = filp; filp->private_data = ffid; } + #endif return 0; --- NEW FILE: fcprint.c --- /* * linux/fs/9p/fcprint.c * * Print 9P call. * * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to: * Free Software Foundation * 51 Franklin Street, Fifth Floor * Boston, MA 02111-1301 USA * */ #include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/idr.h> #include "debug.h" #include "v9fs.h" #include "9p.h" #include "mux.h" static int v9fs_printqid(char *buf, int buflen, struct v9fs_qid *q) { int n; char b[10]; n = 0; if (q->type & V9FS_QTDIR) b[n++] = 'd'; if (q->type & V9FS_QTAPPEND) b[n++] = 'a'; if (q->type & V9FS_QTEXCL) b[n++] = 'x'; if (q->type & V9FS_QTAUTH) b[n++] = 'A'; if (q->type & V9FS_QTTMP) b[n++] = 't'; if (q->type & V9FS_QTSYMLINK) b[n++] = 'l'; if (q->type & V9FS_QTLINK) b[n++] = 'L'; b[n] = '\0'; return snprintf(buf, buflen, "(%.16llx %x %s)", (long long int)q->path, q->version, b); } static int v9fs_printperm(char *buf, int buflen, int perm) { int n; char b[15]; n = 0; if (perm & V9FS_DMDIR) b[n++] = 'd'; if (perm & V9FS_DMAPPEND) b[n++] = 'a'; if (perm & V9FS_DMAUTH) b[n++] = 'A'; if (perm & V9FS_DMDEVICE) b[n++] = 'D'; if (perm & V9FS_DMSOCKET) b[n++] = 'S'; if (perm & V9FS_DMNAMEDPIPE) b[n++] = 'P'; if (perm & V9FS_DMSYMLINK) b[n++] = 'L'; if (perm & V9FS_DMEXCL) b[n++] = 'l'; if (n > 0) b[n++] = '+'; b[n] = 0; return snprintf(buf, buflen, "%s%03o", b, perm&077); } int v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) { int n; n = snprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len, st->name.str, st->uid.len, st->uid.str); if (extended) n += snprintf(buf+n, buflen-n, "(%d)", st->n_uid); n += snprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str); if (extended) n += snprintf(buf+n, buflen-n, "(%d)", st->n_gid); n += snprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str); if (extended) n += snprintf(buf+n, buflen-n, "(%d)", st->n_muid); n += snprintf(buf+n, buflen-n, " q "); n += v9fs_printqid(buf+n, buflen-n, &st->qid); n += snprintf(buf+n, buflen-n, " m "); n += v9fs_printperm(buf+n, buflen-n, st->mode); n += snprintf(buf+n, buflen-n, " at %d mt %d l %lld", st->atime, st->mtime, (long long int)st->length); if (extended) n += snprintf(buf+n, buflen-n, " ext '%.*s'", st->extension.len, st->extension.str); return n; } int v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) { int i, n; i = n = 0; while (i < datalen) { n += snprintf(buf + n, buflen - n, "%02x", data[i]); if (i%4 == 3) n += snprintf(buf + n, buflen - n, " "); if (i%32 == 31) n += snprintf(buf + n, buflen - n, "\n"); i++; } n += snprintf(buf + n, buflen - n, "\n"); return n; } static int v9fs_printdata(char *buf, int buflen, u8 *data, int datalen) { return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16); } int v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) { int i, ret, type, tag; if (!fc) return snprintf(buf, buflen, "<NULL>"); type = fc->id; tag = fc->tag; ret = 0; switch (type) { case TVERSION: ret += snprintf(buf+ret, buflen-ret, "Tversion tag %u msize %u version '%.*s'", tag, fc->params.tversion.msize, fc->params.tversion.version.len, fc->params.tversion.version.str); break; case RVERSION: ret += snprintf(buf+ret, buflen-ret, "Rversion tag %u msize %u version '%.*s'", tag, fc->params.rversion.msize, fc->params.rversion.version.len, fc->params.rversion.version.str); break; case TAUTH: ret += snprintf(buf+ret, buflen-ret, "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, fc->params.tauth.afid, fc->params.tauth.uname.len, fc->params.tauth.uname.str, fc->params.tauth.aname.len, fc->params.tauth.aname.str); break; case RAUTH: ret += snprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); break; case TATTACH: ret += snprintf(buf+ret, buflen-ret, "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag, fc->params.tattach.fid, fc->params.tattach.afid, fc->params.tattach.uname.len, fc->params.tattach.uname.str, fc->params.tattach.aname.len, fc->params.tattach.aname.str); break; case RATTACH: ret += snprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); break; case RERROR: ret += snprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", tag, fc->params.rerror.error.len, fc->params.rerror.error.str); if (extended) ret += snprintf(buf+ret, buflen-ret, " ecode %d\n", fc->params.rerror.errno); break; case TFLUSH: ret += snprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", tag, fc->params.tflush.oldtag); break; case RFLUSH: ret += snprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); break; case TWALK: ret += snprintf(buf+ret, buflen-ret, "Twalk tag %u fid %d newfid %d nwname %d", tag, fc->params.twalk.fid, fc->params.twalk.newfid, fc->params.twalk.nwname); for(i = 0; i < fc->params.twalk.nwname; i++) ret += snprintf(buf+ret, buflen-ret," '%.*s'", fc->params.twalk.wnames[i].len, fc->params.twalk.wnames[i].str); break; case RWALK: ret += snprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", tag, fc->params.rwalk.nwqid); for(i = 0; i < fc->params.rwalk.nwqid; i++) ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rwalk.wqids[i]); break; case TOPEN: ret += snprintf(buf+ret, buflen-ret, "Topen tag %u fid %d mode %d", tag, fc->params.topen.fid, fc->params.topen.mode); break; case ROPEN: ret += snprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); ret += snprintf(buf+ret, buflen-ret," iounit %d", fc->params.ropen.iounit); break; case TCREATE: ret += snprintf(buf+ret, buflen-ret, "Tcreate tag %u fid %d name '%.*s' perm ", tag, fc->params.tcreate.fid, fc->params.tcreate.name.len, fc->params.tcreate.name.str); ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm); ret += snprintf(buf+ret, buflen-ret, " mode %d", fc->params.tcreate.mode); break; case RCREATE: ret += snprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid); ret += snprintf(buf+ret, buflen-ret, " iounit %d", fc->params.rcreate.iounit); break; case TREAD: ret += snprintf(buf+ret, buflen-ret, "Tread tag %u fid %d offset %lld count %u", tag, fc->params.tread.fid, (long long int)fc->params.tread.offset, fc->params.tread.count); break; case RREAD: ret += snprintf(buf+ret, buflen-ret, "Rread tag %u count %u data ", tag, fc->params.rread.count); ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, fc->params.rread.count); break; case TWRITE: ret += snprintf(buf+ret, buflen-ret, "Twrite tag %u fid %d offset %lld count %u data ", tag, fc->params.twrite.fid, (long long int)fc->params.twrite.offset, fc->params.twrite.count); ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, fc->params.twrite.count); break; case RWRITE: ret += snprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", tag, fc->params.rwrite.count); break; case TCLUNK: ret += snprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", tag, fc->params.tclunk.fid); break; case RCLUNK: ret += snprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); break; case TREMOVE: ret += snprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", tag, fc->params.tremove.fid); break; case RREMOVE: ret += snprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); break; case TSTAT: ret += snprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", tag, fc->params.tstat.fid); break; case RSTAT: ret += snprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, extended); break; case TWSTAT: ret += snprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", tag, fc->params.twstat.fid); ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, extended); break; case RWSTAT: ret += snprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); break; default: ret += snprintf(buf+ret, buflen-ret, "unknown type %d", type); break; } return ret; } |
From: Eric V. H. <er...@us...> - 2006-03-12 20:18:59
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13980 Modified Files: 9p.c 9p.h Makefile debug.h fid.c fid.h mux.c trans_fd.c v9fs.c v9fs.h v9fs_vfs.h vfs_dentry.c vfs_file.c vfs_inode.c vfs_super.c Log Message: Updating snapshot that works on ubuntu to debug pwd problem. Index: vfs_file.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_file.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** vfs_file.c 2 Mar 2006 21:30:17 -0000 2.4 --- vfs_file.c 12 Mar 2006 20:18:53 -0000 2.5 *************** *** 54,145 **** { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *v9fid, *fid; struct v9fs_fcall *fcall = NULL; ! int open_mode = 0; ! unsigned int iounit = 0; ! int newfid = -1; ! long result = -1; dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); ! v9fid = v9fs_fid_get_created(file->f_dentry); ! if (!v9fid) ! v9fid = v9fs_fid_lookup(file->f_dentry); ! ! if (!v9fid) { dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); return -EBADF; } ! if (!v9fid->fidcreate) { ! fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); ! if (fid == NULL) { ! dprintk(DEBUG_ERROR, "Out of Memory\n"); ! return -ENOMEM; ! } ! ! fid->fidopen = 0; ! fid->fidcreate = 0; ! fid->fidclunked = 0; ! fid->iounit = 0; ! fid->v9ses = v9ses; ! ! newfid = v9fs_get_idpool(&v9ses->fidpool); ! if (newfid < 0) { eprintk(KERN_WARNING, "newfid fails!\n"); return -ENOSPC; } ! result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL); ! ! if (result < 0) { ! v9fs_put_idpool(newfid, &v9ses->fidpool); dprintk(DEBUG_ERROR, "rewalk didn't work\n"); ! return -EBADF; } - fid->fid = newfid; - v9fid = fid; /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ ! open_mode = file->f_flags & 0x3; ! if (file->f_flags & O_EXCL) ! open_mode |= V9FS_OEXCL; ! if (v9ses->extended) { ! if (file->f_flags & O_TRUNC) ! open_mode |= V9FS_OTRUNC; ! if (file->f_flags & O_APPEND) ! open_mode |= V9FS_OAPPEND; ! } ! result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); ! if (result < 0) { ! PRINT_FCALL_ERROR("open failed", fcall); ! kfree(fcall); ! return result; ! } ! iounit = fcall->params.ropen.iounit; kfree(fcall); - } else { - /* create case */ - newfid = v9fid->fid; - iounit = v9fid->iounit; - v9fid->fidcreate = 0; - } - - file->private_data = v9fid; ! v9fid->rdir_pos = 0; ! v9fid->rdir_fcall = NULL; ! v9fid->fidopen = 1; ! v9fid->filp = file; ! v9fid->iounit = iounit; ! ! return 0; } --- 54,121 ---- { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *vfid; struct v9fs_fcall *fcall = NULL; ! int omode; ! int fid = V9FS_NOFID; ! int err; dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); ! vfid = v9fs_fid_lookup(file->f_dentry); ! if (!vfid) { dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); return -EBADF; } ! fid = v9fs_get_idpool(&v9ses->fidpool); ! if (fid < 0) { eprintk(KERN_WARNING, "newfid fails!\n"); return -ENOSPC; } ! err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); ! if (err < 0) { dprintk(DEBUG_ERROR, "rewalk didn't work\n"); ! goto put_fid; ! } ! ! vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); ! if (vfid == NULL) { ! dprintk(DEBUG_ERROR, "out of memory\n"); ! goto clunk_fid; } /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ ! omode = v9fs_uflags2omode(file->f_flags); ! err = v9fs_t_open(v9ses, fid, omode, &fcall); ! if (err < 0) { ! PRINT_FCALL_ERROR("open failed", fcall); ! goto destroy_vfid; ! } ! file->private_data = vfid; ! vfid->fid = fid; ! vfid->fidopen = 1; ! vfid->fidclunked = 0; ! vfid->iounit = fcall->params.ropen.iounit; ! vfid->rdir_pos = 0; ! vfid->rdir_fcall = NULL; ! vfid->filp = file; ! kfree(fcall); ! return 0; ! destroy_vfid: ! v9fs_fid_destroy(vfid); ! clunk_fid: ! v9fs_t_clunk(v9ses, fid); ! put_fid: ! v9fs_put_idpool(fid, &v9ses->fidpool); kfree(fcall); ! return err; } *************** *** 290,296 **** } while (count); - if(inode->i_mapping->nrpages) invalidate_inode_pages2(inode->i_mapping); - return total; } --- 266,270 ---- Index: mux.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/mux.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** mux.c 2 Mar 2006 21:30:17 -0000 2.4 --- mux.c 12 Mar 2006 20:18:53 -0000 2.5 *************** *** 70,74 **** unsigned char *extended; struct v9fs_transport *trans; ! struct v9fs_idpool tidpool; int err; wait_queue_head_t equeue; --- 70,74 ---- unsigned char *extended; struct v9fs_transport *trans; ! struct v9fs_idpool tagpool; int err; wait_queue_head_t equeue; *************** *** 280,285 **** m->extended = extended; m->trans = trans; ! idr_init(&m->tidpool.pool); ! init_MUTEX(&m->tidpool.lock); m->err = 0; init_waitqueue_head(&m->equeue); --- 280,285 ---- m->extended = extended; m->trans = trans; ! idr_init(&m->tagpool.pool); ! init_MUTEX(&m->tagpool.lock); m->err = 0; init_waitqueue_head(&m->equeue); *************** *** 635,638 **** --- 635,646 ---- } + if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { + char buf[150]; + + v9fs_printfcall(buf, sizeof(buf), m->rcall, + *m->extended); + printk(KERN_NOTICE ">>> %p %s\n", m, buf); + } + rcall = m->rcall; rbuf = m->rbuf; *************** *** 740,743 **** --- 748,758 ---- v9fs_set_tag(tc, n); + if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { + char buf[150]; + + v9fs_printfcall(buf, sizeof(buf), tc, *m->extended); + printk(KERN_NOTICE "<<< %p %s\n", m, buf); + } + req->tag = n; req->tcall = tc; *************** *** 964,968 **** int tag; ! tag = v9fs_get_idpool(&m->tidpool); if (tag < 0) return V9FS_NOTAG; --- 979,983 ---- int tag; ! tag = v9fs_get_idpool(&m->tagpool); if (tag < 0) return V9FS_NOTAG; *************** *** 973,977 **** static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) { ! if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tidpool)) ! v9fs_put_idpool(tag, &m->tidpool); } --- 988,992 ---- static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) { ! if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool)) ! v9fs_put_idpool(tag, &m->tagpool); } Index: trans_fd.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/trans_fd.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** trans_fd.c 2 Mar 2006 21:32:34 -0000 1.2 --- trans_fd.c 12 Mar 2006 20:18:53 -0000 1.3 *************** *** 97,102 **** set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ! ret = vfs_write(ts->wr, (void __user *)v, len, ! &ts->wr->f_pos); set_fs(oldfs); --- 97,101 ---- set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ! ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); set_fs(oldfs); *************** *** 109,113 **** v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) { - int ret, n; struct v9fs_trans_fd *ts; --- 108,111 ---- *************** *** 147,152 **** { struct v9fs_transport *trans = v9ses->transport; ! struct v9fs_trans_fd *ts =kmalloc(sizeof(struct v9fs_trans_fd), ! GFP_KERNEL); if (!ts) return -ENOMEM; --- 145,150 ---- { struct v9fs_transport *trans = v9ses->transport; ! struct v9fs_trans_fd *ts = kmalloc(sizeof(struct v9fs_trans_fd), ! GFP_KERNEL); if (!ts) return -ENOMEM; *************** *** 195,204 **** if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) { ! //TODO: sock_unmap_fd(fd); eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n"); goto release_csocket; } ! ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= O_NONBLOCK; return 0; } --- 193,203 ---- if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) { ! sockfd_put(csocket); eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n"); goto release_csocket; } ! ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= ! O_NONBLOCK; return 0; } *************** *** 215,220 **** sin_server.sin_port = htons(v9ses->port); sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); ! ! if(!csocket) { eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n"); return -1; --- 214,219 ---- sin_server.sin_port = htons(v9ses->port); sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); ! ! if (!csocket) { eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n"); return -1; *************** *** 250,254 **** strcpy(sun_server.sun_path, addr); sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); ! ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, sizeof(struct sockaddr_un) - 1, 0); /* -1 *is* important */ if (ret < 0) { eprintk(KERN_ERR, --- 249,254 ---- strcpy(sun_server.sun_path, addr); sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); ! ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, ! sizeof(struct sockaddr_un) - 1, 0); if (ret < 0) { eprintk(KERN_ERR, *************** *** 273,277 **** return; ! ts = xchg(&trans->priv, NULL); /* do we really need xchg? */ if (!ts) --- 273,277 ---- return; ! ts = xchg(&trans->priv, NULL); if (!ts) Index: vfs_super.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_super.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_super.c 2 Mar 2006 21:30:17 -0000 2.3 --- vfs_super.c 12 Mar 2006 20:18:54 -0000 2.4 *************** *** 147,151 **** root = d_alloc_root(inode); - if (!root) { retval = -ENOMEM; --- 147,150 ---- *************** *** 158,166 **** if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); v9fs_t_clunk(v9ses, newfid); - v9fs_put_idpool(newfid, &v9ses->fidpool); } else { /* Setup the Root Inode */ ! root_fid = v9fs_fid_create(root, v9ses, newfid, 0); if (root_fid == NULL) { retval = -ENOMEM; --- 157,165 ---- if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); + kfree(fcall); v9fs_t_clunk(v9ses, newfid); } else { /* Setup the Root Inode */ ! root_fid = v9fs_fid_create(v9ses, newfid); if (root_fid == NULL) { retval = -ENOMEM; *************** *** 168,171 **** --- 167,176 ---- } + retval = v9fs_fid_insert(root_fid, root); + if (retval < 0) { + kfree(fcall); + goto put_back_sb; + } + root_fid->qid = fcall->params.rstat.stat.qid; root->d_inode->i_ino = Index: 9p.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** 9p.c 2 Mar 2006 21:30:17 -0000 2.3 --- 9p.c 12 Mar 2006 20:18:47 -0000 2.4 *************** *** 153,157 **** * v9fs_v9fs_t_flush - flush a pending transaction * @v9ses: 9P2000 session information ! * @tag: tid to release * */ --- 153,157 ---- * v9fs_v9fs_t_flush - flush a pending transaction * @v9ses: 9P2000 session information ! * @tag: tag to release * */ Index: v9fs.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** v9fs.c 2 Mar 2006 21:30:17 -0000 2.4 --- v9fs.c 12 Mar 2006 20:18:53 -0000 2.5 *************** *** 290,294 **** v9fs_debug_level = v9ses->debug; ! /* id pools that are session-dependent: FIDs and TIDs */ idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); --- 290,294 ---- v9fs_debug_level = v9ses->debug; ! /* id pools that are session-dependent: fids and tags */ idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); *************** *** 398,401 **** --- 398,402 ---- if (v9ses->afid != ~0) { + dprintk(DEBUG_ERROR, "afid not equal to ~0\n"); if (v9fs_t_clunk(v9ses, v9ses->afid)) dprintk(DEBUG_ERROR, "clunk failed\n"); Index: v9fs.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** v9fs.h 2 Mar 2006 21:30:17 -0000 2.3 --- v9fs.h 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 92,109 **** #define V9FS_DEFANAME "" - /* inital pool sizes for fids and tags */ - #define V9FS_START_FIDS 8192 - #define V9FS_START_TIDS 256 - #include <linux/version.h> #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) #define filemap_write_and_wait(x) \ ! do{ \ ! filemap_fdatawrite(x); \ ! filemap_fdatawait(x); \ ! } while(0) #define kzalloc(x,y) kmalloc(x,y) - - #endif --- 92,104 ---- #define V9FS_DEFANAME "" #include <linux/version.h> #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) #define filemap_write_and_wait(x) \ ! do{ \ ! filemap_fdatawrite(x); \ ! filemap_fdatawait(x); \ ! } while(0) #define kzalloc(x,y) kmalloc(x,y) + #endif Index: v9fs_vfs.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs_vfs.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** v9fs_vfs.h 2 Mar 2006 21:30:17 -0000 2.3 --- v9fs_vfs.h 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 52,53 **** --- 52,54 ---- void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat); void v9fs_dentry_release(struct dentry *); + int v9fs_uflags2omode(int uflags); Index: vfs_inode.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_inode.c,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -d -r2.5 -r2.6 *** vfs_inode.c 2 Mar 2006 21:30:17 -0000 2.5 --- vfs_inode.c 12 Mar 2006 20:18:53 -0000 2.6 *************** *** 126,129 **** --- 126,161 ---- } + int v9fs_uflags2omode(int uflags) + { + int ret; + + ret = 0; + switch (uflags & 3) { + default: + case O_RDONLY: + ret = V9FS_OREAD; + break; + + case O_WRONLY: + ret = V9FS_OWRITE; + break; + + case O_RDWR: + ret = V9FS_ORDWR; + break; + } + + if (uflags & O_EXCL) + ret |= V9FS_OEXCL; + + if (uflags & O_TRUNC) + ret |= V9FS_OTRUNC; + + if (uflags & O_APPEND) + ret |= V9FS_OAPPEND; + + return ret; + } + /** * v9fs_blank_wstat - helper function to setup a 9P stat structure *************** *** 133,138 **** */ ! static void ! v9fs_blank_wstat(struct v9fs_wstat *wstat) { wstat->type = ~0; --- 165,169 ---- */ ! static void v9fs_blank_wstat(struct v9fs_wstat *wstat) { wstat->type = ~0; *************** *** 164,168 **** struct inode *v9fs_get_inode(struct super_block *sb, int mode) { ! struct inode *inode = NULL; struct v9fs_session_info *v9ses = sb->s_fs_info; --- 195,199 ---- struct inode *v9fs_get_inode(struct super_block *sb, int mode) { ! struct inode *inode; struct v9fs_session_info *v9ses = sb->s_fs_info; *************** *** 185,194 **** case S_IFCHR: case S_IFSOCK: ! if(!v9ses->extended) { ! dprintk(DEBUG_ERROR, "special files without extended mode\n"); return ERR_PTR(-EINVAL); } ! init_special_inode(inode, inode->i_mode, ! inode->i_rdev); break; case S_IFREG: --- 216,225 ---- case S_IFCHR: case S_IFSOCK: ! if (!v9ses->extended) { ! dprintk(DEBUG_ERROR, ! "special files without extended mode\n"); return ERR_PTR(-EINVAL); } ! init_special_inode(inode, inode->i_mode, inode->i_rdev); break; case S_IFREG: *************** *** 197,202 **** break; case S_IFLNK: ! if(!v9ses->extended) { ! dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n"); return ERR_PTR(-EINVAL); } --- 228,234 ---- break; case S_IFLNK: ! if (!v9ses->extended) { ! dprintk(DEBUG_ERROR, ! "extended modes used w/o 9P2000.u\n"); return ERR_PTR(-EINVAL); } *************** *** 205,209 **** case S_IFDIR: inode->i_nlink++; ! if(v9ses->extended) inode->i_op = &v9fs_dir_inode_operations_ext; else --- 237,241 ---- case S_IFDIR: inode->i_nlink++; ! if (v9ses->extended) inode->i_op = &v9fs_dir_inode_operations_ext; else *************** *** 223,391 **** } - /** - * v9fs_create - helper function to create files and directories - * @dir: directory inode file is being created in - * @file_dentry: dentry file is being created in - * @perm: permissions file is being created with - * @open_mode: resulting open mode for file - * - */ - static int ! v9fs_create(struct inode *dir, ! struct dentry *file_dentry, ! unsigned int perm, unsigned int open_mode) { ! struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); ! struct super_block *sb = dir->i_sb; ! struct v9fs_fid *dirfid = ! v9fs_fid_lookup(file_dentry->d_parent); ! struct v9fs_fid *fid = NULL; ! struct inode *file_inode = NULL; ! struct v9fs_fcall *fcall = NULL; ! struct v9fs_qid qid; ! int dirfidnum = -1; ! long newfid = -1; ! int result = 0; ! unsigned int iounit = 0; ! int wfidno = -1; int err; ! perm = unixmode2p9mode(v9ses, perm); ! ! dprintk(DEBUG_VFS, "dir: %p dentry: %p perm: %o mode: %o\n", dir, ! file_dentry, perm, open_mode); ! ! if (!dirfid) ! return -EBADF; ! ! dirfidnum = dirfid->fid; ! if (dirfidnum < 0) { ! dprintk(DEBUG_ERROR, "No fid for the directory #%lu\n", ! dir->i_ino); ! return -EBADF; ! } ! ! if (file_dentry->d_inode) { ! dprintk(DEBUG_ERROR, ! "Odd. There is an inode for dir %lu, name :%s:\n", ! dir->i_ino, file_dentry->d_name.name); ! return -EEXIST; ! } ! ! newfid = v9fs_get_idpool(&v9ses->fidpool); ! if (newfid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! return -ENOSPC; } ! result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall); ! if (result < 0) { PRINT_FCALL_ERROR("clone error", fcall); ! v9fs_put_idpool(newfid, &v9ses->fidpool); ! newfid = -1; ! goto CleanUpFid; } - kfree(fcall); - fcall = NULL; ! result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name, ! perm, open_mode, &fcall); ! if (result < 0) { PRINT_FCALL_ERROR("create fails", fcall); ! goto CleanUpFid; } ! iounit = fcall->params.rcreate.iounit; ! qid = fcall->params.rcreate.qid; kfree(fcall); ! fcall = NULL; ! if (!(perm&V9FS_DMDIR)) { ! fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1); ! dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate); ! if (!fid) { ! result = -ENOMEM; ! goto CleanUpFid; ! } ! fid->qid = qid; ! fid->iounit = iounit; ! } else { ! err = v9fs_t_clunk(v9ses, newfid); ! newfid = -1; ! if (err < 0) ! dprintk(DEBUG_ERROR, "clunk for mkdir failed: %d\n", err); ! } ! /* walk to the newly created file and put the fid in the dentry */ ! wfidno = v9fs_get_idpool(&v9ses->fidpool); ! if (wfidno < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! return -ENOSPC; } ! result = v9fs_t_walk(v9ses, dirfidnum, wfidno, ! (char *) file_dentry->d_name.name, &fcall); ! if (result < 0) { ! PRINT_FCALL_ERROR("clone error", fcall); ! v9fs_put_idpool(wfidno, &v9ses->fidpool); ! wfidno = -1; ! goto CleanUpFid; } kfree(fcall); fcall = NULL; ! if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) { ! v9fs_put_idpool(wfidno, &v9ses->fidpool); ! ! goto CleanUpFid; } ! if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) || ! (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) || ! (perm & V9FS_DMDEVICE)) ! return 0; ! result = v9fs_t_stat(v9ses, wfidno, &fcall); ! if (result < 0) { ! PRINT_FCALL_ERROR("stat error", fcall); ! goto CleanUpFid; ! } ! file_inode = v9fs_get_inode(sb, ! p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode)); ! if ((!file_inode) || IS_ERR(file_inode)) { ! dprintk(DEBUG_ERROR, "create inode failed\n"); ! result = -EBADF; ! goto CleanUpFid; } ! v9fs_stat2inode(&fcall->params.rstat.stat, file_inode, sb); ! kfree(fcall); ! fcall = NULL; ! file_dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(file_dentry, file_inode); ! return 0; ! CleanUpFid: kfree(fcall); ! fcall = NULL; ! if (newfid >= 0) { ! err = v9fs_t_clunk(v9ses, newfid); ! if (err < 0) ! dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); ! } ! if (wfidno >= 0) { ! err = v9fs_t_clunk(v9ses, wfidno); ! if (err < 0) ! dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); ! } ! return result; } --- 255,386 ---- } static int ! v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, ! u32 perm, u8 mode, u32 * fidp, struct v9fs_qid *qid, u32 * iounit) { ! u32 fid; int err; + struct v9fs_fcall *fcall; ! fid = v9fs_get_idpool(&v9ses->fidpool); ! if (fid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! err = -ENOSPC; ! goto error; } ! err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); ! if (err < 0) { PRINT_FCALL_ERROR("clone error", fcall); ! goto error; } kfree(fcall); ! err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); ! if (err < 0) { PRINT_FCALL_ERROR("create fails", fcall); ! goto error; } ! if (iounit) ! *iounit = fcall->params.rcreate.iounit; ! ! if (qid) ! *qid = fcall->params.rcreate.qid; ! ! if (fidp) ! *fidp = fid; ! kfree(fcall); ! return 0; ! error: ! if (fid >= 0) ! v9fs_put_idpool(fid, &v9ses->fidpool); ! kfree(fcall); ! return err; ! } ! static struct v9fs_fid *v9fs_clone_walk(struct v9fs_session_info *v9ses, ! u32 fid, struct dentry *dentry) ! { ! int err; ! u32 nfid; ! struct v9fs_fid *ret; ! struct v9fs_fcall *fcall; ! ! nfid = v9fs_get_idpool(&v9ses->fidpool); ! if (nfid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); ! err = -ENOSPC; ! goto error; } ! err = v9fs_t_walk(v9ses, fid, nfid, (char *)dentry->d_name.name, ! &fcall); ! ! if (err < 0) { ! PRINT_FCALL_ERROR("walk error", fcall); ! v9fs_put_idpool(nfid, &v9ses->fidpool); ! goto error; } + kfree(fcall); fcall = NULL; + ret = v9fs_fid_create(v9ses, nfid); + if (!ret) { + err = -ENOMEM; + goto clunk_fid; + } ! err = v9fs_fid_insert(ret, dentry); ! if (err < 0) { ! v9fs_fid_destroy(ret); ! goto clunk_fid; } ! return ret; ! clunk_fid: ! v9fs_t_clunk(v9ses, nfid); + error: + kfree(fcall); + return ERR_PTR(err); + } ! struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, ! struct super_block *sb) ! { ! int err, umode; ! struct inode *ret; ! struct v9fs_fcall *fcall; ! ret = NULL; ! err = v9fs_t_stat(v9ses, fid, &fcall); ! if (err) { ! PRINT_FCALL_ERROR("stat error", fcall); ! goto error; } ! umode = p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode); ! ret = v9fs_get_inode(sb, umode); ! if (IS_ERR(ret)) { ! err = PTR_ERR(ret); ! ret = NULL; ! goto error; ! } ! v9fs_stat2inode(&fcall->params.rstat.stat, ret, sb); ! kfree(fcall); ! return ret; ! error: kfree(fcall); ! if (ret) ! iput(ret); ! return ERR_PTR(err); } *************** *** 417,422 **** if (!v9fid) { ! dprintk(DEBUG_ERROR, ! "no v9fs_fid\n"); return -EBADF; } --- 412,416 ---- if (!v9fid) { ! dprintk(DEBUG_ERROR, "no v9fs_fid\n"); return -EBADF; } *************** *** 441,449 **** } /** * v9fs_vfs_create - VFS hook to create files * @inode: directory inode that is being deleted * @dentry: dentry that is being deleted ! * @perm: create permissions * @nd: path information * --- 435,450 ---- } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + static int v9fs_open_created(struct inode *inode, struct file *file) + { + return 0; + } + #endif + /** * v9fs_vfs_create - VFS hook to create files * @inode: directory inode that is being deleted * @dentry: dentry that is being deleted ! * @mode: create permissions * @nd: path information * *************** *** 451,458 **** static int ! v9fs_vfs_create(struct inode *inode, struct dentry *dentry, int perm, struct nameidata *nd) { ! return v9fs_create(inode, dentry, perm, O_RDWR); } --- 452,536 ---- static int ! v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ! int err; ! u32 fid, perm, iounit; ! int flags; ! struct v9fs_session_info *v9ses; ! struct v9fs_fid *dfid, *vfid; ! struct inode *inode; ! struct v9fs_qid qid; ! ! inode = NULL; ! vfid = NULL; ! v9ses = v9fs_inode2v9ses(dir); ! dfid = v9fs_fid_lookup(dentry->d_parent); ! perm = unixmode2p9mode(v9ses, mode); ! ! if (nd && nd->flags & LOOKUP_OPEN) ! flags = nd->intent.open.flags - 1; ! else ! flags = O_RDWR; ! ! err = v9fs_create(v9ses, dfid->fid, (char *)dentry->d_name.name, ! perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); ! ! if (err) ! goto error; ! ! vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); ! if (IS_ERR(vfid)) { ! err = PTR_ERR(vfid); ! vfid = NULL; ! goto error; ! } ! ! inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); ! if (IS_ERR(inode)) { ! err = PTR_ERR(inode); ! inode = NULL; ! goto error; ! } ! ! dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(dentry, inode); ! ! if (nd && nd->flags & LOOKUP_OPEN) { ! #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) ! return -ENOTSUPP; ! #else ! struct v9fs_fid *ffid; ! struct file *filp; ! ! ffid = v9fs_fid_create(v9ses, fid); ! if (!ffid) ! return -ENOMEM; ! ! filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); ! if (IS_ERR(filp)) { ! v9fs_fid_destroy(ffid); ! return PTR_ERR(filp); ! } ! ! ffid->rdir_pos = 0; ! ffid->rdir_fcall = NULL; ! ffid->fidopen = 1; ! ffid->iounit = iounit; ! ffid->filp = filp; ! filp->private_data = ffid; ! #endif ! } ! ! return 0; ! ! error: ! if (vfid) ! v9fs_fid_destroy(vfid); ! ! if (inode) ! iput(inode); ! ! return err; } *************** *** 465,471 **** */ ! static int v9fs_vfs_mkdir(struct inode *inode, struct dentry *dentry, int mode) { ! return v9fs_create(inode, dentry, mode | S_IFDIR, O_RDONLY); } --- 543,597 ---- */ ! static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { ! int err; ! u32 fid, perm; ! struct v9fs_session_info *v9ses; ! struct v9fs_fid *dfid, *vfid; ! struct inode *inode; ! ! inode = NULL; ! vfid = NULL; ! v9ses = v9fs_inode2v9ses(dir); ! dfid = v9fs_fid_lookup(dentry->d_parent); ! perm = unixmode2p9mode(v9ses, mode | S_IFDIR); ! ! err = v9fs_create(v9ses, dfid->fid, (char *)dentry->d_name.name, ! perm, V9FS_OREAD, &fid, NULL, NULL); ! ! if (err) { ! dprintk(DEBUG_ERROR, "create error %d\n", err); ! goto error; ! } ! ! err = v9fs_t_clunk(v9ses, fid); ! if (err) { ! dprintk(DEBUG_ERROR, "clunk error %d\n", err); ! goto error; ! } ! ! vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); ! if (IS_ERR(vfid)) { ! err = PTR_ERR(vfid); ! vfid = NULL; ! goto error; ! } ! ! inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); ! if (IS_ERR(inode)) { ! err = PTR_ERR(inode); ! inode = NULL; ! goto error; ! } ! ! dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(dentry, inode); ! return 0; ! ! error: ! if (vfid) ! v9fs_fid_destroy(vfid); ! ! return err; } *************** *** 517,523 **** } ! result = ! v9fs_t_walk(v9ses, dirfidnum, newfid, (char *)dentry->d_name.name, ! NULL); if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); --- 643,648 ---- } ! result = v9fs_t_walk(v9ses, dirfidnum, newfid, ! (char *)dentry->d_name.name, NULL); if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); *************** *** 540,544 **** inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses, ! fcall->params.rstat.stat.mode)); if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { --- 665,670 ---- inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses, ! fcall->params.rstat.stat. ! mode)); if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { *************** *** 552,556 **** inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); ! fid = v9fs_fid_create(dentry, v9ses, newfid, 0); if (fid == NULL) { dprintk(DEBUG_ERROR, "couldn't insert\n"); --- 678,682 ---- inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); ! fid = v9fs_fid_create(v9ses, newfid); if (fid == NULL) { dprintk(DEBUG_ERROR, "couldn't insert\n"); *************** *** 559,562 **** --- 685,692 ---- } + result = v9fs_fid_insert(fid, dentry); + if (result < 0) + goto FreeFcall; + fid->qid = fcall->params.rstat.stat.qid; *************** *** 614,621 **** struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); ! struct v9fs_fid *olddirfid = ! v9fs_fid_lookup(old_dentry->d_parent); ! struct v9fs_fid *newdirfid = ! v9fs_fid_lookup(new_dentry->d_parent); struct v9fs_wstat wstat; struct v9fs_fcall *fcall = NULL; --- 744,749 ---- struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); ! struct v9fs_fid *olddirfid = v9fs_fid_lookup(old_dentry->d_parent); ! struct v9fs_fid *newdirfid = v9fs_fid_lookup(new_dentry->d_parent); struct v9fs_wstat wstat; struct v9fs_fcall *fcall = NULL; *************** *** 652,656 **** v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.name = (char *) new_dentry->d_name.name; retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); --- 780,784 ---- v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.name = (char *)new_dentry->d_name.name; retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); *************** *** 694,698 **** else { v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode, ! dentry->d_inode->i_sb); generic_fillattr(dentry->d_inode, stat); } --- 822,826 ---- else { v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode, ! dentry->d_inode->i_sb); generic_fillattr(dentry->d_inode, stat); } *************** *** 768,772 **** void v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, ! struct super_block *sb) { int n; --- 896,900 ---- void v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, ! struct super_block *sb) { int n; *************** *** 795,800 **** n = stat->extension.len; ! if (n > sizeof(ext)-1) ! n = sizeof(ext)-1; memmove(ext, stat->extension.str, n); ext[n] = 0; --- 923,928 ---- n = stat->extension.len; ! if (n > sizeof(ext) - 1) ! n = sizeof(ext) - 1; memmove(ext, stat->extension.str, n); ext[n] = 0; *************** *** 887,895 **** /* copy extension buffer into buffer */ ! if (fcall->params.rstat.stat.extension.len+1 < buflen) ! buflen = fcall->params.rstat.stat.extension.len + 1; memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); ! buffer[buflen-1] = 0; retval = buflen; --- 1015,1023 ---- /* copy extension buffer into buffer */ ! if (fcall->params.rstat.stat.extension.len < buflen) ! buflen = fcall->params.rstat.stat.extension.len; memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); ! buffer[buflen - 1] = 0; retval = buflen; *************** *** 935,939 **** } - /** * v9fs_vfs_follow_link - follow a symlink path --- 1063,1066 ---- *************** *** 954,958 **** else { len = v9fs_readlink(dentry, link, PATH_MAX); - if (len < 0) { __putname(link); --- 1081,1084 ---- *************** *** 976,980 **** link = ERR_PTR(-ENOMEM); else { ! len = v9fs_readlink(dentry, link, PATH_MAX); if (len < 0) { --- 1102,1106 ---- link = ERR_PTR(-ENOMEM); else { ! len = v9fs_readlink(dentry, link, strlen(link)); if (len < 0) { *************** *** 1010,1039 **** static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ! int mode, const char *extension) { ! int err, retval; struct v9fs_session_info *v9ses; struct v9fs_fcall *fcall; - struct v9fs_fid *fid; struct v9fs_wstat wstat; - v9ses = v9fs_inode2v9ses(dir); - retval = -EPERM; fcall = NULL; if (!v9ses->extended) { dprintk(DEBUG_ERROR, "not extended\n"); ! goto free_mem; } ! /* issue a create */ ! retval = v9fs_create(dir, dentry, mode, 0); ! if (retval != 0) ! goto free_mem; ! fid = v9fs_fid_get_created(dentry); ! if (!fid) { ! dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n"); ! goto free_mem; } --- 1136,1183 ---- static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ! int mode, const char *extension) { ! int err; ! u32 fid, perm; struct v9fs_session_info *v9ses; + struct v9fs_fid *dfid, *vfid; + struct inode *inode; struct v9fs_fcall *fcall; struct v9fs_wstat wstat; fcall = NULL; + inode = NULL; + vfid = NULL; + v9ses = v9fs_inode2v9ses(dir); + dfid = v9fs_fid_lookup(dentry->d_parent); + perm = unixmode2p9mode(v9ses, mode); if (!v9ses->extended) { dprintk(DEBUG_ERROR, "not extended\n"); ! return -EPERM; } ! err = v9fs_create(v9ses, dfid->fid, (char *)dentry->d_name.name, ! perm, V9FS_OREAD, &fid, NULL, NULL); ! if (err) ! goto error; ! ! err = v9fs_t_clunk(v9ses, fid); ! if (err) ! goto error; ! ! vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); ! if (IS_ERR(vfid)) { ! err = PTR_ERR(vfid); ! vfid = NULL; ! goto error; ! } ! ! inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); ! if (IS_ERR(inode)) { ! err = PTR_ERR(inode); ! inode = NULL; ! goto error; } *************** *** 1041,1062 **** v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.extension = (char *) extension; ! retval = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall); ! if (retval < 0) { ! PRINT_FCALL_ERROR("wstat error", fcall); ! goto free_mem; ! } ! ! err = v9fs_t_clunk(v9ses, fid->fid); if (err < 0) { ! dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); ! goto free_mem; } ! d_drop(dentry); /* FID - will this also clunk? */ ! free_mem: kfree(fcall); ! return retval; } --- 1185,1210 ---- v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; ! wstat.extension = (char *)extension; ! err = v9fs_t_wstat(v9ses, vfid->fid, &wstat, &fcall); if (err < 0) { ! PRINT_FCALL_ERROR("wstat error", fcall); ! goto error; } ! kfree(fcall); ! dentry->d_op = &v9fs_dentry_operations; ! d_instantiate(dentry, inode); ! return 0; ! error: kfree(fcall); ! if (vfid) ! v9fs_fid_destroy(vfid); ! ! if (inode) ! iput(inode); ! ! return err; ! } Index: Makefile =================================================================== RCS file: /cvsroot/v9fs/linux-9p/Makefile,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** Makefile 2 Mar 2006 21:30:17 -0000 2.2 --- Makefile 12 Mar 2006 20:18:51 -0000 2.3 *************** *** 1,3 **** ! 9p2000-objs := fid.o vfs_super.o vfs_inode.o vfs_dentry.o vfs_file.o vfs_addr.o vfs_dir.o error.o mux.o trans_fd.o 9p.o conv.o v9fs.o ifneq ($(KERNELRELEASE),) --- 1,3 ---- ! 9p2000-objs := fid.o vfs_super.o vfs_inode.o vfs_dentry.o vfs_file.o vfs_addr.o vfs_dir.o error.o mux.o trans_fd.o 9p.o conv.o v9fs.o fcprint.o ifneq ($(KERNELRELEASE),) Index: debug.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/debug.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** debug.h 2 Mar 2006 21:30:17 -0000 2.3 --- debug.h 12 Mar 2006 20:18:52 -0000 2.4 *************** *** 31,34 **** --- 31,35 ---- #define DEBUG_TRANS (1<<6) #define DEBUG_SLABS (1<<7) + #define DEBUG_FCALL (1<<8) #define DEBUG_DUMP_PKT 0 Index: 9p.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** 9p.h 2 Mar 2006 21:30:17 -0000 2.3 --- 9p.h 12 Mar 2006 20:18:50 -0000 2.4 *************** *** 375,376 **** --- 375,379 ---- u32 count, const char __user * data, struct v9fs_fcall **rcall); + int v9fs_printfcall(char *, int, struct v9fs_fcall *, int); + int v9fs_dumpdata(char *, int, u8 *, int); + int v9fs_printstat(char *, int, struct v9fs_stat *, int); Index: fid.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/fid.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** fid.c 2 Mar 2006 21:30:17 -0000 2.3 --- fid.c 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 2,6 **** * V9FS FID Management * ! * Copyright (C) 2005 by Eric Van Hensbergen <er...@gm...> * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * V9FS FID Management * ! * Copyright (C) 2005, 2006 by Eric Van Hensbergen <er...@gm...> * * This program is free software; you can redistribute it and/or modify *************** *** 41,45 **** */ ! static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; --- 41,45 ---- */ ! int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; *************** *** 58,62 **** fid->uid = current->uid; - fid->pid = current->pid; list_add(&fid->list, fid_list); return 0; --- 58,61 ---- *************** *** 69,80 **** */ ! struct v9fs_fid *v9fs_fid_create(struct dentry *dentry, ! struct v9fs_session_info *v9ses, int fid, int create) { struct v9fs_fid *new; ! dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n", ! dentry, fid, create); ! new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); if (new == NULL) { --- 68,76 ---- */ ! struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) { struct v9fs_fid *new; ! dprintk(DEBUG_9P, "fid create fid %d\n", fid); new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); if (new == NULL) { *************** *** 86,102 **** new->v9ses = v9ses; new->fidopen = 0; - new->fidcreate = create; new->fidclunked = 0; new->iounit = 0; new->rdir_pos = 0; new->rdir_fcall = NULL; ! if (v9fs_fid_insert(new, dentry) == 0) ! return new; ! else { ! dprintk(DEBUG_ERROR, "Problems inserting to dentry\n"); ! kfree(new); ! return NULL; ! } } --- 82,92 ---- new->v9ses = v9ses; new->fidopen = 0; new->fidclunked = 0; new->iounit = 0; new->rdir_pos = 0; new->rdir_fcall = NULL; + INIT_LIST_HEAD(&new->list); ! return new; } *************** *** 114,177 **** /** - * v9fs_fid_walk_up - walks from the process current directory - * up to the specified dentry. - */ - static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) - { - int fidnum, cfidnum, err; - struct v9fs_fid *cfid; - struct dentry *cde; - struct v9fs_session_info *v9ses; - - v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode); - cfid = v9fs_fid_lookup(current->fs->pwd); - if (cfid == NULL) { - dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n"); - return ERR_PTR(-ENOENT); - } - - cfidnum = cfid->fid; - cde = current->fs->pwd; - /* TODO: take advantage of multiwalk */ - - fidnum = v9fs_get_idpool(&v9ses->fidpool); - if (fidnum < 0) { - dprintk(DEBUG_ERROR, "could not get a new fid num\n"); - err = -ENOENT; - goto clunk_fid; - } - - while (cde != dentry) { - if (cde == cde->d_parent) { - dprintk(DEBUG_ERROR, "can't find dentry\n"); - err = -ENOENT; - goto clunk_fid; - } - - err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL); - if (err < 0) { - dprintk(DEBUG_ERROR, "problem walking to parent\n"); - goto clunk_fid; - } - - cfidnum = fidnum; - cde = cde->d_parent; - } - - return v9fs_fid_create(dentry, v9ses, fidnum, 0); - - clunk_fid: - v9fs_t_clunk(v9ses, fidnum); - return ERR_PTR(err); - } - - /** * v9fs_fid_lookup - retrieve the right fid from a particular dentry * @dentry: dentry to look for fid in * @type: intent of lookup (operation or traversal) * ! * search list of fids associated with a dentry for a fid with a matching ! * thread id or uid. If that fails, look up the dentry's parents to see if you ! * can find a matching fid. * */ --- 104,114 ---- /** * v9fs_fid_lookup - retrieve the right fid from a particular dentry * @dentry: dentry to look for fid in * @type: intent of lookup (operation or traversal) * ! * find a fid in the dentry ! * ! * TODO: only match fids that have the same uid as current user * */ *************** *** 180,252 **** { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; - struct v9fs_fid *current_fid = NULL; - struct v9fs_fid *temp = NULL; struct v9fs_fid *return_fid = NULL; dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); ! if (fid_list) { ! list_for_each_entry_safe(current_fid, temp, fid_list, list) { ! if (!current_fid->fidcreate) { ! return_fid = current_fid; ! break; ! } ! } ! ! if (!return_fid) ! return_fid = current_fid; ! } ! ! /* we are at the root but didn't match */ ! if ((!return_fid) && (dentry->d_parent == dentry)) { ! /* TODO: clone attach with new uid */ ! return_fid = current_fid; ! } if (!return_fid) { ! struct dentry *par = current->fs->pwd->d_parent; ! int count = 1; ! while (par != NULL) { ! if (par == dentry) ! break; ! count++; ! if (par == par->d_parent) { ! dprintk(DEBUG_ERROR, ! "got to root without finding dentry\n"); ! break; ! } ! par = par->d_parent; ! } ! ! /* XXX - there may be some duplication we can get rid of */ ! if (par == dentry) { ! return_fid = v9fs_fid_walk_up(dentry); ! if (IS_ERR(return_fid)) ! return_fid = NULL; ! } } return return_fid; } - - struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry) - { - struct list_head *fid_list; - struct v9fs_fid *fid, *ftmp, *ret; - - dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); - fid_list = (struct list_head *)dentry->d_fsdata; - ret = NULL; - if (fid_list) { - list_for_each_entry_safe(fid, ftmp, fid_list, list) { - if (fid->fidcreate && fid->pid == current->pid) { - list_del(&fid->list); - ret = fid; - break; - } - } - } - - dprintk(DEBUG_9P, "return %p\n", ret); - return ret; - } --- 117,131 ---- { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; struct v9fs_fid *return_fid = NULL; dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); ! if (fid_list) ! return_fid = list_entry(fid_list->next, struct v9fs_fid, list); if (!return_fid) { ! dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); } return return_fid; } Index: fid.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/fid.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** fid.h 2 Mar 2006 21:30:17 -0000 2.3 --- fid.h 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 34,38 **** u32 fid; unsigned char fidopen; /* set when fid is opened */ - unsigned char fidcreate; /* set when fid was just created */ unsigned char fidclunked; /* set when fid has already been clunked */ --- 34,37 ---- *************** *** 46,50 **** /* management stuff */ - pid_t pid; /* thread associated with this fid */ uid_t uid; /* user associated with this fid */ --- 45,48 ---- *************** *** 57,60 **** struct v9fs_fid *v9fs_fid_get_created(struct dentry *); void v9fs_fid_destroy(struct v9fs_fid *fid); ! struct v9fs_fid *v9fs_fid_create(struct dentry *, ! struct v9fs_session_info *v9ses, int fid, int create); --- 55,58 ---- struct v9fs_fid *v9fs_fid_get_created(struct dentry *); void v9fs_fid_destroy(struct v9fs_fid *fid); ! struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); ! int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); Index: vfs_dentry.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_dentry.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_dentry.c 2 Mar 2006 21:30:17 -0000 2.3 --- vfs_dentry.c 12 Mar 2006 20:18:53 -0000 2.4 *************** *** 44,88 **** /** ! * v9fs_dentry_validate - VFS dcache hook to validate cache ! * @dentry: dentry that is being validated ! * @nd: path data ! * ! * dcache really shouldn't be used for 9P2000 as at all due to ! * potential attached semantics to directory traversal (walk). * ! * FUTURE: look into how to use dcache to allow multi-stage ! * walks in Plan 9 & potential for better dcache operation which ! * would remain valid for Plan 9 semantics. Older versions ! * had validation via stat for those interested. However, since ! * stat has the same approximate overhead as walk there really ! * is no difference. The only improvement would be from a ! * time-decay cache like NFS has and that undermines the ! * synchronous nature of 9P2000. * */ ! static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd) { ! struct dentry *dc = current->fs->pwd; ! ! dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry); ! if (v9fs_fid_lookup(dentry)) { ! dprintk(DEBUG_VFS, "VALID\n"); ! return 1; ! } ! ! while (dc != NULL) { ! if (dc == dentry) { ! dprintk(DEBUG_VFS, "VALID\n"); ! return 1; ! } ! if (dc == dc->d_parent) ! break; ! ! dc = dc->d_parent; ! } ! ! dprintk(DEBUG_VFS, "INVALID\n"); ! return 0; } --- 44,59 ---- /** ! * v9fs_dentry_delete - called when dentry refcount equals 0 ! * @dentry: dentry in question * ! * By returning 1 here we should remove cacheing of unused ! * dentry components. * */ ! int v9fs_dentry_delete(struct dentry *dentry) { ! dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); ! return 1; } *************** *** 119,123 **** struct dentry_operations v9fs_dentry_operations = { ! .d_revalidate = v9fs_dentry_validate, .d_release = v9fs_dentry_release, }; --- 90,94 ---- struct dentry_operations v9fs_dentry_operations = { ! .d_delete = v9fs_dentry_delete, .d_release = v9fs_dentry_release, }; |
Update of /cvsroot/v9fs/npfs/libnpfs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12534/libnpfs Removed Files: Makefile conn.c fdtrans.c fidpool.c file.c fmt.c np.c npfsimpl.h pipesrv.c socksrv.c srv.c user.c Log Message: removing npfs source code --- socksrv.c DELETED --- --- npfsimpl.h DELETED --- --- np.c DELETED --- --- srv.c DELETED --- --- Makefile DELETED --- --- pipesrv.c DELETED --- --- fdtrans.c DELETED --- --- file.c DELETED --- --- user.c DELETED --- --- fmt.c DELETED --- --- fidpool.c DELETED --- --- conn.c DELETED --- |
From: Latchesar I. <li...@us...> - 2006-03-10 01:50:49
|
Update of /cvsroot/v9fs/npfs/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12534/include Removed Files: npfs.h Log Message: removing npfs source code --- npfs.h DELETED --- |
From: Latchesar I. <li...@us...> - 2006-03-10 01:50:49
|
Update of /cvsroot/v9fs/npfs/fs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12534/fs Removed Files: Makefile cpu.c cpuhelper.c gphotofs.c mboxfs.c nullfs.c ramfs.c ramfs2.c ufs.c Log Message: removing npfs source code --- mboxfs.c DELETED --- --- gphotofs.c DELETED --- --- Makefile DELETED --- --- nullfs.c DELETED --- --- ramfs2.c DELETED --- --- cpuhelper.c DELETED --- --- ufs.c DELETED --- --- cpu.c DELETED --- --- ramfs.c DELETED --- |
From: Latchesar I. <li...@us...> - 2006-03-10 01:50:49
|
Update of /cvsroot/v9fs/npfs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12534 Added Files: README Removed Files: Makefile Log Message: removing npfs source code --- NEW FILE: README --- Npfs source code is moved to a separate SourceForge project, check http://www.sourceforge.net/projects/npfs. --- Makefile DELETED --- |
From: Eric V. H. <er...@us...> - 2006-03-02 21:32:38
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18112 Added Files: trans_fd.c vfs_addr.c Removed Files: trans_sock.c Log Message: Fix up the build after merge. --- NEW FILE: vfs_addr.c --- /* * linux/fs/9p/vfs_addr.c * * This file contians vfs address (mmap) ops for 9P2000. * * Copyright (C) 2005 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to: * Free Software Foundation * 51 Franklin Street, Fifth Floor * Boston, MA 02111-1301 USA * */ #include <linux/module.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/file.h> #include <linux/stat.h> #include <linux/string.h> #include <linux/smp_lock.h> #include <linux/inet.h> #include <linux/version.h> #include <linux/pagemap.h> #include <linux/idr.h> #include "debug.h" #include "v9fs.h" #include "9p.h" #include "v9fs_vfs.h" #include "fid.h" /** * v9fs_vfs_readpage - read an entire page in from 9P * * @file: file being read * @page: structure to page * */ static int v9fs_vfs_readpage(struct file *filp, struct page *page) { char *buffer = NULL; int retval = -EIO; loff_t offset = page_offset(page); int count = PAGE_CACHE_SIZE; struct inode *inode = filp->f_dentry->d_inode; struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); int rsize = v9ses->maxdata - V9FS_IOHDRSZ; struct v9fs_fid *v9f = filp->private_data; struct v9fs_fcall *fcall = NULL; int fid = v9f->fid; int total = 0; int result = 0; buffer = kmap(page); do { if (count < rsize) rsize = count; result = v9fs_t_read(v9ses, fid, offset, rsize, &fcall); if (result < 0) { printk(KERN_ERR "v9fs_t_read returned %d\n", result); kfree(fcall); goto UnmapAndUnlock; } else offset += result; memcpy(buffer, fcall->params.rread.data, result); count -= result; buffer += result; total += result; kfree(fcall); if (result < rsize) break; } while (count); memset(buffer, 0, count); flush_dcache_page(page); SetPageUptodate(page); retval = 0; UnmapAndUnlock: kunmap(page); unlock_page(page); return retval; } struct address_space_operations v9fs_addr_operations = { .readpage = v9fs_vfs_readpage, }; --- NEW FILE: trans_fd.c --- /* * linux/fs/9p/trans_fd.c * * Fd transport layer. Includes deprecated socket layer. * * Copyright (C) 2006 by Russ Cox <rs...@sw...> * Copyright (C) 2004-2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004-2005 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 1997-2002 by Ron Minnich <rmi...@sa...> * Copyright (C) 1995, 1996 by Olaf Kirch <ok...@mo...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to: * Free Software Foundation * 51 Franklin Street, Fifth Floor * Boston, MA 02111-1301 USA * */ #include <linux/config.h> #include <linux/in.h> #include <linux/module.h> #include <linux/net.h> #include <linux/ipv6.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/un.h> #include <asm/uaccess.h> #include <linux/inet.h> #include <linux/idr.h> #include <linux/file.h> #include "debug.h" #include "v9fs.h" #include "transport.h" #define V9FS_PORT 564 struct v9fs_trans_fd { struct file *rd; struct file *wr; }; /** * v9fs_fd_read- read from a fd * @v9ses: session information * @v: buffer to receive data into * @len: size of receive buffer * */ static int v9fs_fd_read(struct v9fs_transport *trans, void *v, int len) { int ret; struct v9fs_trans_fd *ts; if (!trans || trans->status == Disconnected || !(ts = trans->priv)) return -EREMOTEIO; if (!(ts->rd->f_flags & O_NONBLOCK)) dprintk(DEBUG_ERROR, "blocking read ...\n"); ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) trans->status = Disconnected; return ret; } /** * v9fs_fd_write - write to a socket * @v9ses: session information * @v: buffer to send data from * @len: size of send buffer * */ static int v9fs_fd_write(struct v9fs_transport *trans, void *v, int len) { int ret; mm_segment_t oldfs; struct v9fs_trans_fd *ts; if (!trans || trans->status == Disconnected || !(ts = trans->priv)) return -EREMOTEIO; if (!(ts->wr->f_flags & O_NONBLOCK)) dprintk(DEBUG_ERROR, "blocking write ...\n"); set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); set_fs(oldfs); if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) trans->status = Disconnected; return ret; } static unsigned int v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) { int ret, n; struct v9fs_trans_fd *ts; mm_segment_t oldfs; if (!trans || trans->status != Connected || !(ts = trans->priv)) return -EREMOTEIO; if (!ts->rd->f_op || !ts->rd->f_op->poll) return -EIO; if (!ts->wr->f_op || !ts->wr->f_op->poll) return -EIO; oldfs = get_fs(); set_fs(get_ds()); ret = ts->rd->f_op->poll(ts->rd, pt); if (ret < 0) goto end; if (ts->rd != ts->wr) { n = ts->wr->f_op->poll(ts->wr, pt); if (n < 0) { ret = n; goto end; } ret = (ret & ~POLLOUT) | (n & ~POLLIN); } end: set_fs(oldfs); return ret; } static int v9fs_fd_open(struct v9fs_session_info *v9ses, int rfd, int wfd) { struct v9fs_transport *trans = v9ses->transport; struct v9fs_trans_fd *ts =kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL); if (!ts) return -ENOMEM; ts->rd = fget(rfd); ts->wr = fget(wfd); if (!ts->rd || !ts->wr) { if (ts->rd) fput(ts->rd); if (ts->wr) fput(ts->wr); kfree(ts); return -EIO; } trans->priv = ts; trans->status = Connected; return 0; } static int v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data) { if (v9ses->rfdno == ~0 || v9ses->wfdno == ~0) { printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); return -ENOPROTOOPT; } return v9fs_fd_open(v9ses, v9ses->rfdno, v9ses->wfdno); } static int v9fs_socket_open(struct v9fs_session_info *v9ses, struct socket *csocket) { int fd, ret; csocket->sk->sk_allocation = GFP_NOIO; if ((fd = sock_map_fd(csocket)) < 0) { eprintk(KERN_ERR, "v9fs_socket_open: failed to map fd\n"); ret = fd; release_csocket: sock_release(csocket); return ret; } if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) { //TODO: sock_unmap_fd(fd); eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n"); goto release_csocket; } ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= O_NONBLOCK; return 0; } static int v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data) { int ret; struct socket *csocket = NULL; struct sockaddr_in sin_server; sin_server.sin_family = AF_INET; sin_server.sin_addr.s_addr = in_aton(addr); sin_server.sin_port = htons(v9ses->port); sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); if(!csocket) { eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n"); return -1; } ret = csocket->ops->connect(csocket, (struct sockaddr *)&sin_server, sizeof(struct sockaddr_in), 0); if (ret < 0) { eprintk(KERN_ERR, "v9fs_trans_tcp: problem connecting socket to %s\n", addr); return ret; } return v9fs_socket_open(v9ses, csocket); } static int v9fs_unix_init(struct v9fs_session_info *v9ses, const char *addr, char *data) { int ret; struct socket *csocket; struct sockaddr_un sun_server; if (strlen(addr) > UNIX_PATH_MAX) { eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n", addr); return -ENAMETOOLONG; } sun_server.sun_family = PF_UNIX; strcpy(sun_server.sun_path, addr); sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, sizeof(struct sockaddr_un) - 1, 0); /* -1 *is* important */ if (ret < 0) { eprintk(KERN_ERR, "v9fs_trans_unix: problem connecting socket: %s: %d\n", addr, ret); return ret; } return v9fs_socket_open(v9ses, csocket); } /** * v9fs_sock_close - shutdown socket * @trans: private socket structure * */ static void v9fs_fd_close(struct v9fs_transport *trans) { struct v9fs_trans_fd *ts; if (!trans) return; ts = xchg(&trans->priv, NULL); /* do we really need xchg? */ if (!ts) return; trans->status = Disconnected; if (ts->rd) fput(ts->rd); if (ts->wr) fput(ts->wr); kfree(ts); } struct v9fs_transport v9fs_trans_fd = { .init = v9fs_fd_init, .write = v9fs_fd_write, .read = v9fs_fd_read, .close = v9fs_fd_close, .poll = v9fs_fd_poll, }; struct v9fs_transport v9fs_trans_tcp = { .init = v9fs_tcp_init, .write = v9fs_fd_write, .read = v9fs_fd_read, .close = v9fs_fd_close, .poll = v9fs_fd_poll, }; struct v9fs_transport v9fs_trans_unix = { .init = v9fs_unix_init, .write = v9fs_fd_write, .read = v9fs_fd_read, .close = v9fs_fd_close, .poll = v9fs_fd_poll, }; --- trans_sock.c DELETED --- |
From: Eric V. H. <er...@us...> - 2006-03-02 21:30:26
|
Update of /cvsroot/v9fs/linux-9p In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16402 Modified Files: 9p.c 9p.h Makefile TODO conv.c conv.h debug.h error.c error.h fid.c fid.h mux.c mux.h transport.h v9fs.c v9fs.h v9fs_vfs.h vfs_dentry.c vfs_dir.c vfs_file.c vfs_inode.c vfs_super.c Removed Files: idpool.c idpool.h Log Message: Merge code from kernel.org and make sure it builds as a stand-alone module on 2.6.12. Index: mux.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/mux.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** mux.h 21 Sep 2005 17:43:51 -0000 2.2 --- mux.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 4,7 **** --- 4,8 ---- * Multiplexer Definitions * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * *************** *** 24,41 **** */ ! /* structure to manage each RPC transaction */ ! struct v9fs_rpcreq { ! struct v9fs_fcall *tcall; ! struct v9fs_fcall *rcall; ! int err; /* error code if response failed */ ! /* XXX - could we put scatter/gather buffers here? */ ! struct list_head next; ! }; ! int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name); ! long v9fs_mux_rpc(struct v9fs_session_info *v9ses, ! struct v9fs_fcall *tcall, struct v9fs_fcall **rcall); ! void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err); --- 25,58 ---- */ ! struct v9fs_mux_data; ! /** ! * v9fs_mux_req_callback - callback function that is called when the ! * response of a request is received. The callback is called from ! * a workqueue and shouldn't block. ! * ! * @a - the pointer that was specified when the request was send to be ! * passed to the callback ! * @tc - request call ! * @rc - response call ! * @err - error code (non-zero if error occured) ! */ ! typedef void (*v9fs_mux_req_callback)(void *a, struct v9fs_fcall *tc, ! struct v9fs_fcall *rc, int err); ! int v9fs_mux_global_init(void); ! void v9fs_mux_global_exit(void); ! struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, ! unsigned char *extended); ! void v9fs_mux_destroy(struct v9fs_mux_data *); ! int v9fs_mux_send(struct v9fs_mux_data *m, struct v9fs_fcall *tc); ! struct v9fs_fcall *v9fs_mux_recv(struct v9fs_mux_data *m); ! int v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, struct v9fs_fcall **rc); ! int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc, ! v9fs_mux_req_callback cb, void *a); ! ! void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush); ! void v9fs_mux_cancel(struct v9fs_mux_data *m, int err); ! int v9fs_errstr2errno(char *errstr, int len); Index: vfs_file.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_file.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_file.c 21 Sep 2005 17:43:51 -0000 2.3 --- vfs_file.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 33,36 **** --- 33,37 ---- #include <linux/smp_lock.h> #include <linux/inet.h> + #include <linux/version.h> #include <linux/list.h> #include <asm/uaccess.h> *************** *** 53,58 **** { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK); ! struct v9fs_fid *v9newfid = NULL; struct v9fs_fcall *fcall = NULL; int open_mode = 0; --- 54,58 ---- { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); ! struct v9fs_fid *v9fid, *fid; struct v9fs_fcall *fcall = NULL; int open_mode = 0; *************** *** 61,80 **** long result = -1; ! dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file, ! v9fid); if (!v9fid) { - struct dentry *dentry = file->f_dentry; dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); ! /* XXX - some duplication from lookup, generalize later */ ! /* basically vfs_lookup is too heavy weight */ ! v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP); ! if (!v9fid) ! return -EBADF; ! v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK); ! if (!v9fid) ! return -EBADF; newfid = v9fs_get_idpool(&v9ses->fidpool); --- 61,87 ---- long result = -1; ! dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); ! ! v9fid = v9fs_fid_get_created(file->f_dentry); ! if (!v9fid) ! v9fid = v9fs_fid_lookup(file->f_dentry); if (!v9fid) { dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); + return -EBADF; + } ! if (!v9fid->fidcreate) { ! fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); ! if (fid == NULL) { ! dprintk(DEBUG_ERROR, "Out of Memory\n"); ! return -ENOMEM; ! } ! fid->fidopen = 0; ! fid->fidcreate = 0; ! fid->fidclunked = 0; ! fid->iounit = 0; ! fid->v9ses = v9ses; newfid = v9fs_get_idpool(&v9ses->fidpool); *************** *** 85,90 **** result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, ! (char *)file->f_dentry->d_name.name, NULL); if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); --- 92,97 ---- result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL); ! if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); *************** *** 93,140 **** } ! v9fid = v9fs_fid_create(dentry); ! if (v9fid == NULL) { ! dprintk(DEBUG_ERROR, "couldn't insert\n"); ! return -ENOMEM; ! } ! v9fid->fid = newfid; ! } ! ! if (v9fid->fidcreate) { ! /* create case */ ! newfid = v9fid->fid; ! iounit = v9fid->iounit; ! v9fid->fidcreate = 0; ! } else { ! if (!S_ISDIR(inode->i_mode)) ! newfid = v9fid->fid; ! else { ! newfid = v9fs_get_idpool(&v9ses->fidpool); ! if (newfid < 0) { ! eprintk(KERN_WARNING, "allocation failed\n"); ! return -ENOSPC; ! } ! /* This would be a somewhat critical clone */ ! result = ! v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, ! &fcall); ! if (result < 0) { ! dprintk(DEBUG_ERROR, "clone error: %s\n", ! FCALL_ERROR(fcall)); ! kfree(fcall); ! return result; ! } ! ! v9newfid = v9fs_fid_create(file->f_dentry); ! v9newfid->fid = newfid; ! v9newfid->qid = v9fid->qid; ! v9newfid->iounit = v9fid->iounit; ! v9newfid->fidopen = 0; ! v9newfid->fidclunked = 0; ! v9newfid->v9ses = v9ses; ! v9fid = v9newfid; ! kfree(fcall); ! } ! /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ --- 100,105 ---- } ! fid->fid = newfid; ! v9fid = fid; /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ /* translate open mode appropriately */ *************** *** 154,160 **** result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); if (result < 0) { ! dprintk(DEBUG_ERROR, ! "open failed, open_mode 0x%x: %s\n", open_mode, ! FCALL_ERROR(fcall)); kfree(fcall); return result; --- 119,123 ---- result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); if (result < 0) { ! PRINT_FCALL_ERROR("open failed", fcall); kfree(fcall); return result; *************** *** 163,169 **** iounit = fcall->params.ropen.iounit; kfree(fcall); } - file->private_data = v9fid; --- 126,136 ---- iounit = fcall->params.ropen.iounit; kfree(fcall); + } else { + /* create case */ + newfid = v9fid->fid; + iounit = v9fid->iounit; + v9fid->fidcreate = 0; } file->private_data = v9fid; *************** *** 198,203 **** if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { ! filemap_fdatawrite(inode->i_mapping); ! filemap_fdatawait(inode->i_mapping); invalidate_inode_pages(&inode->i_data); } --- 165,169 ---- if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { ! filemap_write_and_wait(inode->i_mapping); invalidate_inode_pages(&inode->i_data); } *************** *** 207,211 **** /** ! * v9fs_read - read from a file (internal) * @filep: file pointer to read * @data: data buffer to read data into --- 173,177 ---- /** ! * v9fs_file_read - read from a file * @filep: file pointer to read * @data: data buffer to read data into *************** *** 214,220 **** * */ - static ssize_t ! v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; --- 180,186 ---- * */ static ssize_t ! v9fs_file_read(struct file *filp, char __user * data, size_t count, ! loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; *************** *** 226,229 **** --- 192,196 ---- int result = 0; int total = 0; + int n; dprintk(DEBUG_VFS, "\n"); *************** *** 248,255 **** *offset += result; ! /* XXX - extra copy */ ! memcpy(buffer, fcall->params.rread.data, result); count -= result; ! buffer += result; total += result; --- 215,227 ---- *offset += result; ! n = copy_to_user(data, fcall->params.rread.data, result); ! if (n) { ! dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n); ! kfree(fcall); ! return -EFAULT; ! } ! count -= result; ! data += result; total += result; *************** *** 264,303 **** /** ! * v9fs_file_read - read from a file ! * @filep: file pointer to read ! * @data: data buffer to read data into ! * @count: size of buffer ! * @offset: offset at which to read data ! * ! */ ! ! static ssize_t ! v9fs_file_read(struct file *filp, char __user * data, size_t count, ! loff_t * offset) ! { ! int retval = -1; ! int ret = 0; ! char *buffer; ! ! buffer = kmalloc(count, GFP_KERNEL); ! if (!buffer) ! return -ENOMEM; ! ! retval = v9fs_read(filp, buffer, count, offset); ! if (retval > 0) { ! if ((ret = copy_to_user(data, buffer, retval)) != 0) { ! dprintk(DEBUG_ERROR, "Problem copying to user %d\n", ! ret); ! retval = ret; ! } ! } ! ! kfree(buffer); ! ! return retval; ! } ! ! /** ! * v9fs_write - write to a file * @filep: file pointer to write * @data: data buffer to write data from --- 236,240 ---- /** ! * v9fs_file_write - write to a file * @filep: file pointer to write * @data: data buffer to write data from *************** *** 308,312 **** static ssize_t ! v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; --- 245,250 ---- static ssize_t ! v9fs_file_write(struct file *filp, const char __user * data, ! size_t count, loff_t * offset) { struct inode *inode = filp->f_dentry->d_inode; *************** *** 319,323 **** int total = 0; ! dprintk(DEBUG_VFS, "data %p count %d offset %x\n", buffer, (int)count, (int)*offset); rsize = v9ses->maxdata - V9FS_IOHDRSZ; --- 257,261 ---- int total = 0; ! dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count, (int)*offset); rsize = v9ses->maxdata - V9FS_IOHDRSZ; *************** *** 325,339 **** rsize = v9fid->iounit; - dump_data(buffer, count); - do { if (count < rsize) rsize = count; ! result = ! v9fs_t_write(v9ses, fid, *offset, rsize, buffer, &fcall); if (result < 0) { ! eprintk(KERN_ERR, "error while writing: %s(%d)\n", ! FCALL_ERROR(fcall), result); kfree(fcall); return result; --- 263,273 ---- rsize = v9fid->iounit; do { if (count < rsize) rsize = count; ! result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall); if (result < 0) { ! PRINT_FCALL_ERROR("error while writing", fcall); kfree(fcall); return result; *************** *** 342,345 **** --- 276,280 ---- kfree(fcall); + fcall = NULL; if (result != rsize) { *************** *** 351,392 **** count -= result; ! buffer += result; total += result; } while (count); ! return total; ! } ! ! /** ! * v9fs_file_write - write to a file ! * @filep: file pointer to write ! * @data: data buffer to write data from ! * @count: size of buffer ! * @offset: offset at which to write data ! * ! */ ! ! static ssize_t ! v9fs_file_write(struct file *filp, const char __user * data, ! size_t count, loff_t * offset) ! { ! int ret = -1; ! char *buffer; ! ! buffer = kmalloc(count, GFP_KERNEL); ! if (buffer == NULL) ! return -ENOMEM; ! ! ret = copy_from_user(buffer, data, count); ! if (ret) { ! dprintk(DEBUG_ERROR, "Problem copying from user\n"); ! ret = -EFAULT; ! } else { ! ret = v9fs_write(filp, buffer, count, offset); ! } ! ! kfree(buffer); ! return ret; } --- 286,297 ---- count -= result; ! data += result; total += result; } while (count); ! if(inode->i_mapping->nrpages) ! invalidate_inode_pages2(inode->i_mapping); ! return total; } *************** *** 398,400 **** --- 303,306 ---- .release = v9fs_dir_release, .lock = v9fs_file_lock, + .mmap = generic_file_mmap, }; Index: error.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/error.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** error.h 21 Sep 2005 17:43:51 -0000 2.2 --- error.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 37,40 **** --- 37,41 ---- int val; + int namelen; struct hlist_node list; }; *************** *** 176,178 **** extern int v9fs_error_init(void); - extern int v9fs_errstr2errno(char *errstr); --- 177,178 ---- Index: mux.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/mux.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** mux.c 21 Sep 2005 17:43:51 -0000 2.3 --- mux.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 5,9 **** * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> ! * Copyright (C) 2004 by Latchesar Ionkov <lu...@io...> * * This program is free software; you can redistribute it and/or modify --- 5,9 ---- * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> ! * Copyright (C) 2004-2005 by Latchesar Ionkov <lu...@io...> * [...1375 lines suppressed...] ! wake_up(&m->equeue); ! } ! static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m) ! { ! int tag; ! ! tag = v9fs_get_idpool(&m->tidpool); ! if (tag < 0) ! return V9FS_NOTAG; ! else ! return (u16) tag; ! } ! ! static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) ! { ! if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tidpool)) ! v9fs_put_idpool(tag, &m->tidpool); } Index: error.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/error.c,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** error.c 21 Sep 2005 17:43:51 -0000 2.2 --- error.c 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 55,59 **** /* load initial error map into hash table */ for (c = errmap; c->name != NULL; c++) { ! bucket = jhash(c->name, strlen(c->name), 0) % ERRHASHSZ; INIT_HLIST_NODE(&c->list); hlist_add_head(&c->list, &hash_errmap[bucket]); --- 55,60 ---- /* load initial error map into hash table */ for (c = errmap; c->name != NULL; c++) { ! c->namelen = strlen(c->name); ! bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ; INIT_HLIST_NODE(&c->list); hlist_add_head(&c->list, &hash_errmap[bucket]); *************** *** 69,81 **** */ ! int v9fs_errstr2errno(char *errstr) { int errno = 0; struct hlist_node *p = NULL; struct errormap *c = NULL; ! int bucket = jhash(errstr, strlen(errstr), 0) % ERRHASHSZ; hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { ! if (!strcmp(c->name, errstr)) { errno = c->val; break; --- 70,82 ---- */ ! int v9fs_errstr2errno(char *errstr, int len) { int errno = 0; struct hlist_node *p = NULL; struct errormap *c = NULL; ! int bucket = jhash(errstr, len, 0) % ERRHASHSZ; hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { ! if (c->namelen==len && !memcmp(c->name, errstr, len)) { errno = c->val; break; Index: vfs_super.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_super.c,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** vfs_super.c 21 Sep 2005 17:43:51 -0000 2.2 --- vfs_super.c 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 45,49 **** #include "9p.h" #include "v9fs_vfs.h" - #include "conv.h" #include "fid.h" --- 45,48 ---- *************** *** 93,97 **** sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | ! MS_NODIRATIME | MS_NOATIME; } --- 92,96 ---- sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | ! MS_NOATIME; } *************** *** 124,128 **** dprintk(DEBUG_VFS, " \n"); ! v9ses = kcalloc(1, sizeof(struct v9fs_session_info), GFP_KERNEL); if (!v9ses) return ERR_PTR(-ENOMEM); --- 123,127 ---- dprintk(DEBUG_VFS, " \n"); ! v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); if (!v9ses) return ERR_PTR(-ENOMEM); *************** *** 130,135 **** if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { dprintk(DEBUG_ERROR, "problem initiating session\n"); ! retval = newfid; ! goto free_session; } --- 129,134 ---- if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { dprintk(DEBUG_ERROR, "problem initiating session\n"); ! kfree(v9ses); ! return ERR_PTR(newfid); } *************** *** 151,180 **** if (!root) { retval = -ENOMEM; ! goto release_inode; } sb->s_root = root; - /* Setup the Root Inode */ - root_fid = v9fs_fid_create(root); - if (root_fid == NULL) { - retval = -ENOMEM; - goto release_dentry; - } - - root_fid->fidopen = 0; - root_fid->v9ses = v9ses; - stat_result = v9fs_t_stat(v9ses, newfid, &fcall); if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); ! v9fs_t_clunk(v9ses, newfid, NULL); v9fs_put_idpool(newfid, &v9ses->fidpool); } else { ! root_fid->fid = newfid; ! root_fid->qid = fcall->params.rstat.stat->qid; root->d_inode->i_ino = ! v9fs_qid2ino(&fcall->params.rstat.stat->qid); ! v9fs_mistat2inode(fcall->params.rstat.stat, root->d_inode, sb); } --- 150,175 ---- if (!root) { retval = -ENOMEM; ! goto put_back_sb; } sb->s_root = root; stat_result = v9fs_t_stat(v9ses, newfid, &fcall); if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); ! v9fs_t_clunk(v9ses, newfid); v9fs_put_idpool(newfid, &v9ses->fidpool); } else { ! /* Setup the Root Inode */ ! root_fid = v9fs_fid_create(root, v9ses, newfid, 0); ! if (root_fid == NULL) { ! retval = -ENOMEM; ! goto put_back_sb; ! } ! ! root_fid->qid = fcall->params.rstat.stat.qid; root->d_inode->i_ino = ! v9fs_qid2ino(&fcall->params.rstat.stat.qid); ! v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb); } *************** *** 183,205 **** if (stat_result < 0) { retval = stat_result; ! goto release_dentry; } return sb; ! release_dentry: ! dput(sb->s_root); ! ! release_inode: ! iput(inode); ! ! put_back_sb: up_write(&sb->s_umount); deactivate_super(sb); - v9fs_session_close(v9ses); - - free_session: - kfree(v9ses); - return ERR_PTR(retval); } --- 178,190 ---- if (stat_result < 0) { retval = stat_result; ! goto put_back_sb; } return sb; ! put_back_sb: ! /* deactivate_super calls v9fs_kill_super which will frees the rest */ up_write(&sb->s_umount); deactivate_super(sb); return ERR_PTR(retval); } --- idpool.c DELETED --- Index: conv.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/conv.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** conv.h 21 Sep 2005 17:43:51 -0000 2.2 --- conv.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 2,7 **** * linux/fs/9p/conv.h * ! * 9P protocol conversion definitions * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> --- 2,8 ---- * linux/fs/9p/conv.h * ! * 9P protocol conversion definitions. * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 25,36 **** */ ! int v9fs_deserialize_stat(struct v9fs_session_info *, void *buf, ! u32 buflen, struct v9fs_stat *stat, u32 statlen); ! int v9fs_serialize_fcall(struct v9fs_session_info *, struct v9fs_fcall *tcall, ! void *buf, u32 buflen); ! int v9fs_deserialize_fcall(struct v9fs_session_info *, u32 msglen, ! void *buf, u32 buflen, struct v9fs_fcall *rcall, ! int rcalllen); ! /* this one is actually in error.c right now */ ! int v9fs_errstr2errno(char *errstr); --- 26,51 ---- */ ! int v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, ! int extended); ! int v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, ! int extended); ! void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag); ! ! struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version); ! struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname); ! struct v9fs_fcall *v9fs_create_tattach(u32 fid, u32 afid, char *uname, ! char *aname); ! struct v9fs_fcall *v9fs_create_tflush(u16 oldtag); ! struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, ! char **wnames); ! struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); ! struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode); ! struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); ! struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, ! const char __user *data); ! struct v9fs_fcall *v9fs_create_tclunk(u32 fid); ! struct v9fs_fcall *v9fs_create_tremove(u32 fid); ! struct v9fs_fcall *v9fs_create_tstat(u32 fid); ! struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat, ! int extended); Index: 9p.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.c,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** 9p.c 21 Sep 2005 17:43:51 -0000 2.2 --- 9p.c 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 2,7 **** * linux/fs/9p/9p.c * ! * This file contains functions 9P2000 functions * * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> --- 2,8 ---- * linux/fs/9p/9p.c * ! * This file contains functions to perform synchronous 9P calls * + * Copyright (C) 2004 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 34,37 **** --- 35,39 ---- #include "v9fs.h" #include "9p.h" + #include "conv.h" #include "mux.h" *************** *** 47,60 **** int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, ! char *version, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version); ! msg.id = TVERSION; ! msg.params.tversion.msize = msize; ! msg.params.tversion.version = version; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 49,67 ---- int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, ! char *version, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version); ! tc = v9fs_create_tversion(msize, version); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 72,88 **** int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, ! u32 fid, u32 afid, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname, aname, fid, afid); - msg.id = TATTACH; - msg.params.tattach.fid = fid; - msg.params.tattach.afid = afid; - msg.params.tattach.uname = uname; - msg.params.tattach.aname = aname; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 79,121 ---- int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, ! u32 fid, u32 afid, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall* tc; dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname, aname, fid, afid); ! tc = v9fs_create_tattach(fid, afid, uname, aname); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; ! } ! ! static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, ! struct v9fs_fcall *rc, int err) ! { ! int fid; ! struct v9fs_session_info *v9ses; ! ! if (err) ! return; ! ! fid = tc->params.tclunk.fid; ! kfree(tc); ! ! if (!rc) ! return; ! ! dprintk(DEBUG_9P, "tcall id %d rcall id %d\n", tc->id, rc->id); ! v9ses = a; ! if (rc->id == RCLUNK) ! v9fs_put_idpool(fid, &v9ses->fidpool); ! ! kfree(rc); } *************** *** 96,109 **** int ! v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d\n", fid); - msg.id = TCLUNK; - msg.params.tclunk.fid = fid; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 129,151 ---- int ! v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid) { ! int ret; ! struct v9fs_fcall *tc, *rc; dprintk(DEBUG_9P, "fid %d\n", fid); ! rc = NULL; ! tc = v9fs_create_tclunk(fid); ! if (!IS_ERR(tc)) ! ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); ! else ! ret = PTR_ERR(tc); ! ! if (ret) ! dprintk(DEBUG_ERROR, "failed fid %d err %d\n", fid, ret); ! ! v9fs_t_clunk_cb(v9ses, tc, rc, ret); ! return ret; } *************** *** 115,126 **** */ ! int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 tag) { ! struct v9fs_fcall msg; ! dprintk(DEBUG_9P, "oldtag %d\n", tag); ! msg.id = TFLUSH; ! msg.params.tflush.oldtag = tag; ! return v9fs_mux_rpc(v9ses, &msg, NULL); } --- 157,175 ---- */ ! int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) { ! int ret; ! struct v9fs_fcall *tc; ! dprintk(DEBUG_9P, "oldtag %d\n", oldtag); ! ! tc = v9fs_create_tflush(oldtag); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, NULL); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 134,148 **** int ! v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d\n", fid); - if (fcall) - *fcall = NULL; ! msg.id = TSTAT; ! msg.params.tstat.fid = fid; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 183,202 ---- int ! v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d\n", fid); ! ret = -ENOMEM; ! tc = v9fs_create_tstat(fid); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 158,171 **** int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_stat *stat, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! dprintk(DEBUG_9P, "fid %d length %d\n", fid, (int)stat->length); ! msg.id = TWSTAT; ! msg.params.twstat.fid = fid; ! msg.params.twstat.stat = stat; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 212,230 ---- int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_wstat *wstat, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; ! dprintk(DEBUG_9P, "fid %d\n", fid); ! tc = v9fs_create_twstat(fid, wstat, v9ses->extended); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 184,204 **** int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, ! char *name, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name); - msg.id = TWALK; - msg.params.twalk.fid = fid; - msg.params.twalk.newfid = newfid; ! if (name) { ! msg.params.twalk.nwname = 1; ! msg.params.twalk.wnames = &name; ! } else { ! msg.params.twalk.nwname = 0; ! } ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 243,267 ---- int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, ! char *name, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; ! int nwname; dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name); ! if (name) ! nwname = 1; ! else ! nwname = 0; ! tc = v9fs_create_twalk(fid, newfid, nwname, &name); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 215,231 **** int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, ! struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! long errorno = -1; dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode); - msg.id = TOPEN; - msg.params.topen.fid = fid; - msg.params.topen.mode = mode; ! errorno = v9fs_mux_rpc(v9ses, &msg, fcall); ! return errorno; } --- 278,296 ---- int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, ! struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode); ! tc = v9fs_create_topen(fid, mode); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } *************** *** 240,251 **** int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d\n", fid); ! msg.id = TREMOVE; ! msg.params.tremove.fid = fid; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 305,323 ---- int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d\n", fid); ! ! tc = v9fs_create_tremove(fid); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! ! return ret; } *************** *** 263,280 **** int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, ! u32 perm, u8 mode, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", fid, name, perm, mode); ! msg.id = TCREATE; ! msg.params.tcreate.fid = fid; ! msg.params.tcreate.name = name; ! msg.params.tcreate.perm = perm; ! msg.params.tcreate.mode = mode; ! return v9fs_mux_rpc(v9ses, &msg, fcall); } --- 335,354 ---- int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, ! u32 perm, u8 mode, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc; dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", fid, name, perm, mode); ! tc = v9fs_create_tcreate(fid, name, perm, mode); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } *************** *** 291,319 **** int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, ! u32 count, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! struct v9fs_fcall *rc = NULL; ! long errorno = -1; ! dprintk(DEBUG_9P, "fid %d offset 0x%lx count 0x%x\n", fid, ! (long unsigned int)offset, count); ! msg.id = TREAD; ! msg.params.tread.fid = fid; ! msg.params.tread.offset = offset; ! msg.params.tread.count = count; ! errorno = v9fs_mux_rpc(v9ses, &msg, &rc); ! if (!errorno) { ! errorno = rc->params.rread.count; ! dump_data(rc->params.rread.data, rc->params.rread.count); ! } ! if (fcall) ! *fcall = rc; ! else ! kfree(rc); ! return errorno; } --- 365,391 ---- int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, ! u32 count, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc, *rc; ! dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, ! (long long unsigned) offset, count); ! tc = v9fs_create_tread(fid, offset, count); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); ! if (!ret) ! ret = rc->params.rread.count; ! if (rcp) ! *rcp = rc; ! else ! kfree(rc); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } *************** *** 329,359 **** int ! v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, ! u64 offset, u32 count, void *data, struct v9fs_fcall **fcall) { ! struct v9fs_fcall msg; ! struct v9fs_fcall *rc = NULL; ! long errorno = -1; ! ! dprintk(DEBUG_9P, "fid %d offset 0x%llx count 0x%x\n", fid, ! (unsigned long long)offset, count); ! dump_data(data, count); ! msg.id = TWRITE; ! msg.params.twrite.fid = fid; ! msg.params.twrite.offset = offset; ! msg.params.twrite.count = count; ! msg.params.twrite.data = data; ! errorno = v9fs_mux_rpc(v9ses, &msg, &rc); ! if (!errorno) ! errorno = rc->params.rwrite.count; ! if (fcall) ! *fcall = rc; ! else ! kfree(rc); ! return errorno; } --- 401,429 ---- int ! v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count, ! const char __user *data, struct v9fs_fcall **rcp) { ! int ret; ! struct v9fs_fcall *tc, *rc; ! dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, ! (long long unsigned) offset, count); ! tc = v9fs_create_twrite(fid, offset, count, data); ! if (!IS_ERR(tc)) { ! ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); ! if (!ret) ! ret = rc->params.rwrite.count; ! if (rcp) ! *rcp = rc; ! else ! kfree(rc); ! kfree(tc); ! } else ! ret = PTR_ERR(tc); ! return ret; } + Index: conv.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/conv.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** conv.c 21 Sep 2005 17:43:51 -0000 2.3 --- conv.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 4,7 **** --- 4,8 ---- * 9P protocol conversion functions * + * Copyright (C) 2004, 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 30,34 **** #include <linux/fs.h> #include <linux/idr.h> [...1355 lines suppressed...] ! struct cbuf buffer; ! struct cbuf *bufp = &buffer; ! ! statsz = v9fs_size_wstat(wstat, extended); ! size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ ! fc = v9fs_create_common(bufp, size, TWSTAT); ! if (IS_ERR(fc)) ! goto error; ! ! v9fs_put_int32(bufp, fid, &fc->params.twstat.fid); ! buf_put_int16(bufp, statsz + 2); ! v9fs_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, extended); ! ! if (buf_check_overflow(bufp)) { ! kfree(fc); ! fc = ERR_PTR(-ENOMEM); ! } ! error: ! return fc; } --- idpool.h DELETED --- Index: v9fs.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** v9fs.c 21 Sep 2005 17:43:51 -0000 2.3 --- v9fs.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 38,42 **** #include "transport.h" #include "mux.h" - #include "conv.h" /* TODO: sysfs or debugfs interface */ --- 38,41 ---- *************** *** 68,72 **** {Opt_rfdno, "rfdno=%u"}, {Opt_wfdno, "wfdno=%u"}, ! {Opt_debug, "debug=%u"}, {Opt_name, "name=%s"}, {Opt_remotename, "aname=%s"}, --- 67,71 ---- {Opt_rfdno, "rfdno=%u"}, {Opt_wfdno, "wfdno=%u"}, ! {Opt_debug, "debug=%x"}, {Opt_name, "name=%s"}, {Opt_remotename, "aname=%s"}, *************** *** 214,218 **** } ! error = idr_get_new(&p->pool, NULL, &i); up(&p->lock); --- 213,218 ---- } ! /* no need to store exactly p, we just need something non-null */ ! error = idr_get_new(&p->pool, p, &i); up(&p->lock); *************** *** 244,247 **** --- 244,257 ---- /** + * v9fs_check_idpool - check if the specified id is available + * @id - id to check + * @p - pool + */ + int v9fs_check_idpool(int id, struct v9fs_idpool *p) + { + return idr_find(&p->pool, id) != NULL; + } + + /** * v9fs_session_init - initialize session * @v9ses: session information structure *************** *** 260,263 **** --- 270,274 ---- int newfid = -1; int retval = -EINVAL; + struct v9fs_str *version; v9ses->name = __getname(); *************** *** 267,271 **** v9ses->remotename = __getname(); if (!v9ses->remotename) { ! putname(v9ses->name); return -ENOMEM; } --- 278,282 ---- v9ses->remotename = __getname(); if (!v9ses->remotename) { ! __putname(v9ses->name); return -ENOMEM; } *************** *** 282,288 **** idr_init(&v9ses->fidpool.pool); init_MUTEX(&v9ses->fidpool.lock); - idr_init(&v9ses->tidpool.pool); - init_MUTEX(&v9ses->tidpool.lock); - switch (v9ses->proto) { --- 293,296 ---- *************** *** 304,308 **** }; ! v9ses->transport = trans_proto; if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { --- 312,322 ---- }; ! v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL); ! if (!v9ses->transport) { ! retval = -ENOMEM; ! goto SessCleanUp; ! } ! ! memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport)); if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { *************** *** 315,319 **** v9ses->session_hung = 0; ! if ((retval = v9fs_mux_init(v9ses, dev_name)) < 0) { dprintk(DEBUG_ERROR, "problem initializing mux\n"); goto SessCleanUp; --- 329,338 ---- v9ses->session_hung = 0; ! v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ, ! &v9ses->extended); ! ! if (IS_ERR(v9ses->mux)) { ! retval = PTR_ERR(v9ses->mux); ! v9ses->mux = NULL; dprintk(DEBUG_ERROR, "problem initializing mux\n"); goto SessCleanUp; *************** *** 334,344 **** } ! /* Really should check for 9P1 and report error */ ! if (!strcmp(fcall->params.rversion.version, "9P2000.u")) { dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); v9ses->extended = 1; ! } else { dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); v9ses->extended = 0; } --- 353,366 ---- } ! version = &fcall->params.rversion.version; ! if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) { dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); v9ses->extended = 1; ! } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) { dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); v9ses->extended = 0; + } else { + retval = -EREMOTEIO; + goto FreeFcall; } *************** *** 376,380 **** if (v9ses->afid != ~0) { ! if (v9fs_t_clunk(v9ses, v9ses->afid, NULL)) dprintk(DEBUG_ERROR, "clunk failed\n"); } --- 398,402 ---- if (v9ses->afid != ~0) { ! if (v9fs_t_clunk(v9ses, v9ses->afid)) dprintk(DEBUG_ERROR, "clunk failed\n"); } *************** *** 398,420 **** void v9fs_session_close(struct v9fs_session_info *v9ses) { ! if (v9ses->recvproc) { ! send_sig(SIGKILL, v9ses->recvproc, 1); ! wait_for_completion(&v9ses->proccmpl); } ! if (v9ses->transport) v9ses->transport->close(v9ses->transport); ! putname(v9ses->name); ! putname(v9ses->remotename); } /** ! * v9fs_session_cancel - mark transport as disconnected * and cancel all pending requests. */ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { v9ses->transport->status = Disconnected; ! v9fs_mux_cancel_requests(v9ses, -EIO); } --- 420,446 ---- void v9fs_session_close(struct v9fs_session_info *v9ses) { ! if (v9ses->mux) { ! v9fs_mux_destroy(v9ses->mux); ! v9ses->mux = NULL; } ! if (v9ses->transport) { v9ses->transport->close(v9ses->transport); + kfree(v9ses->transport); + v9ses->transport = NULL; + } ! __putname(v9ses->name); ! __putname(v9ses->remotename); } /** ! * v9fs_session_cancel - mark transport as disconnected * and cancel all pending requests. */ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { + dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses); v9ses->transport->status = Disconnected; ! v9fs_mux_cancel(v9ses->mux, -EIO); } *************** *** 428,436 **** static int __init init_v9fs(void) { v9fs_error_init(); printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); ! return register_filesystem(&v9fs_fs_type); } --- 454,468 ---- static int __init init_v9fs(void) { + int ret; + v9fs_error_init(); printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); ! ret = v9fs_mux_global_init(); ! if (!ret) ! ret = register_filesystem(&v9fs_fs_type); ! ! return ret; } *************** *** 442,445 **** --- 474,478 ---- static void __exit exit_v9fs(void) { + v9fs_mux_global_exit(); unregister_filesystem(&v9fs_fs_type); } Index: transport.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/transport.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** transport.h 21 Sep 2005 17:43:51 -0000 2.2 --- transport.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 4,7 **** --- 4,8 ---- * Transport Definition * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * *************** *** 32,37 **** struct v9fs_transport { enum v9fs_transport_status status; - struct semaphore writelock; - struct semaphore readlock; void *priv; --- 33,36 ---- *************** *** 40,43 **** --- 39,43 ---- int (*read) (struct v9fs_transport *, void *, int); void (*close) (struct v9fs_transport *); + unsigned int (*poll)(struct v9fs_transport *, struct poll_table_struct *); }; Index: v9fs.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** v9fs.h 21 Sep 2005 17:43:51 -0000 2.2 --- v9fs.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 58,79 **** /* book keeping */ struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ - struct v9fs_idpool tidpool; /* The TID pool for transactions ids */ - /* transport information */ struct v9fs_transport *transport; int inprogress; /* session in progress => true */ int shutdown; /* session shutting down. no more attaches. */ unsigned char session_hung; ! ! /* mux private data */ ! struct v9fs_fcall *curfcall; ! wait_queue_head_t read_wait; ! struct completion fcread; ! struct completion proccmpl; ! struct task_struct *recvproc; ! ! spinlock_t muxlock; ! struct list_head mux_fcalls; }; --- 58,69 ---- /* book keeping */ struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ struct v9fs_transport *transport; + struct v9fs_mux_data *mux; int inprogress; /* session in progress => true */ int shutdown; /* session shutting down. no more attaches. */ unsigned char session_hung; ! struct dentry *debugfs_dir; }; *************** *** 85,88 **** --- 75,80 ---- }; + extern struct dentry *v9fs_debugfs_root; + int v9fs_session_init(struct v9fs_session_info *, const char *, char *); struct v9fs_session_info *v9fs_inode2v9ses(struct inode *); *************** *** 90,93 **** --- 82,86 ---- int v9fs_get_idpool(struct v9fs_idpool *p); void v9fs_put_idpool(int id, struct v9fs_idpool *p); + int v9fs_check_idpool(int id, struct v9fs_idpool *p); void v9fs_session_cancel(struct v9fs_session_info *v9ses); *************** *** 102,103 **** --- 95,109 ---- #define V9FS_START_FIDS 8192 #define V9FS_START_TIDS 256 + + #include <linux/version.h> + + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)) + #define filemap_write_and_wait(x) \ + do{ \ + filemap_fdatawrite(x); \ + filemap_fdatawait(x); \ + } while(0) + #define kzalloc(x,y) kmalloc(x,y) + + #endif + Index: v9fs_vfs.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/v9fs_vfs.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** v9fs_vfs.h 21 Sep 2005 17:43:51 -0000 2.2 --- v9fs_vfs.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 40,43 **** --- 40,44 ---- extern struct file_system_type v9fs_fs_type; + extern struct address_space_operations v9fs_addr_operations; extern struct file_operations v9fs_file_operations; extern struct file_operations v9fs_dir_operations; *************** *** 46,53 **** struct inode *v9fs_get_inode(struct super_block *sb, int mode); ino_t v9fs_qid2ino(struct v9fs_qid *qid); ! void v9fs_mistat2inode(struct v9fs_stat *, struct inode *, ! struct super_block *); int v9fs_dir_release(struct inode *inode, struct file *filp); int v9fs_file_open(struct inode *inode, struct file *file); ! void v9fs_inode2mistat(struct inode *inode, struct v9fs_stat *mistat); void v9fs_dentry_release(struct dentry *); --- 47,53 ---- struct inode *v9fs_get_inode(struct super_block *sb, int mode); ino_t v9fs_qid2ino(struct v9fs_qid *qid); ! void v9fs_stat2inode(struct v9fs_stat *, struct inode *, struct super_block *); int v9fs_dir_release(struct inode *inode, struct file *filp); int v9fs_file_open(struct inode *inode, struct file *file); ! void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat); void v9fs_dentry_release(struct dentry *); Index: vfs_inode.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_inode.c,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** vfs_inode.c 21 Sep 2005 17:43:51 -0000 2.4 --- vfs_inode.c 2 Mar 2006 21:30:17 -0000 2.5 *************** *** 41,45 **** #include "9p.h" #include "v9fs_vfs.h" - #include "conv.h" #include "fid.h" --- 41,44 ---- *************** *** 128,225 **** /** [...1313 lines suppressed...] ! if (!new_valid_dev(rdev)) ! return -EINVAL; + name = __getname(); /* build extension */ if (S_ISBLK(mode)) ! sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); else if (S_ISCHR(mode)) ! sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev)); else if (S_ISFIFO(mode)) ! *name = 0; else { ! __putname(name); ! return -EINVAL; } ! retval = v9fs_vfs_mkspecial(dir, dentry, mode, name); ! __putname(name); return retval; Index: Makefile =================================================================== RCS file: /cvsroot/v9fs/linux-9p/Makefile,v retrieving revision 2.1 retrieving revision 2.2 diff -C2 -d -r2.1 -r2.2 *** Makefile 21 Sep 2005 17:43:51 -0000 2.1 --- Makefile 2 Mar 2006 21:30:17 -0000 2.2 *************** *** 1,22 **** ! KDIR := /lib/modules/$(shell uname -r)/build ! ! obj-$(CONFIG_9P_FS) := 9p2000.o ! 9p2000-objs := \ ! vfs_super.o \ ! vfs_inode.o \ ! vfs_file.o \ ! vfs_dir.o \ ! vfs_dentry.o \ ! idpool.o \ ! error.o \ ! mux.o \ ! trans_sock.o \ ! trans_fd.o \ ! 9p.o \ ! conv.o \ ! v9fs.o \ ! fid.o default: ! CONFIG_9P_FS=m make -C $(KDIR) SUBDIRS=`pwd` modules --- 1,25 ---- ! 9p2000-objs := fid.o vfs_super.o vfs_inode.o vfs_dentry.o vfs_file.o vfs_addr.o vfs_dir.o error.o mux.o trans_fd.o 9p.o conv.o v9fs.o ! ifneq ($(KERNELRELEASE),) ! obj-m := 9p2000.o ! else ! KERNELDIR ?= /lib/modules/$(shell uname -r)/build ! PWD := $(shell pwd) default: ! $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ! endif ! ! EXTRA_CFLAGS += -Wall ! ! install: ! make -C ${KERNEL_SOURCE} SUBDIRS=`pwd` modules_install ! ! clean: ! rm -f *.o kver *~ ! ! mods: v9fs_ ! /sbin/insmod -m > v9fs.map v9fs.ko ! ! rmods: ! -/sbin/rmmod v9fs Index: vfs_dir.c =================================================================== RCS file: /cvsroot/v9fs/linux-9p/vfs_dir.c,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** vfs_dir.c 21 Sep 2005 17:43:51 -0000 2.3 --- vfs_dir.c 2 Mar 2006 21:30:17 -0000 2.4 *************** *** 38,43 **** #include "v9fs.h" #include "9p.h" - #include "v9fs_vfs.h" #include "conv.h" #include "fid.h" --- 38,43 ---- #include "v9fs.h" #include "9p.h" #include "conv.h" + #include "v9fs_vfs.h" #include "fid.h" *************** *** 75,82 **** struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); struct v9fs_fid *file = filp->private_data; ! unsigned int i, n; int fid = -1; int ret = 0; ! struct v9fs_stat *mi = NULL; int over = 0; --- 75,82 ---- struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); struct v9fs_fid *file = filp->private_data; ! unsigned int i, n, s; int fid = -1; int ret = 0; ! struct v9fs_stat stat; int over = 0; *************** *** 85,92 **** fid = file->fid; - mi = kmalloc(v9ses->maxdata, GFP_KERNEL); - if (!mi) - return -ENOMEM; - if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) { kfree(file->rdir_fcall); --- 85,88 ---- *************** *** 98,115 **** i = file->rdir_fpos; while (i < n) { ! int s = v9fs_deserialize_stat(v9ses, ! file->rdir_fcall->params.rread.data + i, ! n - i, mi, v9ses->maxdata); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing mistat\n"); ret = -EIO; goto FreeStructs; } ! over = filldir(dirent, mi->name, strlen(mi->name), ! filp->f_pos, v9fs_qid2ino(&mi->qid), ! dt_type(mi)); if (over) { --- 94,111 ---- i = file->rdir_fpos; while (i < n) { ! s = v9fs_deserialize_stat( ! file->rdir_fcall->params.rread.data + i, ! n - i, &stat, v9ses->extended); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing stat\n"); ret = -EIO; goto FreeStructs; } ! over = filldir(dirent, stat.name.str, stat.name.len, ! filp->f_pos, v9fs_qid2ino(&stat.qid), ! dt_type(&stat)); if (over) { *************** *** 131,135 **** while (!over) { ret = v9fs_t_read(v9ses, fid, filp->f_pos, ! v9ses->maxdata-V9FS_IOHDRSZ, &fcall); if (ret < 0) { dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", --- 127,131 ---- while (!over) { ret = v9fs_t_read(v9ses, fid, filp->f_pos, ! v9ses->maxdata-V9FS_IOHDRSZ, &fcall); if (ret < 0) { dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", *************** *** 142,158 **** i = 0; while (i < n) { ! int s = v9fs_deserialize_stat(v9ses, ! fcall->params.rread.data + i, n - i, mi, ! v9ses->maxdata); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing mistat\n"); return -EIO; } ! over = filldir(dirent, mi->name, strlen(mi->name), ! filp->f_pos, v9fs_qid2ino(&mi->qid), ! dt_type(mi)); if (over) { --- 138,153 ---- i = 0; while (i < n) { ! s = v9fs_deserialize_stat(fcall->params.rread.data + i, ! n - i, &stat, v9ses->extended); if (s == 0) { dprintk(DEBUG_ERROR, ! "error while deserializing stat\n"); return -EIO; } ! over = filldir(dirent, stat.name.str, stat.name.len, ! filp->f_pos, v9fs_qid2ino(&stat.qid), ! dt_type(&stat)); if (over) { *************** *** 173,177 **** FreeStructs: kfree(fcall); - kfree(mi); return ret; } --- 168,171 ---- *************** *** 194,216 **** fidnum = fid->fid; ! filemap_fdatawrite(inode->i_mapping); ! filemap_fdatawait(inode->i_mapping); if (fidnum >= 0) { - fid->fidopen--; dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, fid->fid); ! if (fid->fidopen == 0) { ! if (v9fs_t_clunk(v9ses, fidnum, NULL)) ! dprintk(DEBUG_ERROR, "clunk failed\n"); ! ! v9fs_put_idpool(fid->fid, &v9ses->fidpool); ! } kfree(fid->rdir_fcall); filp->private_data = NULL; - v9fs_fid_destroy(fid); } --- 188,204 ---- fidnum = fid->fid; ! filemap_write_and_wait(inode->i_mapping); if (fidnum >= 0) { dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, fid->fid); ! if (v9fs_t_clunk(v9ses, fidnum)) ! dprintk(DEBUG_ERROR, "clunk failed\n"); kfree(fid->rdir_fcall); + kfree(fid); filp->private_data = NULL; } Index: TODO =================================================================== RCS file: /cvsroot/v9fs/linux-9p/TODO,v retrieving revision 2.0 retrieving revision 2.1 diff -C2 -d -r2.0 -r2.1 *** TODO 6 Jun 2005 19:26:50 -0000 2.0 --- TODO 2 Mar 2006 21:30:17 -0000 2.1 *************** *** 1,29 **** - Things which need to be done: - - Clean-ness: - * delay module removal for system to quiesce - (need to wait for stuff to shut down before trying to free slabs) - * review mistat allocation (of maxdata) - this seems overzealous - - Peformance: - * remove extra copies in read and write path - * performance tuning - * come up with a cache model - * support multiple walks in t_walk and leverage from VFS - - 9P Correctness: - * revisit transient clunks - * new attach per user in extended mode - * Do a full validation versus Russ Cox's Plan 9 from User Space - - Future: - * locking infrastructure support - * kernel mode server (with Plan 9 srv like infrastructure) - * security/authentication support - - (See sourceforge bug-tracking for known bugs) - - Current batch of linux-kernel/linux-mentors/linux-fsdevel requests: - ------------------------------------------------------ - - (empty?) --- 0 ---- Index: debug.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/debug.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** debug.h 21 Sep 2005 17:43:51 -0000 2.2 --- debug.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 52,65 **** static inline void dump_data(const unsigned char *data, unsigned int datalen) { ! int i, j; ! int len = datalen; ! printk(KERN_DEBUG "data "); ! for (i = 0; i < len; i += 4) { ! for (j = 0; (j < 4) && (i + j < len); j++) ! printk(KERN_DEBUG "%02x", data[i + j]); ! printk(KERN_DEBUG " "); } ! printk(KERN_DEBUG "\n"); } #else /* DEBUG_DUMP_PKT */ --- 52,72 ---- static inline void dump_data(const unsigned char *data, unsigned int datalen) { ! int i, n; ! char buf[5*8]; ! n = 0; ! i = 0; ! while (i < datalen) { ! n += snprintf(buf+n, sizeof(buf)-n, "%02x", data[i++]); ! if (i%4 == 0) ! n += snprintf(buf+n, sizeof(buf)-n, " "); ! ! if (i%16 == 0) { ! dprintk(DEBUG_ERROR, "%s\n", buf); ! n = 0; ! } } ! ! dprintk(DEBUG_ERROR, "%s\n", buf); } #else /* DEBUG_DUMP_PKT */ Index: 9p.h =================================================================== RCS file: /cvsroot/v9fs/linux-9p/9p.h,v retrieving revision 2.2 retrieving revision 2.3 diff -C2 -d -r2.2 -r2.3 *** 9p.h 21 Sep 2005 17:43:51 -0000 2.2 --- 9p.h 2 Mar 2006 21:30:17 -0000 2.3 *************** *** 4,7 **** --- 4,8 ---- * 9P protocol definitions. * + * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * Copyright (C) 2004 by Eric Van Hensbergen <er...@gm...> * Copyright (C) 2002 by Ron Minnich <rmi...@la...> *************** *** 101,107 **** --- 102,117 ---- }; + #define V9FS_NOTAG (u16)(~0) + #define V9FS_NOFID (u32)(~0) + #define V9FS_MAXWELEM 16 + /* ample room for Twrite/Rread header (iounit) */ #define V9FS_IOHDRSZ 24 + struct v9fs_str { + u16 len; + char *str; + }; + /* qids are the unique ID for a file (like an inode */ struct v9fs_qid { *************** *** 121,124 **** --- 131,157 ---- u32 mtime; u64 length; + struct v9fs_str name; + struct v9fs_str uid; + struct v9fs_str gid; + struct v9fs_str muid; + struct v9fs_str extension; /* 9p2000.u extensions */ + u32 n_uid; /* 9p2000.u extensions */ + u32 n_gid; /* 9p2000.u extensions */ + u32 n_muid; /* 9p2000.u extensions */ + }; + + /* file metadata (stat) structure used to create Twstat message + The is similar to v9fs_stat, but the strings don't point to + the same memory block and should be freed separately + */ + struct v9fs_wstat { + u16 size; + u16 type; + u32 dev; + struct v9fs_qid qid; + u32 mode; + u32 atime; + u32 mtime; + u64 length; char *name; char *uid; *************** *** 129,133 **** u32 n_gid; /* 9p2000.u extensions */ u32 n_muid; /* 9p2000.u extensions */ - char data[0]; }; --- 162,165 ---- *************** *** 136,151 **** struct Tversion { u32 msize; ! char *version; }; struct Rversion { u32 msize; ! char *version; }; struct Tauth { u32 afid; ! char *uname; ! char *aname; }; --- 168,183 ---- struct Tversion { u32 msize; ! struct v9fs_str version; }; struct Rversion { u32 msize; ! struct v9fs_str version; }; struct Tauth { u32 afid; ! struct v9fs_str uname; ! struct v9fs_str aname; }; *************** *** 155,164 **** struct Rerror { ! char *error; u32 errno; /* 9p2000.u extension */ }; struct Tflush { ! u32 oldtag; }; --- 187,196 ---- struct Rerror { ! struct v9fs_str error; u32 errno; /* 9p2000.u extension */ }; struct Tflush { ! u16 oldtag; }; *************** *** 169,174 **** u32 fid; u32 afid; ! char *uname; ! char *aname; }; --- 201,206 ---- u32 fid; u32 afid; ! struct v9fs_str uname; ! struct v9fs_str aname; }; *************** *** 180,190 **** u32 fid; u32 newfid; ! u32 nwname; ! char **wnames; }; struct Rwalk { ! u32 nwqid; ! struct v9fs_qid *wqids; }; --- 212,222 ---- u32 fid; u32 newfid; ! u16 nwname; ! struct v9fs_str wnames[16]; }; struct Rwalk { ! u16 nwqid; ! struct v9fs_qid wqids[16]; }; *************** *** 201,205 **** struct Tcreate { u32 fid; ! char *name; u32 perm; u8 mode; --- 233,237 ---- struct Tcreate { u32 fid; ! struct v9fs_str name; u32 perm; u8 mode; *************** *** 252,261 **** struct Rstat { ! struct v9fs_stat *stat; }; struct Twstat { u32 fid; ! struct v9fs_stat *stat; }; --- 284,293 ---- struct Rstat { ! struct v9fs_stat stat; }; struct Twstat { u32 fid; ! struct v9fs_stat stat; }; *************** *** 272,275 **** --- 304,308 ---- u8 id; u16 tag; + void *sdata; union { *************** *** 304,308 **** }; ! #define FCALL_ERROR(fcall) (fcall ? fcall->params.rerror.error : "") int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, --- 337,343 ---- }; ! #define PRINT_FCALL_ERROR(s, fcall) dprintk(DEBUG_ERROR, "%s: %.*s\n", s, \ ! fcall?fcall->params.rerror.error.len:0, \ ! fcall?fcall->params.rerror.error.str:""); int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, *************** *** 312,317 **** u32 fid, u32 afid, struct v9fs_fcall **rcall); ! int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_fcall **rcall); int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag); --- 347,351 ---- u32 fid, u32 afid, struct v9fs_fcall **rcall); ! int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid); int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag); *************** *** 321,325 **** int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, ! struct v9fs_stat *stat, struct v9... [truncated message content] |
From: Eric V. H. <er...@us...> - 2006-02-19 20:53:12
|
Update of /cvsroot/v9fs/tests/iozone/src/current In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5556/iozone/src/current Added Files: Changes.txt Generate_Graphs Gnuplot.txt client_list fileop.c gengnuplot.sh gnu3d.dem gnuplot.dem gnuplotps.dem iozone.c libasync.c libbif.c makefile read_telemetry report.pl spec.in write_telemetry Log Message: Add iozone to tests --- NEW FILE: report.pl --- #!/usr/bin/perl # # arguments: one of more report files # # Christian Mautner <christian * mautner . ca>, 2005-10-31 # # This script is based loosely on the Generate_Graph set # of scripts that come with iozone, but is a complete re-write # # The main reason to write this was the need to compare the behaviour of # two or more different setups, for tuning filesystems or # comparing different pieces of hardware. # # This script is in the public domain, too short and too trivial # to deserve a copyright. # # Simply run iozone like, for example, ./iozone -a -g 4G > config1.out (if your machine has 4GB) # and then run perl report.pl config1.out # or get another report from another box into config2.out and run # perl report.pl config1.out config2.out # the look in the report_* directory for .png # # If you don't like png or the graphic size, search for "set terminal" in this file and put whatever gnuplot # terminal you want. Note I've also noticed that gnuplot switched the set terminal png syntax # a while back, you might need "set terminal png small size 900,700" # @Reports=@ARGV; die "usage: $0 <iozone.out> [<iozone2.out>...]\n" if not @Reports or grep (m|^-|, @Reports); die "report files must be in current directory" if grep (m|/|, @Reports); %columns=( 'write' =>3, 'read' =>5, 'rewrite' =>4, 'reread' =>6, 'randread' =>7, 'randwrite' =>8, 'bkwdread' =>9, 'recrewrite'=>10, 'strideread'=>11, 'fwrite' =>12, 'frewrite' =>13, 'fread' =>14, 'freread' =>15, ); # # create output directory. the name is the concatenation # of all report file names (minus the file extension, plus # prefix report_) # $outdir="report_".join("_",map{/([^\.]+)(\..*)?/ && $1}(@Reports)); print STDERR "Output directory: $outdir "; if ( -d $outdir ) { print STDERR "(removing old directory) "; system "rm -rf $outdir"; } mkdir $outdir or die "cannot make directory $outdir"; print STDERR "done.\nPreparing data files..."; foreach $report (@Reports) { open(I, $report) or die "cannot open $report for reading"; $report=~/^([^\.]+)/; $datafile="$1.dat"; push @datafiles, $datafile; open(O, ">$outdir/$datafile") or die "cannot open $outdir/$datafile for writing"; open(O2, ">$outdir/2d-$datafile") or die "cannot open $outdir/$datafile for writing"; while(<I>) { next unless ( /^[\s\d]+$/ ); @split = split(); next unless ( @split == 15 ); print O; print O2 if $split[1] == 16384 or $split[0] == $split[1]; } close I, O, O2; } print STDERR "done.\nGenerating graphs:"; foreach $column (keys %columns) { print STDERR " $column"; open(G, ">$outdir/$column.do") or die "cannot open $outdir/$column.do for writing"; print G qq{ set title "Iozone performance: $column" set grid lt 2 lw 1 set surface set parametric set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [2.**5:2.**24] set xlabel "File size in KBytes" set ylabel "Record size in Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 set terminal png small picsize 900 700 set output "$column.png" }; print G "splot ". join(", ", map{qq{"$_" using 1:2:$columns{$column} title "$_"}}(@datafiles)); print G "\n"; close G; open(G, ">$outdir/2d-$column.do") or die "cannot open $outdir/$column.do for writing"; print G qq{ set title "Iozone performance: $column" set terminal png small picsize 450 350 set logscale x set xlabel "File size in KBytes" set ylabel "Kbytes/sec" set output "2d-$column.png" }; print G "plot ". join(", ", map{qq{"2d-$_" using 1:$columns{$column} title "$_" with lines}}(@datafiles)); print G "\n"; close G; if ( system("cd $outdir && gnuplot $column.do && gnuplot 2d-$column.do") ) { print STDERR "(failed) "; } else { print STDERR "(ok) "; } } print STDERR "done.\n"; --- NEW FILE: gnuplot.dem --- # # $Id: Plot of latency versus offset in a file # # Requires data file "wol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system write latency " set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" plot 'wol.dat' using 1:2 title "Latency Plot" with lines pause -1 "Hit return to continue" # # $Id: Plot of latency versus offset in a file # # Requires data file "rwol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system re-write latency " set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" plot 'rwol.dat' using 1:2 title "Latency Plot" with lines pause -1 "Hit return to continue" # # $Id: Plot of latency versus offset in a file # # Requires data file "rol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system read latency " set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" plot 'rol.dat' using 1:2 title "Latency Plot" with lines pause -1 "Hit return to continue" # # $Id: Plot of latency versus offset in a file # # Requires data file "rrol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system re-read latency " set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" plot 'rrol.dat' using 1:2 title "Latency Plot" with lines pause -1 "Hit return to continue" --- NEW FILE: gengnuplot.sh --- #!/bin/sh # # Copyright (c) 2001 Yves Rougy Yv...@Ro... # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA cp $1 iozone_gen_out file_name=iozone_gen_out #set -x write_gnuplot_file() { echo \#test : $query case $query in (write) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $3 }' < $file_name ;; (rewrite) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $4 }' < $file_name ;; (read) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $5 }' < $file_name ;; (reread) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $6 }' < $file_name ;; (randread) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $7 }' < $file_name ;; (randwrite) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $8 }' < $file_name ;; (bkwdread) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $9 }' < $file_name ;; (recrewrite) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $10 }' < $file_name ;; (strideread) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $11 }' < $file_name ;; (fwrite) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $12 }' < $file_name ;; (frewrite) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $13 }' < $file_name ;; (fread) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $14 }' < $file_name ;; (freread) awk '$1 ~ /^[0-9]+/ { print $1 " " $2 " " $15 }' < $file_name ;; (*) echo "Usage : gengnuplot.sh <filename> <test>" >> /dev/stderr ; echo "filename is the output of iozone -a" >> /dev/stderr ; echo "test is one of write rewrite read reread randread randwrite bkwdread recrewrite strideread fwrite frewrite fread freread" >> /dev/stderr ;; esac } #filename=$1 filename=iozone_gen_out query=$2 if (! [ -e $query ] ) ; then mkdir $query; fi if ( [ $# -eq 2 ] ) ; then write_gnuplot_file > $query/`basename $file_name.gnuplot` else echo "Usage : gengnuplot.sh <filename> <test>" 2>&1 echo "filename is the output of iozone -a" 2>&1 echo "test is one of write rewrite read reread randread randwrite bkwdread recrewrite strideread fwrite frewrite fread freread" 2>&1 fi --- NEW FILE: libasync.c --- /* * Library for Posix async read operations with hints. * Author: Don Capps * Company: Hewlett Packard * Date: 4/24/1998 * * Two models are supported. First model is a replacement for read() where the async * operations are performed and the requested data is bcopy()-ed back into the users * buffer. The second model is a new version of read() where the caller does not * supply the address of the buffer but instead is returned an address to the * location of the data. The second model eliminates a bcopy from the path. * * To use model #1: * 1. Call async_init(&pointer_on_stack,fd,direct_flag); * The fd is the file descriptor for the async operations. * The direct_flag sets VX_DIRECT * [...1505 lines suppressed...] ce->myaiocb.aio_offset, ce->myaiocb.aio_nbytes); #endif exit(182); } } else { return((ssize_t)size); } } void mbcopy(source, dest, len) char *source,*dest; size_t len; { int i; for(i=0;i<len;i++) *dest++=*source++; } --- NEW FILE: Changes.txt --- V1.0 (capps): Capps: Beginning of the code base. Isom: Added reread Added rewrite Added read backwards Added lseek+read Added lseek+reread Capps: Added more accurate time collection method. Added alignment in the on chip Cache code. Added change step when passing 16 Meg size file. Capps: Added auto+ to purge on chip cache. kcollins: [...1967 lines suppressed...] ============================================================================= Revision 3.255 ============================================================================= Add -+K flag for Sony. ============================================================================= Revision 3.256 ============================================================================= Move -+K outside of Windows only. ============================================================================= Revision 3.257 ============================================================================= Simplify percentage calculation ============================================================================= Revision 3.258 ============================================================================= Add error checking for -f and -F in the wrong modes. ============================================================================= Revision 3.259 ============================================================================= Bug fix for pbuffer allocation on remote clients. --- NEW FILE: iozone.c --- /************************************************************************/ /* Original Author: */ /* William Norcott (wno...@us...) */ /* 4 Dunlap Drive */ /* Nashua, NH 03060 */ /* */ /************************************************************************/ /* Enhancements by: */ /* Don Capps (ca...@io...) */ /* 7417 Crenshaw */ /* Plano, TX 75025 */ /* */ /************************************************************************/ /* Copyright 1991, 1992, 1994, 1998, 2000, 2001 William D. Norcott */ /************************************************************************/ /* */ /* Iozone is based on the original work done by William Norrcot. It has */ /* been enhanced so that it provides a more complete filesystem */ /* characterization. */ [...20812 lines suppressed...] * Allocate the buffer for purge. */ void alloc_pbuf(void) { pbuffer = (char *) alloc_mem((long long)(3 * cache_size),(int)0); if(pbuffer == 0) { perror("Memory allocation failed:"); exit(9); } #ifdef _64BIT_ARCH_ pbuffer = (char *) (((unsigned long long)pbuffer + cache_size ) & ~(cache_size-1)); #else pbuffer = (char *) (((long)pbuffer + (long)cache_size ) & ~((long)cache_size-1)); #endif } --- NEW FILE: gnu3d.dem --- # # $Id: 3D plot of performance # # Processes files that were created by Generate_Graphs # and displays the results. Also, saves a postscript copy. # # Don Capps set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set parametric set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [2.**5:2.**24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'write/iozone_gen_out.gnuplot' title "Write performance" set terminal postscript color set output "write/write.ps" splot 'write/iozone_gen_out.gnuplot' title "Write performance" pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'rewrite/iozone_gen_out.gnuplot' using 1:2:3 title "ReWrite performance" with lines set terminal postscript color set output "rewrite/rewrite.ps" splot 'rewrite/iozone_gen_out.gnuplot' using 1:2:3 title "ReWrite performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'read/iozone_gen_out.gnuplot' using 1:2:3 title "Read performance" with lines set terminal postscript color set output "read/read.ps" splot 'read/iozone_gen_out.gnuplot' using 1:2:3 title "Read performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'reread/iozone_gen_out.gnuplot' using 1:2:3 title "Reread performance" with lines set terminal postscript color set output "reread/reread.ps" splot 'reread/iozone_gen_out.gnuplot' using 1:2:3 title "Reread performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'randread/iozone_gen_out.gnuplot' using 1:2:3 title "Random read performance" with lines set terminal postscript color set output "randread/randread.ps" splot 'randread/iozone_gen_out.gnuplot' using 1:2:3 title "Random read performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'randwrite/iozone_gen_out.gnuplot' using 1:2:3 title "Random write performance" with lines set terminal postscript color set output "randwrite/randwrite.ps" splot 'randwrite/iozone_gen_out.gnuplot' using 1:2:3 title "Random write performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'bkwdread/iozone_gen_out.gnuplot' using 1:2:3 title "Read Backwards performance" with lines set terminal postscript color set output "bkwdread/bkwdread.ps" splot 'bkwdread/iozone_gen_out.gnuplot' using 1:2:3 title "Read Backwards performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'recrewrite/iozone_gen_out.gnuplot' using 1:2:3 title "Record rewrite performance" with lines set terminal postscript color set output "recrewrite/recrewrite.ps" splot 'recrewrite/iozone_gen_out.gnuplot' using 1:2:3 title "Record rewrite performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'strideread/iozone_gen_out.gnuplot' using 1:2:3 title "Stride read performance" with lines set terminal postscript color set output "strideread/strideread.ps" splot 'strideread/iozone_gen_out.gnuplot' using 1:2:3 title "Stride read performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'fwrite/iozone_gen_out.gnuplot' using 1:2:3 title "Fwrite performance" with lines set terminal postscript color set output "fwrite/fwrite.ps" splot 'fwrite/iozone_gen_out.gnuplot' using 1:2:3 title "Fwrite performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'frewrite/iozone_gen_out.gnuplot' using 1:2:3 title "Frewrite performance" with lines set terminal postscript color set output "frewrite/frewrite.ps" splot 'frewrite/iozone_gen_out.gnuplot' using 1:2:3 title "Frewrite performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'fread/iozone_gen_out.gnuplot' using 1:2:3 title "Fread performance" with lines set terminal postscript color set output "fread/fread.ps" splot 'fread/iozone_gen_out.gnuplot' using 1:2:3 title "Fread performance" with lines pause -1 "Hit return to continue" set terminal x11 set title "Iozone performance" set grid lt 2 lw 1 set surface set xtics set ytics set logscale x 2 set logscale y 2 set autoscale z set xrange [5:24] set xlabel "File size in 2^n KBytes" set ylabel "Record size in 2^n Kbytes" set zlabel "Kbytes/sec" set data style lines set dgrid3d 80,80,3 splot 'freread/iozone_gen_out.gnuplot' using 1:2:3 title "Freread performance" with lines set terminal postscript color set output "freread/freread.ps" splot 'freread/iozone_gen_out.gnuplot' using 1:2:3 title "Freread performance" with lines pause -1 "Hit return to exit" --- NEW FILE: write_telemetry --- # # # The format is: # # All fields are space delimited. # A # symbol in column 1 indicates a comment. # First field: Byte offset within the file. # Second field: Size in bytes of the I/O operation. # Third field: Number of milliseconds to delay before I/O operation. # # This is an example of sequential 64k writer with 2 milliseconds # before each write. # 0 65536 2 65536 65536 2 131072 65536 2 196608 65536 2 262144 65536 2 327680 65536 2 393216 65536 2 458752 65536 2 524288 65536 2 589824 65536 2 655360 65536 2 720896 65536 2 786432 65536 2 851968 65536 2 917504 65536 2 983040 65536 2 --- NEW FILE: gnuplotps.dem --- # # $Id: Plot of latency versus offset in a file # # Requires data file "wol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system write latency " set terminal postscript set output "gnu_wol.ps" set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" plot 'wol.dat' using 1:2 title "Latency Plot" with lines # # $Id: Plot of latency versus offset in a file # # Requires data file "rwol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system re-write latency " set terminal postscript set output "gnu_rwol.ps" set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" plot 'rwol.dat' using 1:2 title "Latency Plot" with lines # # $Id: Plot of latency versus offset in a file # # Requires data file "rol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system read latency " set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" set terminal postscript set output "gnu_rol.ps" plot 'rol.dat' using 1:2 title "Latency Plot" with lines # # $Id: Plot of latency versus offset in a file # # Requires data file "rrol.dat" from this directory, # so change current working directory to this directory before running. # set title "File system re-read latency " set terminal postscript set output "gnu_rrol.ps" set autoscale x set xtics set xlabel "Offset in file (KB)" set ylabel "Latency in Microseconds" plot 'rrol.dat' using 1:2 title "Latency Plot" with lines --- NEW FILE: makefile --- # # Version $Revision: 1.1 $ # # The makefile for building all versions of iozone for all supported # platforms # # Supports: hpux, hpux_no_ansi, hpux-10.1, hpux_no_ansi-10.1, # sppux, sppux-10.1, ghpux, sppux, # convex, FreeBSD, OpenBSD, OSFV3, OSFV4, OSFV5, SCO # SCO_Unixware_gcc,NetBSD,TRU64, Mac OS X CC = cc C89 = c89 GCC = gcc CCS = /usr/ccs/bin/cc NACC = /opt/ansic/bin/cc CFLAGS = all: [...987 lines suppressed...] iozone_SCO_Unixware_gcc.o: iozone.c libbif.c libasync.c @echo "" @echo "Building iozone SCO_Unixware_gcc " @echo "" $(GCC) -c -O -DSCO_Unixware_gcc -Dunix -DHAVE_ANSIC_C \ -DASYNC_IO -D_LARGEFILE64_SOURCE $(CFLAGS) iozone.c \ -DNAME='"SCO_Unixware_gcc"' -o iozone_SCO_Unixware_gcc.o $(GCC) -c -O -DSCO_Unixware_gcc -Dunix -DHAVE_ANSIC_C \ -DASYNC_IO -D_LARGEFILE64_SOURCE $(CFLAGS) libbif.c -o libbif.o $(GCC) -c -O -DSCO_Unixware_gcc -Dunix -DHAVE_ANSIC_C \ -DASYNC_IO -D_LARGEFILE64_SOURCE $(CFLAGS) libasync.c -o libasync.o iozone_netbsd.o: iozone.c libbif.c @echo "" @echo "Building iozone NetBSD " @echo "" $(CC) -c -O -Dunix -Dbsd4_4 -DHAVE_ANSIC_C -DNO_THREADS \ -DNAME='"netbsd"' -DSHARED_MEM $(CFLAGS) iozone.c -o iozone_netbsd.o $(CC) -c -O -Dunix -Dbsd4_4 -DHAVE_ANSIC_C -DNO_THREADS \ -DSHARED_MEM $(CFLAGS) libbif.c -o libbif.o --- NEW FILE: client_list --- # # Lines that start with # in column 0 are comments. # # Format: 3 fields, space delimited. # # client_name working_dir_on_client path_to_iozone_on_client # # Example: With two clients # # client1 /home/user/tmp /home/user/tmp/iozone # client2 /home/user/tmp /home/user/tmp/iozone # # # Example: With two copies of Iozone on each of the two clients # # client1 /home/user/tmp /home/user/tmp/iozone # client1 /home/user/tmp /home/user/tmp/iozone # client2 /home/user/tmp /home/user/tmp/iozone # client2 /home/user/tmp /home/user/tmp/iozone # --- NEW FILE: libbif.c --- /* * Here is a very simple set of routines to write an Excel worksheet * Microsoft BIFF format. The Excel version is set to 2.0 so that it * will work with all versions of Excel. * * Author: Don Capps 1999 (Hewlett Packard) */ /* * Note: rows and colums should not exceed 255 or this code will * act poorly */ #include <sys/types.h> #include <stdio.h> #include <sys/file.h> #ifdef __AIX__ #include <fcntl.h> #else #include <sys/fcntl.h> #endif #if defined(OSV5) || defined(linux) || defined (__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) #include <string.h> #endif #if defined(linux) #include <unistd.h> #include <stdlib.h> #endif #if ((defined(solaris) && defined( __LP64__ )) || defined(__s390x__)) /* If we are building for 64-bit Solaris, all functions that return pointers * must be declared before they are used; otherwise the compiler will assume * that they return ints and the top 32 bits of the pointer will be lost, * causing segmentation faults. The following includes take care of this. * It should be safe to add these for all other OSs too, but we're only * doing it for Solaris now in case another OS turns out to be a special case. */ #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #endif /* Little Endian */ #define ENDIAN_1 1 /* Big Endian */ #define ENDIAN_2 2 /* Middle Endian */ #define ENDIAN_3 3 #ifdef HAVE_ANSIC_C /************************************************************************/ /* Here is the API... Enjoy */ /************************************************************************/ /* Create worksheet */ int create_xls(char *); /* Args: Filename */ /* */ /* Close worksheet */ void close_xls(int); /* Args: file descriptor */ /* */ /* Put a 16 bit integer in worksheet */ void do_int(int,int,int,int); /* Args: file descriptor, */ /* value, */ /* row, */ /* column */ /* Put a double in 8 byte float */ void do_float(int,double,int,int); /* Args: file descriptor, */ /* value, */ /* row, */ /* column */ /* Put a string in worksheet */ void do_label(int,char *,int,int); /* Args: file descriptor, */ /* string, */ /* row, */ /* column */ /************************************************************************/ char libbif_version[] = "Libbif Version $Revision: 1.1 $"; void do_eof(int ); /* Used internally */ void do_header(int ); /* Used internally */ #endif #define BOF 0x9 #define INTEGER 0x2 #define FLOAT 0x3 #define LABEL 0x4 #define EXCEL_VERS 0x2 #define WORKSHEET 0x10 struct bof_record{ /* Beginning of file */ char hi_opcode; char lo_opcode; char hi_length; char lo_length; char hi_version; /* Excel version */ char lo_version; char hi_filetype; char lo_filetype; }; struct int_record { char hi_opcode; /* Type 2 of record */ char lo_opcode; char hi_length; char lo_length; char hi_row; char lo_row; char hi_column; char lo_column; char rgbhi; char rgbmed; char rgblo; char hi_data; char lo_data; }; struct label_record { char hi_opcode; /* Type 4 of record */ char lo_opcode; char hi_length; char lo_length; char hi_row; char lo_row; char hi_column; char lo_column; char rgbhi; char rgbmed; char rgblo; char string_length; char str_array[256]; }; struct float_record { /* Type 3 record */ char hi_opcode; char lo_opcode; char hi_length; char lo_length; char hi_row; char lo_row; char hi_column; char lo_column; char rgbhi; char rgbmed; char rgblo; double data; }; /* * Write the EOF and close the file */ #ifdef HAVE_ANSIC_C void close_xls(int fd) { #else close_xls(fd) int fd; { #endif do_eof(fd); close(fd); } /* * Create xls worksheet. Create file and put the BOF record in it. */ #ifdef HAVE_ANSIC_C int create_xls(char *name) { #else create_xls(name) char *name; { #endif int fd; unlink(name); #ifdef Windows fd=open(name,O_BINARY|O_CREAT|O_RDWR,0666); #else fd=open(name,O_CREAT|O_RDWR,0666); #endif if(fd<0) { printf("Error opening file %s\n",name); exit(-1); } do_header(fd); return(fd); } #ifdef HAVE_ANSIC_C void do_header(int fd) /* Stick the BOF at the beginning of the file */ { #else do_header(fd) int fd; { #endif struct bof_record bof; bof.hi_opcode=BOF; bof.lo_opcode = 0x0; bof.hi_length=0x4; bof.lo_length=0x0; bof.hi_version=EXCEL_VERS; bof.lo_version=0x0; bof.hi_filetype=WORKSHEET; bof.lo_filetype=0x0; write(fd,&bof,sizeof(struct bof_record)); } /* * Put an integer (16 bit) in the worksheet */ #ifdef HAVE_ANSIC_C void do_int(int fd,int val, int row, int column) { #else do_int(fd,val,row,column) int fd,val,row,column; { #endif struct int_record intrec; short s_row,s_column; s_row=(short)row; s_column=(short)column; intrec.hi_opcode=INTEGER; intrec.lo_opcode=0x00; intrec.hi_length=0x09; intrec.lo_length=0x00; intrec.rgbhi=0x0; intrec.rgbmed=0x0; intrec.rgblo=0x0; intrec.hi_row=(char)s_row&0xff; intrec.lo_row=(char)(s_row>>8)&0xff; intrec.hi_column=(char)(s_column&0xff); intrec.lo_column=(char)(s_column>>8)&0xff; intrec.hi_data=(val & 0xff); intrec.lo_data=(val & 0xff00)>>8; write(fd,&intrec,13); } /* Note: This routine converts Big Endian to Little Endian * and writes the record out. */ /* * Put a double in the worksheet as 8 byte float in IEEE format. */ #ifdef HAVE_ANSIC_C void do_float(int fd, double value, int row, int column) { #else do_float(fd, value, row, column) int fd; double value; int row,column; { #endif struct float_record floatrec; short s_row,s_column; unsigned char *sptr,*dptr; s_row=(short)row; s_column=(short)column; floatrec.hi_opcode=FLOAT; floatrec.lo_opcode=0x00; floatrec.hi_length=0xf; floatrec.lo_length=0x00; floatrec.rgbhi=0x0; floatrec.rgbmed=0x0; floatrec.rgblo=0x0; floatrec.hi_row=(char)(s_row&0xff); floatrec.lo_row=(char)((s_row>>8)&0xff); floatrec.hi_column=(char)(s_column&0xff); floatrec.lo_column=(char)((s_column>>8)&0xff); sptr =(unsigned char *) &value; dptr =(unsigned char *) &floatrec.data; if(endian()==ENDIAN_2) /* Big Endian */ { dptr[0]=sptr[7]; /* Convert to Little Endian */ dptr[1]=sptr[6]; dptr[2]=sptr[5]; dptr[3]=sptr[4]; dptr[4]=sptr[3]; dptr[5]=sptr[2]; dptr[6]=sptr[1]; dptr[7]=sptr[0]; } if(endian()==ENDIAN_3) /* Middle Endian */ { dptr[0]=sptr[4]; /* 16 bit swapped ARM */ dptr[1]=sptr[5]; dptr[2]=sptr[6]; dptr[3]=sptr[7]; dptr[4]=sptr[0]; dptr[5]=sptr[1]; dptr[6]=sptr[2]; dptr[7]=sptr[3]; } if(endian()==ENDIAN_1) /* Little Endian */ { dptr[0]=sptr[0]; /* Do not convert to Little Endian */ dptr[1]=sptr[1]; dptr[2]=sptr[2]; dptr[3]=sptr[3]; dptr[4]=sptr[4]; dptr[5]=sptr[5]; dptr[6]=sptr[6]; dptr[7]=sptr[7]; } write(fd,&floatrec,11); /* Don't write floatrec. Padding problems */ write(fd,&floatrec.data,8); /* Write value seperately */ } /* * Put a string as a label in the worksheet. */ #ifdef HAVE_ANSIC_C void do_label(int fd, char *string, int row, int column) { #else do_label(fd, string, row, column) int fd; char *string; int row,column; { #endif struct label_record labelrec; short s_row,s_column; int i; for(i=0;i<255;i++) labelrec.str_array[i]=0; s_row=(short)row; s_column=(short)column; i=strlen(string); labelrec.hi_opcode=LABEL; labelrec.lo_opcode=0x00; labelrec.hi_length=0x08; /* 264 total bytes */ labelrec.lo_length=0x01; labelrec.rgblo=0x0; labelrec.rgbmed=0x0; labelrec.rgbhi=0x0; labelrec.hi_row=(char)(s_row&0xff); labelrec.lo_row=(char)((s_row>>8)&0xff); labelrec.hi_column=(char)(s_column&0xff); labelrec.lo_column=(char)((s_column>>8)&0xff); labelrec.string_length=i; if(i > 255) /* If too long then terminate it early */ string[254]=0; i=strlen(string); strcpy(labelrec.str_array,string); write(fd,&labelrec,sizeof(struct label_record)); } /* * Write the EOF in the file */ #ifdef HAVE_ANSIC_C void do_eof(int fd) { #else do_eof(fd) int fd; { #endif char buf[]={0x0a,0x00,0x00,0x00}; write(fd,buf,4); } /* * Routine to determine the Endian-ness of the system. This * is needed for Iozone to convert doubles (floats) into * Little-endian format. This is needed for Excel to be * able to interpret the file */ int endian(void) { long long foo = 0x0102030405060708LL; unsigned char *c,c1,c2,c3,c4,c5,c6,c7,c8; c=(char *)&foo; c1=*c++; c2=*c++; c3=*c++; c4=*c++; c5=*c++; c6=*c++; c7=*c++; c8=*c; /*--------------------------------------------------------------*/ /* printf("%x %x %x %x %x %x %x %x\n",c1,c2,c3,c4,c5,c6,c7,c8); */ /*--------------------------------------------------------------*/ /* Little Endian format ? ( Intel ) */ if( (c1==0x08) && (c2=0x07) && (c3==0x06) && (c4==0x05) && (c5==0x04) && (c6==0x03) && (c7==0x02) && (c8==0x01) ) return(ENDIAN_1); /* Big Endian format ? ( Sparc, Risc... */ if( (c1==0x01) && (c2=0x02) && (c3==0x03) && (c4==0x04) && (c5==0x05) && (c6==0x06) && (c7==0x07) && (c8==0x08) ) return(ENDIAN_2); /* Middle Endian format ? ( ARM ... ) */ if( (c1==0x04) && (c2=0x03) && (c3==0x02) && (c4==0x01) && (c5==0x08) && (c6==0x07) && (c7==0x06) && (c8==0x05) ) return(ENDIAN_3); } --- NEW FILE: fileop.c --- /* * Maintainer: Don Capps * 5/22/2005 * * A long time ago I ran across this simple benchmark. * It simply tests how fast can a system create and * destroy files. * * Usage: fileop X * * X is a force factor. The total number of files will * be X * X * X ( X ^ 3 ) * The structure of the file tree is: * X number of Level 1 directorys, with X number of * level 2 directories, with X number of files in each * of the level 2 directories. * * Example: fileop 2 * * dir_1 dir_2 * / \ / \ * sdir_1 sdir_2 sdir_1 sdir_2 * / \ / \ / \ / \ * file_1 file_2 file_1 file_2 file_1 file_2 file_1 file_2 * * Each file will be created, and then 1 byte is written to the file. * */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/time.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <unistd.h> #include <dirent.h> #if defined(Windows) #include <Windows.h> #endif int x; #define _STAT_CREATE 0 #define _STAT_WRITE 1 #define _STAT_CLOSE 2 #define _STAT_LINK 3 #define _STAT_UNLINK 4 #define _STAT_DELETE 5 #define _STAT_STAT 6 #define _STAT_ACCESS 7 #define _STAT_CHMOD 8 #define _STAT_READDIR 9 #define _STAT_DIR_CREATE 10 #define _STAT_DIR_DELETE 11 #define _NUM_STATS 13 struct stat_struct { double starttime; double endtime; double speed; double best; double worst; double dummy; double total_time; double dummy1; long long counter; } volatile stats[_NUM_STATS]; static double time_so_far(void); void dir_create(int); void dir_delete(int); void file_create(int); void file_stat(int); void file_access(int); void file_chmod(int); void file_readdir(int); void file_delete(int); void file_link(int); void file_unlink(int); void splash(void); void usage(void); #define THISVERSION " $Revision: 1.1 $" /*#define NULL 0*/ char version[]=THISVERSION; int main(int argc, char **argv) { if(argc == 2) { x=atoi(argv[1]); } else { usage(); exit(1); } splash(); /* * Dir Create test */ dir_create(x); printf("mkdir: Dirs = %9lld ",stats[_STAT_DIR_CREATE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_DIR_CREATE].total_time); printf(" Avg mkdir(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_DIR_CREATE].counter/stats[_STAT_DIR_CREATE].total_time, stats[_STAT_DIR_CREATE].total_time/stats[_STAT_DIR_CREATE].counter); printf(" Best mkdir(s)/sec = %12.2f (%12.9f seconds/op)\n",1/stats[_STAT_DIR_CREATE].best,stats[_STAT_DIR_CREATE].best); printf(" Worst mkdir(s)/sec = %12.2f (%12.9f seconds/op)\n\n",1/stats[_STAT_DIR_CREATE].worst,stats[_STAT_DIR_CREATE].worst); /* * Dir delete test */ dir_delete(x); printf("rmdir: Dirs = %9lld ",stats[_STAT_DIR_DELETE].counter); printf("Total Time = %12.9f seconds\n",stats[_STAT_DIR_DELETE].total_time); printf(" Avg rmdir(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_DIR_DELETE].counter/stats[_STAT_DIR_DELETE].total_time, stats[_STAT_DIR_DELETE].total_time/stats[_STAT_DIR_DELETE].counter); printf(" Best rmdir(s)/sec = %12.2f (%12.9f seconds/op)\n",1/stats[_STAT_DIR_DELETE].best,stats[_STAT_DIR_DELETE].best); printf(" Worst rmdir(s)/sec = %12.2f (%12.9f seconds/op)\n\n",1/stats[_STAT_DIR_DELETE].worst,stats[_STAT_DIR_DELETE].worst); /* * Create test */ file_create(x); printf("create: Files = %9lld ",stats[_STAT_CREATE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_CREATE].total_time); printf(" Avg create(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_CREATE].counter/stats[_STAT_CREATE].total_time, stats[_STAT_CREATE].total_time/stats[_STAT_CREATE].counter); printf(" Best create(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_CREATE].best,stats[_STAT_CREATE].best); printf(" Worst create(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_CREATE].worst,stats[_STAT_CREATE].worst); printf("write: Files = %9lld ",stats[_STAT_WRITE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_WRITE].total_time); printf(" Avg write(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_WRITE].counter/stats[_STAT_WRITE].total_time, stats[_STAT_WRITE].total_time/stats[_STAT_WRITE].counter); printf(" Best write(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_WRITE].best,stats[_STAT_WRITE].best); printf(" Worst write(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_WRITE].worst,stats[_STAT_WRITE].worst); printf("close: Files = %9lld ",stats[_STAT_CLOSE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_CLOSE].total_time); printf(" Avg close(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_CLOSE].counter/stats[_STAT_CLOSE].total_time, stats[_STAT_CLOSE].total_time/stats[_STAT_CLOSE].counter); printf(" Best close(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_CLOSE].best,stats[_STAT_CLOSE].best); printf(" Worst close(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_CLOSE].worst,stats[_STAT_CLOSE].worst); /* * Stat test */ file_stat(x); printf("stat: Files = %9lld ",stats[_STAT_STAT].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_STAT].total_time); printf(" Avg stat(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_STAT].counter/stats[_STAT_STAT].total_time, stats[_STAT_STAT].total_time/stats[_STAT_STAT].counter); printf(" Best stat(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_STAT].best,stats[_STAT_STAT].best); printf(" Worst stat(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_STAT].worst,stats[_STAT_STAT].worst); /* * Access test */ file_access(x); printf("access: Files = %9lld ",stats[_STAT_ACCESS].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_ACCESS].total_time); printf(" Avg access(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_ACCESS].counter/stats[_STAT_ACCESS].total_time, stats[_STAT_ACCESS].total_time/stats[_STAT_ACCESS].counter); printf(" Best access(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_ACCESS].best,stats[_STAT_ACCESS].best); printf(" Worst access(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_ACCESS].worst,stats[_STAT_ACCESS].worst); /* * Chmod test */ file_chmod(x); printf("chmod: Files = %9lld ",stats[_STAT_CHMOD].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_CHMOD].total_time); printf(" Avg chmod(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_CHMOD].counter/stats[_STAT_CHMOD].total_time, stats[_STAT_CHMOD].total_time/stats[_STAT_CHMOD].counter); printf(" Best chmod(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_CHMOD].best,stats[_STAT_CHMOD].best); printf(" Worst chmod(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_CHMOD].worst,stats[_STAT_CHMOD].worst); /* * readdir test */ file_readdir(x); printf("readdir: Files = %9lld ",stats[_STAT_READDIR].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_READDIR].total_time); printf(" Avg readdir(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_READDIR].counter/stats[_STAT_READDIR].total_time, stats[_STAT_READDIR].total_time/stats[_STAT_READDIR].counter); printf(" Best readdir(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_READDIR].best,stats[_STAT_READDIR].best); printf(" Worst readdir(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_READDIR].worst,stats[_STAT_READDIR].worst); #if !defined(Windows) /* * link test */ file_link(x); printf("link: Files = %9lld ",stats[_STAT_LINK].counter); printf("Total Time = %12.9f seconds\n",stats[_STAT_LINK].total_time); printf(" Avg link(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_LINK].counter/stats[_STAT_LINK].total_time, stats[_STAT_LINK].total_time/stats[_STAT_LINK].counter); printf(" Best link(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_LINK].best,stats[_STAT_LINK].best); printf(" Worst link(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_LINK].worst,stats[_STAT_LINK].worst); /* * unlink test */ file_unlink(x); printf("unlink: Files = %9lld ",stats[_STAT_UNLINK].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_UNLINK].total_time); printf(" Avg unlink(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_UNLINK].counter/stats[_STAT_UNLINK].total_time, stats[_STAT_UNLINK].total_time/stats[_STAT_UNLINK].counter); printf(" Best unlink(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_UNLINK].best,stats[_STAT_UNLINK].best); printf(" Worst unlink(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_UNLINK].worst,stats[_STAT_UNLINK].worst); #endif /* * Delete test */ file_delete(x); printf("delete: Files = %9lld ",stats[_STAT_DELETE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_DELETE].total_time); printf(" Avg delete(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_DELETE].counter/stats[_STAT_DELETE].total_time, stats[_STAT_DELETE].total_time/stats[_STAT_DELETE].counter); printf(" Best delete(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_DELETE].best,stats[_STAT_DELETE].best); printf(" Worst delete(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_DELETE].worst,stats[_STAT_DELETE].worst); return(0); } void dir_create(int x) { int i,j; int ret; char buf[100]; stats[_STAT_DIR_CREATE].best=(double)99999.9; stats[_STAT_DIR_CREATE].worst=(double)0.00000000; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); stats[_STAT_DIR_CREATE].starttime=time_so_far(); ret=mkdir(buf,0777); if(ret < 0) { printf("Mkdir failed\n"); exit(1); } stats[_STAT_DIR_CREATE].endtime=time_so_far(); stats[_STAT_DIR_CREATE].speed=stats[_STAT_DIR_CREATE].endtime-stats[_STAT_DIR_CREATE].starttime; if(stats[_STAT_DIR_CREATE].speed < (double)0.0) stats[_STAT_DIR_CREATE].speed=(double)0.0; stats[_STAT_DIR_CREATE].total_time+=stats[_STAT_DIR_CREATE].speed; stats[_STAT_DIR_CREATE].counter++; if(stats[_STAT_DIR_CREATE].speed < stats[_STAT_DIR_CREATE].best) stats[_STAT_DIR_CREATE].best=stats[_STAT_DIR_CREATE].speed; if(stats[_STAT_DIR_CREATE].speed > stats[_STAT_DIR_CREATE].worst) stats[_STAT_DIR_CREATE].worst=stats[_STAT_DIR_CREATE].speed; chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); stats[_STAT_DIR_CREATE].starttime=time_so_far(); ret=mkdir(buf,0777); if(ret < 0) { printf("Mkdir failed\n"); exit(1); } stats[_STAT_DIR_CREATE].endtime=time_so_far(); stats[_STAT_DIR_CREATE].speed=stats[_STAT_DIR_CREATE].endtime-stats[_STAT_DIR_CREATE].starttime; if(stats[_STAT_DIR_CREATE].speed < (double)0.0) stats[_STAT_DIR_CREATE].speed=(double) 0.0; stats[_STAT_DIR_CREATE].total_time+=stats[_STAT_DIR_CREATE].speed; stats[_STAT_DIR_CREATE].counter++; if(stats[_STAT_DIR_CREATE].speed < stats[_STAT_DIR_CREATE].best) stats[_STAT_DIR_CREATE].best=stats[_STAT_DIR_CREATE].speed; if(stats[_STAT_DIR_CREATE].speed > stats[_STAT_DIR_CREATE].worst) stats[_STAT_DIR_CREATE].worst=stats[_STAT_DIR_CREATE].speed; chdir(buf); chdir(".."); } chdir(".."); } } void file_create(int x) { int i,j,k; int fd; int ret; char buf[100]; stats[_STAT_CREATE].best=(double)999999.9; stats[_STAT_CREATE].worst=(double)0.0; stats[_STAT_WRITE].best=(double)999999.9; stats[_STAT_WRITE].worst=(double)0.0; stats[_STAT_CLOSE].best=(double)999999.9; stats[_STAT_CLOSE].worst=(double)0.0; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); ret=mkdir(buf,0777); if(ret < 0) { printf("Mkdir failed\n"); exit(1); } chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); ret=mkdir(buf,0777); if(ret < 0) { printf("Mkdir failed\n"); exit(1); } chdir(buf); for(k=0;k<x;k++) { sprintf(buf,"iozone_file_%d_%d_%d",i,j,k); stats[_STAT_CREATE].starttime=time_so_far(); fd=creat(buf,O_RDWR|0600); if(fd < 0) { printf("Create failed\n"); exit(1); } stats[_STAT_CREATE].endtime=time_so_far(); stats[_STAT_CREATE].speed=stats[_STAT_CREATE].endtime-stats[_STAT_CREATE].starttime; if(stats[_STAT_CREATE].speed < (double)0.0) stats[_STAT_CREATE].speed=(double)0.0; stats[_STAT_CREATE].total_time+=stats[_STAT_CREATE].speed; stats[_STAT_CREATE].counter++; if(stats[_STAT_CREATE].speed < stats[_STAT_CREATE].best) stats[_STAT_CREATE].best=stats[_STAT_CREATE].speed; if(stats[_STAT_CREATE].speed > stats[_STAT_CREATE].worst) stats[_STAT_CREATE].worst=stats[_STAT_CREATE].speed; stats[_STAT_WRITE].starttime=time_so_far(); write(fd,"a",1); stats[_STAT_WRITE].endtime=time_so_far(); stats[_STAT_WRITE].counter++; stats[_STAT_WRITE].speed=stats[_STAT_WRITE].endtime-stats[_STAT_WRITE].starttime; if(stats[_STAT_WRITE].speed < (double)0.0) stats[_STAT_WRITE].speed=(double)0.0; stats[_STAT_WRITE].total_time+=stats[_STAT_WRITE].speed; if(stats[_STAT_WRITE].speed < stats[_STAT_WRITE].best) stats[_STAT_WRITE].best=stats[_STAT_WRITE].speed; if(stats[_STAT_WRITE].speed > stats[_STAT_WRITE].worst) stats[_STAT_WRITE].worst=stats[_STAT_WRITE].speed; stats[_STAT_CLOSE].starttime=time_so_far(); close(fd); stats[_STAT_CLOSE].endtime=time_so_far(); stats[_STAT_CLOSE].speed=stats[_STAT_CLOSE].endtime-stats[_STAT_CLOSE].starttime; if(stats[_STAT_CLOSE].speed < (double)0.0) stats[_STAT_CLOSE].speed=(double)0.0; stats[_STAT_CLOSE].total_time+=stats[_STAT_CLOSE].speed; stats[_STAT_CLOSE].counter++; if(stats[_STAT_CLOSE].speed < stats[_STAT_CLOSE].best) stats[_STAT_CLOSE].best=stats[_STAT_CLOSE].speed; if(stats[_STAT_CLOSE].speed > stats[_STAT_CLOSE].worst) stats[_STAT_CLOSE].worst=stats[_STAT_CLOSE].speed; } chdir(".."); } chdir(".."); } } void file_stat(int x) { int i,j,k,y; char buf[100]; struct stat mystat; stats[_STAT_STAT].best=(double)99999.9; stats[_STAT_STAT].worst=(double)0.00000000; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); for(k=0;k<x;k++) { sprintf(buf,"iozone_file_%d_%d_%d",i,j,k); stats[_STAT_STAT].starttime=time_so_far(); y=stat(buf,&mystat); if(y < 0) { printf("Stat failed\n"); exit(1); } stats[_STAT_STAT].endtime=time_so_far(); stats[_STAT_STAT].speed=stats[_STAT_STAT].endtime-stats[_STAT_STAT].starttime; if(stats[_STAT_STAT].speed < (double)0.0) stats[_STAT_STAT].speed=(double)0.0; stats[_STAT_STAT].total_time+=stats[_STAT_STAT].speed; stats[_STAT_STAT].counter++; if(stats[_STAT_STAT].speed < stats[_STAT_STAT].best) stats[_STAT_STAT].best=stats[_STAT_STAT].speed; if(stats[_STAT_STAT].speed > stats[_STAT_STAT].worst) stats[_STAT_STAT].worst=stats[_STAT_STAT].speed; } chdir(".."); } chdir(".."); } } void file_access(int x) { int i,j,k,y; char buf[100]; stats[_STAT_ACCESS].best=(double)999999.9; stats[_STAT_ACCESS].worst=(double)0.0; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); for(k=0;k<x;k++) { sprintf(buf,"iozone_file_%d_%d_%d",i,j,k); stats[_STAT_ACCESS].starttime=time_so_far(); y=access(buf,W_OK|F_OK); if(y < 0) { printf("access failed\n"); perror("what"); exit(1); } stats[_STAT_ACCESS].endtime=time_so_far(); stats[_STAT_ACCESS].speed=stats[_STAT_ACCESS].endtime-stats[_STAT_ACCESS].starttime; if(stats[_STAT_ACCESS].speed < (double)0.0) stats[_STAT_ACCESS].speed=(double)0.0; stats[_STAT_ACCESS].total_time+=stats[_STAT_ACCESS].speed; stats[_STAT_ACCESS].counter++; if(stats[_STAT_ACCESS].speed < stats[_STAT_ACCESS].best) stats[_STAT_ACCESS].best=stats[_STAT_ACCESS].speed; if(stats[_STAT_ACCESS].speed > stats[_STAT_ACCESS].worst) stats[_STAT_ACCESS].worst=stats[_STAT_ACCESS].speed; } chdir(".."); } chdir(".."); } } void file_chmod(int x) { int i,j,k,y; char buf[100]; stats[_STAT_CHMOD].best=(double)999999.9; stats[_STAT_CHMOD].worst=(double)0.0; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); for(k=0;k<x;k++) { sprintf(buf,"iozone_file_%d_%d_%d",i,j,k); stats[_STAT_CHMOD].starttime=time_so_far(); y=chmod(buf,0666); if(y < 0) { printf("chmod failed\n"); perror("what"); exit(1); } stats[_STAT_CHMOD].endtime=time_so_far(); stats[_STAT_CHMOD].speed=stats[_STAT_CHMOD].endtime-stats[_STAT_CHMOD].starttime; if(stats[_STAT_CHMOD].speed < (double)0.0) stats[_STAT_CHMOD].speed=(double)0.0; stats[_STAT_CHMOD].total_time+=stats[_STAT_CHMOD].speed; stats[_STAT_CHMOD].counter++; if(stats[_STAT_CHMOD].speed < stats[_STAT_CHMOD].best) stats[_STAT_CHMOD].best=stats[_STAT_CHMOD].speed; if(stats[_STAT_CHMOD].speed > stats[_STAT_CHMOD].worst) stats[_STAT_CHMOD].worst=stats[_STAT_CHMOD].speed; } chdir(".."); } chdir(".."); } } void file_readdir(int x) { int i,j,ret1; char buf[100]; DIR *dirbuf; struct dirent *y; stats[_STAT_READDIR].best=(double)999999.9; stats[_STAT_READDIR].worst=(double)0.0; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); dirbuf=opendir("."); if(dirbuf==0) { printf("opendir failed\n"); exit(1); } stats[_STAT_READDIR].starttime=time_so_far(); y=readdir(dirbuf); if(y == 0) { printf("readdir failed\n"); exit(1); } stats[_STAT_READDIR].endtime=time_so_far(); stats[_STAT_READDIR].speed=stats[_STAT_READDIR].endtime-stats[_STAT_READDIR].starttime; if(stats[_STAT_READDIR].speed < (double)0.0) stats[_STAT_READDIR].speed=(double)0.0; stats[_STAT_READDIR].total_time+=stats[_STAT_READDIR].speed; stats[_STAT_READDIR].counter++; if(stats[_STAT_READDIR].speed < stats[_STAT_READDIR].best) stats[_STAT_READDIR].best=stats[_STAT_READDIR].speed; if(stats[_STAT_READDIR].speed > stats[_STAT_READDIR].worst) stats[_STAT_READDIR].worst=stats[_STAT_READDIR].speed; ret1=closedir(dirbuf); if(ret1 < 0) { printf("closedir failed\n"); exit(1); } chdir(".."); } chdir(".."); } } void file_link(int x) { int i,j,k,y; char buf[100]; char bufn[100]; stats[_STAT_LINK].best=(double)999999.9; stats[_STAT_LINK].worst=(double)0.0; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); for(k=0;k<x;k++) { sprintf(buf,"iozone_file_%d_%d_%d",i,j,k); sprintf(bufn,"iozone_file_%d_%d_%dL",i,j,k); stats[_STAT_LINK].starttime=time_so_far(); y=link(buf,bufn); if(y < 0) { printf("Link failed\n"); exit(1); } stats[_STAT_LINK].endtime=time_so_far(); stats[_STAT_LINK].speed=stats[_STAT_LINK].endtime-stats[_STAT_LINK].starttime; if(stats[_STAT_LINK].speed < (double)0.0) stats[_STAT_LINK].speed=(double)0.0; stats[_STAT_LINK].total_time+=stats[_STAT_LINK].speed; stats[_STAT_LINK].counter++; if(stats[_STAT_LINK].speed < stats[_STAT_LINK].best) stats[_STAT_LINK].best=stats[_STAT_LINK].speed; if(stats[_STAT_LINK].speed > stats[_STAT_LINK].worst) stats[_STAT_LINK].worst=stats[_STAT_LINK].speed; } chdir(".."); } chdir(".."); } } void file_unlink(int x) { int i,j,k,y; char buf[100]; char bufn[100]; stats[_STAT_UNLINK].best=(double)999999.9; stats[_STAT_UNLINK].worst=(double)0.0; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); for(k=0;k<x;k++) { sprintf(buf,"iozone_file_%d_%d_%d",i,j,k); sprintf(bufn,"iozone_file_%d_%d_%dL",i,j,k); stats[_STAT_UNLINK].starttime=time_so_far(); y=unlink(bufn); if(y < 0) { printf("Unlink failed\n"); exit(1); } stats[_STAT_UNLINK].endtime=time_so_far(); stats[_STAT_UNLINK].speed=stats[_STAT_UNLINK].endtime-stats[_STAT_UNLINK].starttime; if(stats[_STAT_UNLINK].speed < (double)0.0) stats[_STAT_UNLINK].speed=(double)0.0; stats[_STAT_UNLINK].total_time+=stats[_STAT_UNLINK].speed; stats[_STAT_UNLINK].counter++; if(stats[_STAT_UNLINK].speed < stats[_STAT_UNLINK].best) stats[_STAT_UNLINK].best=stats[_STAT_UNLINK].speed; if(stats[_STAT_UNLINK].speed > stats[_STAT_UNLINK].worst) stats[_STAT_UNLINK].worst=stats[_STAT_UNLINK].speed; } chdir(".."); } chdir(".."); } } void dir_delete(int x) { int i,j; char buf[100]; stats[_STAT_DIR_DELETE].best=(double)99999.9; stats[_STAT_DIR_DELETE].worst=(double)0.00000000; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); chdir(".."); sprintf(buf,"iozone_L1_%d_L2_%d",i,j); stats[_STAT_DIR_DELETE].starttime=time_so_far(); rmdir(buf); stats[_STAT_DIR_DELETE].endtime=time_so_far(); stats[_STAT_DIR_DELETE].speed=stats[_STAT_DIR_DELETE].endtime-stats[_STAT_DIR_DELETE].starttime; if(stats[_STAT_DIR_DELETE].speed < (double)0.0) stats[_STAT_DIR_DELETE].speed=(double)0.0; stats[_STAT_DIR_DELETE].total_time+=stats[_STAT_DIR_DELETE].speed; stats[_STAT_DIR_DELETE].counter++; if(stats[_STAT_DIR_DELETE].speed < stats[_STAT_DIR_DELETE].best) stats[_STAT_DIR_DELETE].best=stats[_STAT_DIR_DELETE].speed; if(stats[_STAT_DIR_DELETE].speed > stats[_STAT_DIR_DELETE].worst) stats[_STAT_DIR_DELETE].worst=stats[_STAT_DIR_DELETE].speed; } chdir(".."); sprintf(buf,"iozone_L1_%d",i); stats[_STAT_DIR_DELETE].starttime=time_so_far(); rmdir(buf); stats[_STAT_DIR_DELETE].endtime=time_so_far(); stats[_STAT_DIR_DELETE].speed=stats[_STAT_DIR_DELETE].endtime-stats[_STAT_DIR_DELETE].starttime; if(stats[_STAT_DIR_DELETE].speed < (double)0.0) stats[_STAT_DIR_DELETE].speed=(double)0.0; stats[_STAT_DIR_DELETE].total_time+=stats[_STAT_DIR_DELETE].speed; stats[_STAT_DIR_DELETE].counter++; if(stats[_STAT_DIR_DELETE].speed < stats[_STAT_DIR_DELETE].best) stats[_STAT_DIR_DELETE].best=stats[_STAT_DIR_DELETE].speed; if(stats[_STAT_DIR_DELETE].speed > stats[_STAT_DIR_DELETE].worst) stats[_STAT_DIR_DELETE].worst=stats[_STAT_DIR_DELETE].speed; } } void file_delete(int x) { int i,j,k; char buf[100]; stats[_STAT_DELETE].best=(double)999999.9; stats[_STAT_DELETE].worst=(double)0.0; for(i=0;i<x;i++) { sprintf(buf,"iozone_L1_%d",i); chdir(buf); for(j=0;j<x;j++) { sprintf(buf,"iozone_L1_%d_L2_%d",i,j); chdir(buf); for(k=0;k<x;k++) { sprintf(buf,"iozone_file_%d_%d_%d",i,j,k); stats[_STAT_DELETE].starttime=time_so_far(); unlink(buf); stats[_STAT_DELETE].endtime=time_so_far(); stats[_STAT_DELETE].speed=stats[_STAT_DELETE].endtime-stats[_STAT_DELETE].starttime; if(stats[_STAT_DELETE].speed < (double)0.0) stats[_STAT_DELETE].speed=(double)0.0; stats[_STAT_DELETE].total_time+=stats[_STAT_DELETE].speed; stats[_STAT_DELETE].counter++; if(stats[_STAT_DELETE].speed < stats[_STAT_DELETE].best) stats[_STAT_DELETE].best=stats[_STAT_DELETE].speed; if(stats[_STAT_DELETE].speed > stats[_STAT_DELETE].worst) stats[_STAT_DELETE].worst=stats[_STAT_DELETE].speed; } chdir(".."); sprintf(buf,"iozone_L1_%d_L2_%d",i,j); rmdir(buf); } chdir(".."); sprintf(buf,"iozone_L1_%d",i); rmdir(buf); } } /************************************************************************/ /* Time measurement routines. Thanks to Iozone :-) */ /************************************************************************/ #ifdef HAVE_ANSIC_C static double time_so_far(void) #else static double time_so_far() #endif { #ifdef Windows LARGE_INTEGER freq,counter; double wintime,bigcounter; /* For Windows the time_of_day() is useless. It increments in 55 milli second */ /* increments. By using the Win32api one can get access to the high performance */ /* measurement interfaces. With this one can get back into the 8 to 9 */ /* microsecond resolution. */ QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&counter); bigcounter=(double)counter.HighPart *(double)0xffffffff + (double)counter.LowPart; wintime = (double)(bigcounter/(double)freq.LowPart); return((double)wintime); #else #if defined (OSFV4) || defined(OSFV3) || defined(OSFV5) struct timespec gp; if (getclock(TIMEOFDAY, (struct timespec *) &gp) == -1) perror("getclock"); return (( (double) (gp.tv_sec)) + ( ((float)(gp.tv_nsec)) * 0.000000001 )); #else struct timeval tp; if (gettimeofday(&tp, (struct timezone *) NULL) == -1) perror("gettimeofday"); return ((double) (tp.tv_sec)) + (((double) tp.tv_usec) * 0.000001 ); #endif #endif } void splash(void) { printf("\n"); printf(" ... [truncated message content] |
From: Eric V. H. <er...@us...> - 2006-02-19 20:53:10
|
Update of /cvsroot/v9fs/tests/iozone/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5556/iozone/docs Added Files: IOzone_msword_98.doc IOzone_msword_98.pdf Iozone_ps.gz Run_rules.doc iozone.1 Log Message: Add iozone to tests --- NEW FILE: IOzone_msword_98.doc --- (This appears to be a binary file; contents omitted.) --- NEW FILE: Run_rules.doc --- (This appears to be a binary file; contents omitted.) --- NEW FILE: IOzone_msword_98.pdf --- (This appears to be a binary file; contents omitted.) --- NEW FILE: iozone.1 --- .TH IOZONE 1 .SH NAME Iozone \- Filesystem Benchmark .SH SYNOPSIS .B Iozone .nh {\fB\-a | -A\fP} [\fB\-s\fP \fIfilesize_Kb\fP] [\fB\-r\fP \fIrecord_size_Kb\fP] [\fB\-f\fP \fI[path]filename\fP] [\fB\-i\fP \fItest\fP] [\fB\-E\fP] [\fB\-p\fP] [\fB\-m\fP] [\fB\-M\fP] [\fB\-t\fP \fIchildren\fP] [\fB\-h\fP] [\fB\-o\fP] [\fB\-l\fP \fImin_number_procs\fP] [\fB\-u\fP \fImax_number_procs\fP] [\fB\-v\fP] [\fB\-R\fP] [\fB\-x\fP] [\fB\-d\fP \fImicroseconds\fP] [\fB\-F\fP \fIpath1 path2...\fP] [\fB\-V\fP \fIpattern \fP] [\fB\-j\fP \fIstride\fP] [\fB\-T\fP] [\fB\-C\fP] [\fB\-B\fP] [\fB\-D\fP] [\fB\-G\fP] [\fB\-I\fP] [\fB\-H\fP \fIdepth\fP] [\fB\-k\fP \fIdepth\fP] [\fB\-U\fP \fImount_point\fP] [\fB\-S\fP \fIcache_size\fP] [\fB\-O\fP] [\fB\-L\fP \fIline_size\fP] [\fB\-K\fP] [\fB\-N\fP] [\fB\-Q\fP] [\fB\-P\fP \fIstart_cpu\fP] [\fB\-c\fP] [\fB\-e\fP] [\fB\-b\fP \fIExcel.xls\fP] [\fB\-J\fP \fImilliseconds\fP] [\fB\-X\fP \fI[path]filename\fP] [\fB\-Y\fP \fI[path]filename\fP] [\fB\-w\fP] [\fB\-W\fP] [\fB\-z\fP] [\fB\-Z\fP] [\fB\-n\fP \fImin_filesize_Kb\fP] [\fB\-g\fP \fImax_filesize_Kb\fP] [\fB\-y\fP \fImin_recordsize_Kb\fP] [\fB\-q\fP \fImax_recordsize_Kb\fP] [\fB\-+d\fP] [\fB\-+u\fP] [\fB\-+m\fP \fIclient_filename\fP] [\fB\-+p\fP \fIpercent_read\fP] [\fB\-+r\fP] [\fB\-+t\fP] [\fB\-+l\fP] [\fB\-+L\fP] [\fB\-+D\fP] [\fB\-+A\fP \fImadvise_selector\fP] [\fB\-+h\fP \fIhostname\fP] [\fB\-+T\fP] .hy .SH DESCRIPTION .B Iozone is a filesystem benchmark tool. The benchmark generates and measures a variety of file operations. .B Iozone has been ported to many machines and runs under many operating systems. This document will cover the many different types of operations that are tested as well as coverage of all of the command line options. .PP .B Iozone is useful for determining a broad filesystem analysis of a vendor's computer platform. The benchmark tests file I/O performance for the following operations. .PP Read, write, re-read, re-write, read backwards, read strided, fread, fwrite, random read/write, pread/pwrite variants .PP While computers are typically purchased with an application in mind it is also likely that over time the application mix will change. Many vendors have enhanced their operating systems to perform well for some frequently used applications. Although this accelerates the I/O for those few applications it is also likely that the system may not perform well for other applications that were not targeted by the operating system. An example of this type of enhancement is: Database. Many operating systems have tested and tuned the filesystem so it works well with databases. While the database users are happy, the other users may not be so happy as the entire system may be giving all of the system resources to the database users at the expense of all other users. As time rolls on the system administrator may decide that a few more office automation tasks could be shifted to this machine. The load may now shift from a random reader application (database) to a sequential reader. The users may discover that the machine is very slow when running this new application and become dissatisfied with the decision to purchase this platform. By using .B Iozone to get a broad filesystem performance coverage the buyer is much more likely to see any hot or cold spots and pick a platform and operating system that is more well balanced. .SH OPTIONS .TP .BI \-a Used to select full automatic mode. Produces output that covers all tested file operations for record sizes of 4k to 16M for file sizes of 64k to 512M. .TP .BI \-A This version of automatic mode provides more coverage but consumes a bunch of time. The .BI \-a option will automatically stop using transfer sizes less than 64k once the file size is 32M or larger. This saves time. The .BI \-A option tells .B Iozone that you are willing to wait and want dense coverage for small transfers even when the file size is very large. .BI NOTE: This option is deprecated in .BI Iozone version 3.61. Use .BI \-az\ \-i\ 0\ \-i\ 1 instead. .TP .BI \-b\ filename Used to specify a filename that will be used for output of an Excel compatible file that contains the results. .TP .BI \-B Use mmap() files. This causes all of the temporary files being measured to be created and accessed with the mmap() interface. Some applications prefer to treat files as arrays of memory. These applications mmap() the file and then just access the array with loads and stores to perform file I/O. .TP .BI \-c Include close() in the timing calculations. This is useful only if you suspect that close() is broken in the operating system currently under test. It can be useful for NFS Version 3 testing as well to help identify if the nfs3_commit is working well. .TP .BI \-C Show bytes transferred by each child in throughput testing. Useful if your operating system has any starvation problems in file I/O or in process management. .TP .BI \-d\ # Microsecond delay out of barrier. During the throughput tests all threads or processes are forced to a barrier before beginning the test. Normally, all of the threads or processes are released at the same moment. This option allows one to delay a specified time in microseconds between releasing each of the processes or threads. .TP .BI \-D Use msync(MS_ASYNC) on mmap files. This tells the operating system that all the data in the mmap space needs to be written to disk asynchronously. .TP .BI \-e Include flush (fsync,fflush) in the timing calculations .TP .BI \-E Used to select the extension tests. Only available on some platforms. Uses pread interfaces. .TP .BI \-f\ filename Used to specify the filename for the temporary file under test. This is useful when the unmount option is used. When testing with unmount between tests it is necessary for the temporary file under test to be in a directory that can be unmounted. It is not possible to unmount the current working directory as the process .B Iozone is running in this directory. .TP .BI \-F\ filename\ filename\ filename\ ? Specify each of the temporary file names to be used in the throughput testing. The number of names should be equal to the number of processes or threads that are specified. .TP .BI \-g\ # Set maximum file size (in Kbytes) for auto mode. One may also specify .BI \-g\ #k (size in Kbytes) or .BI \-g\ #m (size in Mbytes) or .BI \-g\ #g (size in Gbytes). See .BI \-n for minimum file size. .TP .BI \-G Use msync(MS_SYNC) on mmap files. This tells the operating system that all the data in the mmap space needs to be written to disk synchronously. .TP .BI \-h Displays help screen. .TP .BI \-H\ # Use POSIX async I/O with\ # async operations. .B Iozone will use POSIX async I/O with a bcopy from the async buffers back into the applications buffer. Some versions of MSC NASTRAN perform I/O this way. This technique is used by applications so that the async I/O may be performed in a library and requires no changes to the applications internal model. .TP .BI \-i\ # Used to specify which tests to run. (0=write/rewrite, 1=read/re-read, 2=random-read/write, 3=Read-backwards, 4=Re-write-record, 5=stride-read, 6=fwrite/re-fwrite, 7=fread/Re-fread, 8=mixed workload, 9=pwrite/Re-pwrite, 10=pread/Re-pread, 11=pwritev/Re-pwritev, 12=preadv/Re-preadv). One will always need to specify 0 so that any of the following tests will have a file to measure. .BI -i\ #\ -i\ #\ -i\ # is also supported so that one may select more than one test. .TP .BI \-I Use VxFS VX_DIRECT for all file operations. Tells the VXFS filesystem that all operations to the file are to bypass the buffer cache and go directly to disk. .TP .BI \-j\ # Set stride of file accesses to (# * record size). The stride read test will read records at this stride. .TP .BI \-J\ # Millisecond delay before each I/O operation. This simulates the cpu compute cycle of an application that precedes an I/O operation. One may also use .BI \-X or .BI \-Y to control the compute cycle on a per I/O operation basis. .TP .BI \-k\ # Use POSIX async I/O (no bcopy) with\ # async operations. .B Iozone will use POSIX async I/O and will not perform any extra bcopys. The buffers used by .B Iozone will be handed to the async I/O system call directly. .TP .BI \-K Inject some random accesses in the testing. .TP .BI \-l\ # Set the lower limit on number of processes to run. When running throughput tests this option allows the user to specify the least number of processes or threads to start. This option should be used in conjunction with the .BI \-u option. .TP .BI \-L\ # Set processor cache line size to value (in bytes). Tells .B Iozone the processor cache line size. This is used internally to help speed up the test. .TP .BI \-m Tells .B Iozone to use multiple buffers internally. Some applications read into a single buffer over and over. Others have an array of buffers. This option allows both types of applications to be simulated. .B Iozone\'s default behavior is to re-use internal buffers. This option allows one to override the default and to use multiple internal buffers. .TP .BI \-M \.B Iozone will call uname() and will put the string in the output file. .TP .BI \-n\ # Set minimum file size (in Kbytes) for auto mode. One may also specify .BI \-n\ #k (size in Kbytes) or .BI \-n\ #m (size in Mbytes) or .BI \-n\ #g (size in Gbytes). See .BI \-g for maximum file size. .TP .BI \-N Report results in microseconds per operation. .TP .BI \-o Writes are synchronously written to disk. (O_SYNC). .B Iozone will open the files with the O_SYNC flag. This forces all writes to the file to go completely to disk before returning to the benchmark. .TP .BI \-O Give results in operations per second. .TP .BI \-p This purges the processor cache before each file operation. .B Iozone will allocate another internal buffer that is aligned to the same processor cache boundary and is of a size that matches the processor cache. It will zero fill this alternate buffer before beginning each test. This will purge the processor cache and allow one to see the memory subsystem without the acceleration due to the processor cache. .TP .BI \-P\ # Bind processes/threads to processors, starting with this cpu\ #. Only available on some platforms. The first sub process or thread will begin on the specified processor. Future processes or threads will be placed on the next processor. Once the total number of cpus is exceeded then future processes or threads will be placed in a round robin fashion. .TP .BI \-q\ # Set maximum record size (in Kbytes) for auto mode. One may also specify .BI \-q\ #k (size in Kbytes) or .BI \-q\ #m (size in Mbytes) or .BI \-q\ #g (size in Gbytes). See .BI \-y for minimum record size. .TP .BI \-Q Create offset/latency files. .B Iozone will create latency versus offset data files that can be imported with a graphics package and plotted. This is useful for finding if certain offsets have very high latencies. Such as the point where UFS will allocate its first indirect block. One can see from the data the impacts of the extent allocations for extent based filesystems with this option. .TP .BI \-r\ # Used to specify the record size, in Kbytes, to test. One may also specify .BI \-r\ #k (size in Kbytes) or .BI \-r\ #m (size in Mbytes) or .BI \-r\ #g (size in Gbytes). .TP .BI \-R Generate Excel report. .B Iozone will generate an Excel compatible report to standard out. This file may be imported with Microsoft Excel (space delimited) and used to create a graph of the filesystem performance. Note: The 3D graphs are column oriented. You will need to select this when graphing as the default in Excel is row oriented data. .TP .BI \-s\ # Used to specify the size, in Kbytes, of the file to test. One may also specify .BI \-s\ #k (size in Kbytes) or .BI \-s\ #m (size in Mbytes) or .BI \-s\ #g (size in Gbytes). .TP .BI \-S\ # Set processor cache size to value (in Kbytes). This tells .B Iozone the size of the processor cache. It is used internally for buffer alignment and for the purge functionality. .TP .BI \-t\ # Run .B Iozone in a throughput mode. This option allows the user to specify how many threads or processes to have active during the measurement. .TP .BI \-T Use POSIX pthreads for throughput tests. Available on platforms that have POSIX threads. .TP .BI \-u\ # Set the upper limit on number of processes to run. When running throughput tests this option allows the user to specify the greatest number of processes or threads to start. This option should be used in conjunction with the .BI \-l option. .TP .BI \-U\ mountpoint Mount point to unmount and remount between tests. .B Iozone will unmount and remount this mount point before beginning each test. This guarantees that the buffer cache does not contain any of the file under test. .TP .BI \-v Display the version of .B Iozone. .TP .BI \-V\ # Specify a pattern that is to be written to the temporary file and validated for accuracy in each of the read tests. .TP .BI \-w Do not unlink temporary files when finished using them. .TP .BI \-W Lock file when reading or writing. .TP .BI \-x Turn off stone-walling. Stonewalling is a technique used internally to .B Iozone. It is used during the throughput tests. The code starts all threads or processes and then stops them on a barrier. Once they are all ready to start then they are all released at the same time. The moment that any of the threads or processes finish their work then the entire test is terminated and throughput is calculated on the total I/O that was completed up to this point. This ensures that the entire measurement was taken while all of the processes or threads were running in parallel. This flag allows one to turn off the stonewalling and see what happens. .TP .BI \-X\ filename Used to specify a filename that will be used for the write telemetry information. The file contains lines with offset, size, delay_in_milliseconds. Each of these lines are used to perform an I/O operation. This is used when an application'ss specific I/O operations are known, and one wishes to benchmark the system with this specific application file behavior. .TP .BI \-y\ # Set minimum record size (in Kbytes) for auto mode. One may also specify .BI \-y\ #k (size in Kbytes) or .BI \-y\ #m (size in Mbytes) or .BI \-y\ #g (size in Gbytes). See .BI \-q for maximum record size. .TP .BI \-Y\ filename Used to specify a filename that will be used for the read telemetry information. The file contains lines with offset, size, delay_in_milliseconds. Each of these lines are used to perform an I/O operation. This is used when an application'ss specific I/O operations are known, and one wishes to benchmark the system with this specific application file behavior. .TP .BI \-z Used in conjunction with .BI \-a to test all possible record sizes. Normally .BI Iozone omits testing of small record sizes for very large files when used in full automatic mode. This option forces .BI Iozone to include the small record sizes in the automatic tests also. .TP .BI \-Z Enable mixing of mmap I/O and file I/O. .TP .BI \-+m\ filename Used to specify a filename that will be used to specify the clients in a distributed measurement. The file contains one line for each client. The fields are space delimited. Field 1 is the client name. Field 2 is the working directory, on the client, where Iozone will run. Field 3 is the path to the executable Iozone on the client. .TP .BI \-+u Used to enable CPU statistics collection. .TP .BI \-+d Diagnostic mode to troubleshoot a broken file I/O subsystem. .TP .BI \-+p\ percentage_reads Used to set the percentage of threads/processes that will perform read testing in the mixed workload test case. .TP .BI \-+r Enable O_RSYNC | O_SYNC on all testing. .TP .BI \-+l Enable byte range locking. .TP .BI \-+L Enable byte range locking & shared file mode. .TP .BI \-+D Enable O_DSYNC on all testing. .TP .BI \-+t Enable network performance test. Use with -+m .TP .BI \-+A # Enable madvise behavior. 0 = normal, 1=random, 2=sequential, 3=dontneed, 4=willneed .TP .BI \-+B Enable sequential mixed workload testing. .TP .BI \-+T Enable time stamps logging. .TP .BI \-+h Manually set hostname. .SH AUTHOR Original Author: William D. Norcott. wno...@us... Features & extensions: Don Capps ca...@io... --- NEW FILE: Iozone_ps.gz --- (This appears to be a binary file; contents omitted.) |
From: Eric V. H. <er...@us...> - 2006-02-19 20:50:13
|
Update of /cvsroot/v9fs/tests/iozone/src/current In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4767/src/current Log Message: Directory /cvsroot/v9fs/tests/iozone/src/current added to the repository |
From: Eric V. H. <er...@us...> - 2006-02-19 20:50:07
|
Update of /cvsroot/v9fs/tests/iozone/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4603/src Log Message: Directory /cvsroot/v9fs/tests/iozone/src added to the repository |
From: Eric V. H. <er...@us...> - 2006-02-19 20:49:42
|
Update of /cvsroot/v9fs/tests/iozone/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4540/docs Log Message: Directory /cvsroot/v9fs/tests/iozone/docs added to the repository |
From: Eric V. H. <er...@us...> - 2006-02-19 20:49:19
|
Update of /cvsroot/v9fs/tests/iozone In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4493/iozone Log Message: Directory /cvsroot/v9fs/tests/iozone added to the repository |
From: Latchesar I. <li...@us...> - 2006-01-21 00:35:08
|
Update of /cvsroot/v9fs/npfs/libnpfs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2347/libnpfs Modified Files: conn.c fdtrans.c file.c fmt.c np.c socksrv.c srv.c Log Message: various fixes, (not very useful at the moment) implementation of cpu command for Linux Index: socksrv.c =================================================================== RCS file: /cvsroot/v9fs/npfs/libnpfs/socksrv.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** socksrv.c 29 Dec 2005 01:42:34 -0000 1.2 --- socksrv.c 21 Jan 2006 00:34:52 -0000 1.3 *************** *** 64,69 **** Npsrv* ! np_socksrv_create_tcp(int nwthreads, int port) { Npsrv *srv; Socksrv *ss; --- 64,70 ---- Npsrv* ! np_socksrv_create_tcp(int nwthreads, int *port) { + socklen_t n; Npsrv *srv; Socksrv *ss; *************** *** 75,81 **** saddr->sin_family = AF_INET; ! saddr->sin_port = htons(port); saddr->sin_addr.s_addr = htonl(INADDR_ANY); - if (bind(ss->sock, ss->addr, sizeof(*saddr)) < 0) { fprintf(stderr, "cannot bind: %d\n", errno); --- 76,81 ---- saddr->sin_family = AF_INET; ! saddr->sin_port = htons(*port); saddr->sin_addr.s_addr = htonl(INADDR_ANY); if (bind(ss->sock, ss->addr, sizeof(*saddr)) < 0) { fprintf(stderr, "cannot bind: %d\n", errno); *************** *** 84,87 **** --- 84,95 ---- } + saddr->sin_port = 4242; + n = sizeof(*saddr); + if (getsockname(ss->sock, ss->addr, &n) < 0) { + perror("getsockname"); + } + + *port = ntohs(saddr->sin_port); + srv = np_srv_create(nwthreads); srv->srvaux = ss; *************** *** 93,96 **** --- 101,115 ---- } + /* + int + np_socksrv_get_port(Npsrv *srv) + { + Socksrv *ss; + + ss = srv->srvaux; + return ss->addr->port; + } + */ + static void np_socksrv_start(Npsrv *srv) Index: np.c =================================================================== RCS file: /cvsroot/v9fs/npfs/libnpfs/np.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** np.c 2 Jan 2006 02:12:49 -0000 1.3 --- np.c 21 Jan 2006 00:34:52 -0000 1.4 *************** *** 328,342 **** np_strcmp(Npstr *str, char *cs) { ! int n, ret; ret = strncmp(str->str, cs, str->len); ! if (!ret) { ! n = strlen(cs); ! if (n > str->len) ! ret = -1; ! else if (n < str->len) ! ret = 1; ! } ! return ret; } --- 328,337 ---- np_strcmp(Npstr *str, char *cs) { ! int ret; ret = strncmp(str->str, cs, str->len); ! if (!ret && cs[str->len]) ! ret = 1; ! return ret; } *************** *** 345,352 **** np_strncmp(Npstr *str, char *cs, int len) { ! int n, ret; ! n = strlen(cs); ! if (n>=len && str->len>=len) ret = strncmp(str->str, cs, len); else --- 340,346 ---- np_strncmp(Npstr *str, char *cs, int len) { ! int ret; ! if (str->len >= len) ret = strncmp(str->str, cs, len); else Index: srv.c =================================================================== RCS file: /cvsroot/v9fs/npfs/libnpfs/srv.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** srv.c 2 Jan 2006 02:12:49 -0000 1.3 --- srv.c 21 Jan 2006 00:34:52 -0000 1.4 *************** *** 84,88 **** srv = malloc(sizeof(*srv)); pthread_mutex_init(&srv->lock, NULL); - pthread_cond_init(&srv->conncond, NULL); pthread_cond_init(&srv->reqcond, NULL); srv->msize = 8192; --- 84,87 ---- Index: fdtrans.c =================================================================== RCS file: /cvsroot/v9fs/npfs/libnpfs/fdtrans.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** fdtrans.c 29 Dec 2005 01:42:34 -0000 1.2 --- fdtrans.c 21 Jan 2006 00:34:52 -0000 1.3 *************** *** 92,97 **** npt->aux = fdt; npt->destroy = np_fdtrans_destroy; ! npt->settbuf = np_fdtrans_settbuf; ! npt->setrbuf = np_fdtrans_setrbuf; npt->error = np_fdtrans_error; --- 92,97 ---- npt->aux = fdt; npt->destroy = np_fdtrans_destroy; ! npt->settxbuf = np_fdtrans_settbuf; ! npt->setrxbuf = np_fdtrans_setrbuf; npt->error = np_fdtrans_error; *************** *** 130,134 **** fdt = trans->aux; ! if (trans->tbuf && trans->tbuf->buf) { fdt->pfdout->events |= POLLOUT; --- 130,134 ---- fdt = trans->aux; ! if (trans->txbuf && trans->txbuf->buf) { fdt->pfdout->events |= POLLOUT; *************** *** 148,152 **** fdt = trans->aux; ! if (trans->rbuf && trans->rbuf->buf) { fdt->pfdin->events |= POLLIN; n = nppoll.flags & Notified; --- 148,152 ---- fdt = trans->aux; ! if (trans->rxbuf && trans->rxbuf->buf) { fdt->pfdin->events |= POLLIN; n = nppoll.flags & Notified; *************** *** 169,173 **** trans = fdt->trans; ! rbuf = trans->rbuf; n = read(fdt->fdin, rbuf->buf + rbuf->pos, rbuf->size - rbuf->pos); if (n <= 0) { --- 169,173 ---- trans = fdt->trans; ! rbuf = trans->rxbuf; n = read(fdt->fdin, rbuf->buf + rbuf->pos, rbuf->size - rbuf->pos); if (n <= 0) { *************** *** 193,197 **** trans = fdt->trans; ! wbuf = trans->tbuf; if (!wbuf || !wbuf->size) return; --- 193,197 ---- trans = fdt->trans; ! wbuf = trans->txbuf; if (!wbuf || !wbuf->size) return; *************** *** 216,220 **** np_fdtrans_error(Nptrans *trans) { ! trans->tbuf->error(trans->tbuf->aux, EPIPE); } --- 216,221 ---- np_fdtrans_error(Nptrans *trans) { ! if (trans->txbuf && trans->txbuf->error) ! trans->txbuf->error(trans->txbuf->aux, EPIPE); } Index: file.c =================================================================== RCS file: /cvsroot/v9fs/npfs/libnpfs/file.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** file.c 2 Jan 2006 02:12:49 -0000 1.2 --- file.c 21 Jan 2006 00:34:52 -0000 1.3 *************** *** 110,117 **** if (f->mode & Dmdir) { dops = f->ops; ! (*dops->destroy)(f); } else { fops = f->ops; ! (*fops->destroy)(f); } } --- 110,119 ---- if (f->mode & Dmdir) { dops = f->ops; ! if (dops->destroy) ! (*dops->destroy)(f); } else { fops = f->ops; ! if (fops->destroy) ! (*fops->destroy)(f); } } Index: fmt.c =================================================================== RCS file: /cvsroot/v9fs/npfs/libnpfs/fmt.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** fmt.c 13 Dec 2005 02:23:45 -0000 1.1.1.1 --- fmt.c 21 Jan 2006 00:34:52 -0000 1.2 *************** *** 92,96 **** static int ! printstat(FILE *f, Npstat *st) { int n; --- 92,96 ---- static int ! printstat(FILE *f, Npstat *st, int dotu) { int n; *************** *** 105,108 **** --- 105,111 ---- n += fprintf(f, " at %d mt %d l %lld t %d d %d", st->atime, st->mtime, st->length, st->type, st->dev); + if (dotu) + n += fprintf(f, " ext '%.*s'", st->extension.len, + st->extension.str); return n; *************** *** 142,146 **** int ! printfcall(FILE *f, Npfcall *fc) { int i, ret, type, fid, tag; --- 145,149 ---- int ! printfcall(FILE *f, Npfcall *fc, int dotu) { int i, ret, type, fid, tag; *************** *** 189,192 **** --- 192,197 ---- ret += fprintf(f, "Rerror tag %u ename %.*s", tag, fc->ename.len, fc->ename.str); + if (dotu) + ret += fprintf(f, " ecode %d", fc->ecode); break; *************** *** 279,288 **** case Rstat: ret += fprintf(f, "Rstat tag %u ", tag); ! ret += printstat(f, &fc->stat); break; case Twstat: ret += fprintf(f, "Twstat tag %u fid %d ", tag, fid); ! ret += printstat(f, &fc->stat); break; --- 284,293 ---- case Rstat: ret += fprintf(f, "Rstat tag %u ", tag); ! ret += printstat(f, &fc->stat, dotu); break; case Twstat: ret += fprintf(f, "Twstat tag %u fid %d ", tag, fid); ! ret += printstat(f, &fc->stat, dotu); break; Index: conn.c =================================================================== RCS file: /cvsroot/v9fs/npfs/libnpfs/conn.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** conn.c 13 Dec 2005 02:23:45 -0000 1.1.1.1 --- conn.c 21 Jan 2006 00:34:52 -0000 1.2 *************** *** 29,34 **** #include "npfsimpl.h" ! extern int printfcall(FILE *f, Npfcall *fc); ! static void np_conn_error(Npconn *conn, int err); static void np_conn_data_in(void *); --- 29,33 ---- #include "npfsimpl.h" ! extern int printfcall(FILE *f, Npfcall *fc, int dotu); static void np_conn_error(Npconn *conn, int err); static void np_conn_data_in(void *); *************** *** 69,73 **** conn->freerclist = NULL; np_conn_new_rcall(conn); ! np_trans_set_rbuf(conn->trans, &conn->rbuf); np_conn_new_wcall(conn, NULL); --- 68,72 ---- conn->freerclist = NULL; np_conn_new_rcall(conn); ! np_trans_set_rxbuf(conn->trans, &conn->rbuf); np_conn_new_wcall(conn, NULL); *************** *** 134,138 **** free(conn->rcall); np_conn_new_rcall(conn); ! np_trans_set_rbuf(conn->trans, &conn->rbuf); np_conn_new_wcall(conn, NULL); pthread_mutex_unlock(&conn->lock); --- 133,137 ---- free(conn->rcall); np_conn_new_rcall(conn); ! np_trans_set_rxbuf(conn->trans, &conn->rbuf); np_conn_new_wcall(conn, NULL); pthread_mutex_unlock(&conn->lock); *************** *** 191,195 **** if (conn->srv->debuglevel) { fprintf(stderr, "<<< "); ! printfcall(stderr, conn->rcall); fprintf(stderr, "\n"); } --- 190,194 ---- if (conn->srv->debuglevel) { fprintf(stderr, "<<< "); ! printfcall(stderr, conn->rcall, conn->dotu); fprintf(stderr, "\n"); } *************** *** 216,220 **** if (bufchanged) ! np_trans_set_rbuf(conn->trans, &conn->rbuf); } --- 215,219 ---- if (bufchanged) ! np_trans_set_rxbuf(conn->trans, &conn->rbuf); } *************** *** 241,245 **** np_conn_new_wcall(conn, rc); pthread_mutex_unlock(&conn->lock); ! np_trans_set_tbuf(conn->trans, &conn->wbuf); } --- 240,244 ---- np_conn_new_wcall(conn, rc); pthread_mutex_unlock(&conn->lock); ! np_trans_set_txbuf(conn->trans, &conn->wbuf); } *************** *** 266,270 **** if (conn->srv->debuglevel) { fprintf(stderr, ">>> "); ! printfcall(stderr, rc); fprintf(stderr, "\n"); } --- 265,269 ---- if (conn->srv->debuglevel) { fprintf(stderr, ">>> "); ! printfcall(stderr, rc, conn->dotu); fprintf(stderr, "\n"); } *************** *** 274,278 **** np_conn_new_wcall(conn, rc); pthread_mutex_unlock(&conn->lock); ! np_trans_set_tbuf(conn->trans, &conn->wbuf); } else { rc->next = NULL; --- 273,277 ---- np_conn_new_wcall(conn, rc); pthread_mutex_unlock(&conn->lock); ! np_trans_set_txbuf(conn->trans, &conn->wbuf); } else { rc->next = NULL; *************** *** 362,367 **** trans = malloc(sizeof(*trans)); pthread_mutex_init(&trans->lock, NULL); ! trans->tbuf = NULL; ! trans->rbuf = NULL; return trans; --- 361,366 ---- trans = malloc(sizeof(*trans)); pthread_mutex_init(&trans->lock, NULL); ! trans->txbuf = NULL; ! trans->rxbuf = NULL; return trans; *************** *** 376,395 **** void ! np_trans_set_tbuf(Nptrans *trans, Npbuf *buf) { pthread_mutex_lock(&trans->lock); ! trans->tbuf = buf; ! if (trans->settbuf) ! (*trans->settbuf)(trans); pthread_mutex_unlock(&trans->lock); } void ! np_trans_set_rbuf(Nptrans *trans, Npbuf *buf) { pthread_mutex_lock(&trans->lock); ! trans->rbuf = buf; ! if (trans->setrbuf) ! (*trans->setrbuf)(trans); pthread_mutex_unlock(&trans->lock); } --- 375,394 ---- void ! np_trans_set_txbuf(Nptrans *trans, Npbuf *buf) { pthread_mutex_lock(&trans->lock); ! trans->txbuf = buf; ! if (trans->settxbuf) ! (*trans->settxbuf)(trans); pthread_mutex_unlock(&trans->lock); } void ! np_trans_set_rxbuf(Nptrans *trans, Npbuf *buf) { pthread_mutex_lock(&trans->lock); ! trans->rxbuf = buf; ! if (trans->setrxbuf) ! (*trans->setrxbuf)(trans); pthread_mutex_unlock(&trans->lock); } |
From: Latchesar I. <li...@us...> - 2006-01-21 00:35:07
|
Update of /cvsroot/v9fs/npfs/fs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2347/fs Modified Files: Makefile nullfs.c ufs.c Added Files: cpu.c cpuhelper.c Log Message: various fixes, (not very useful at the moment) implementation of cpu command for Linux --- NEW FILE: cpuhelper.c --- /* * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sched.h> #include <string.h> #include <sys/mount.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/stat.h> #include <errno.h> #include <signal.h> #include <linux/unistd.h> #define MS_MOVE 8192 static char *host; static int port; static char *uname; static char *cmd; static char **args; static char mntpt[256]; int procfn(void *a) { int n; char opts[256]; char mdir[256]; snprintf(opts, sizeof(opts), "name=%s,port=%d,debug=1", uname, port); n = mount(host, mntpt, "9P", 0, opts); if (n < 0) { perror("mount"); return -1; } snprintf(mdir, sizeof(mdir), "%s/dev", mntpt); n = mount("/dev", mdir, NULL, MS_BIND, NULL); if (n < 0) { perror("bind dev"); return -1; } snprintf(mdir, sizeof(mdir), "%s/proc", mntpt); n = mount("/proc", mdir, NULL, MS_BIND, NULL); if (n < 0) { perror("bind proc"); return -1; } snprintf(mdir, sizeof(mdir), "%s/sys", mntpt); n = mount("/sys", mdir, NULL, MS_BIND, NULL); if (n < 0) { perror("bind sys"); return -1; } chdir(mntpt); n = mount(mntpt, "/", NULL, MS_MOVE, NULL); if (n < 0) { perror("move mount"); return -1; } chroot("."); execv(cmd, args); snprintf(mdir, sizeof(mdir), "execv %s", cmd); perror(mdir); return -1; } static void usage() { fprintf(stderr, "cpud uname host port\n"); exit(-1); } int main(int argc, char **argv) { int i, nargs; char *s; pid_t pid, p; char stk[10000]; if (argc < 4) usage(); uname = argv[1]; host = argv[2]; port = strtol(argv[3], &s, 10); if (*s != 0) usage(); nargs = argc - 3; if (nargs < 2) nargs = 2; cmd = "/bin/bash"; args = calloc(nargs, sizeof(char *)); if (argc > 4) { cmd = argv[4]; for(i = 4; i < argc; i++) args[i-4] = argv[i]; } else { cmd = "/bin/bash"; args[1] = "--login"; } args[0] = cmd; snprintf(mntpt, sizeof(mntpt), "/tmp/cpu%d", getpid()); mkdir(mntpt, 0700); pid = clone(procfn, stk + 5000, CLONE_NEWNS | CLONE_FILES | CLONE_PTRACE | SIGCHLD, NULL); if ((int) pid == -1) { perror("clone"); exit(-1); } p = waitpid(pid, NULL, 0); if ((int) p == -1) { perror("waitpid"); exit(-1); } if (!rmdir(mntpt)) perror("rmdir"); return 0; } Index: Makefile =================================================================== RCS file: /cvsroot/v9fs/npfs/fs/Makefile,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Makefile 29 Dec 2005 01:42:34 -0000 1.2 --- Makefile 21 Jan 2006 00:34:52 -0000 1.3 *************** *** 18,22 **** mboxfs.o\ ! all: ufs ramfs nullfs ramfs2 gphotofs mboxfs ufs: ufs.o --- 18,22 ---- mboxfs.o\ ! all: ufs ramfs nullfs ramfs2 ufs: ufs.o *************** *** 44,47 **** --- 44,53 ---- $(CC) $(CFLAGS) -I/usr/include/libetpan -c $*.c + cpu: cpu.o ../libnpfs/libnpfs.a + $(CC) -o cpu $(CFLAGS) cpu.o $(LFLAGS) + + cpuhelper: cpuhelper.o + $(CC) -o cpuhelper $(CFLAGS) cpuhelper.o $(LFLAGS) + clean: rm -f *.o ufs ramfs nullfs ramfs2 gphotofs mboxfs --- NEW FILE: cpu.c --- /* * Copyright (C) 2005 by Latchesar Ionkov <lu...@io...> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, [...991 lines suppressed...] create_rerror(errno); goto out; } free(f->path); f->path = npath; } } if (stat->length != ~0) { if (truncate(f->path, stat->length) < 0) { create_rerror(errno); goto out; } } ret = np_create_rwstat(); out: return ret; } Index: nullfs.c =================================================================== RCS file: /cvsroot/v9fs/npfs/fs/nullfs.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** nullfs.c 29 Dec 2005 01:42:34 -0000 1.2 --- nullfs.c 21 Jan 2006 00:34:52 -0000 1.3 *************** *** 32,242 **** #include "npfs.h" ! #define ROOTPERM 0755 ! #define NELEM(x) (sizeof(x)/sizeof((x)[0])) ! ! typedef struct Fid Fid; ! struct Fid { ! int isnull; ! }; static Npsrv *srv; ! static Npqid rootqid; ! static Npqid nullqid; ! static Npfcall* nullfs_attach(Npfid *fid, Npfid *afid, Npstr *uname, Npstr *aname); ! static int nullfs_clone(Npfid *fid, Npfid *newfid); ! static int nullfs_walk(Npfid *fid, Npstr* wname, Npqid *wqid); ! static Npfcall* nullfs_open(Npfid *fid, u8 mode); ! static Npfcall* nullfs_create(Npfid *fid, Npstr* name, u32 perm, u8 mode); ! static Npfcall* nullfs_read(Npfid *fid, u64 offset, u32 count); ! static Npfcall* nullfs_write(Npfid *fid, u64 offset, u32 count, u8 *data); ! static Npfcall* nullfs_clunk(Npfid *fid); ! static Npfcall* nullfs_remove(Npfid *fid); ! static Npfcall* nullfs_stat(Npfid *fid); ! static Npfcall* nullfs_wstat(Npfid *fid, Npstat *stat); static void - fillwstat(Npwstat *wstat, int isnull) { - wstat->size = 0; - wstat->type = 0; - wstat->dev = 0; - if (!isnull) { - wstat->qid = nullqid; - wstat->mode = Dmdir | 0777; - wstat->name = ""; - wstat->qid.path = 0; - } else { - wstat->qid = rootqid; - wstat->mode = 0666; - wstat->name = "null"; - wstat->qid.path = 1; - } - - wstat->qid.type = 0; - wstat->qid.version = 0; - wstat->length = 0; - wstat->uid = "root"; - wstat->gid = "root"; - wstat->muid = "root"; - wstat->extension = ""; - wstat->n_uid = 0; - wstat->n_gid = 0; - wstat->n_muid = 0; - } - - static Npfcall* - nullfs_attach(Npfid *nfid, Npfid *nafid, Npstr *uname, Npstr *aname) - { - Npfcall* ret; - Fid *fid; - Npuser *user; - - user = NULL; - ret = NULL; - - if (nafid != NULL) { - np_werror(Enoauth, EIO); - return NULL; - } - - fid = malloc(sizeof(*fid)); - fid->isnull = 0; - nfid->aux = fid; - - np_fid_incref(nfid); - ret = np_create_rattach(&rootqid); - return ret; - } - - static int - nullfs_clone(Npfid *fid, Npfid *newfid) - { - Fid *f, *nf; - - f = fid->aux; - nf = malloc(sizeof(*nf)); - nf->isnull = f->isnull; - newfid->aux = nf; - - return 1; - } - - static int - nullfs_walk(Npfid *fid, Npstr* wname, Npqid *wqid) - { - char *name; - Fid *f; - - f = fid->aux; - - if (f->isnull) { - np_werror("can't walk", EPERM); - return 0; - } - - name = np_strdup(wname); - if (strcmp(name, "null") != 0) { - np_werror(Enotfound, ENOENT); - return 0; - } - - f->isnull = 1; - *wqid = nullqid; - return 1; - } - - static Npfcall* - nullfs_open(Npfid *fid, u8 mode) - { - Fid *f; - Npqid *qid; - - f = fid->aux; - if (f->isnull) - qid = &nullqid; - else - qid = &rootqid; - - return np_create_ropen(qid, 0); - } - - static Npfcall* - nullfs_create(Npfid *fid, Npstr* name, u32 perm, u8 mode) - { - np_werror(Eperm, EPERM); - return NULL; - } - - static Npfcall* - nullfs_read(Npfid *fid, u64 offset, u32 count) - { - int n; - Fid *f; - Npfcall *ret; - u8* buf; - Npwstat wstat; - - buf = malloc(count); - f = fid->aux; - if (f->isnull) { - memset(buf, 0, count); - ret = np_create_rread(count, buf); - goto out; - } - - n = 0; - if (offset == 0) { - fillwstat(&wstat, 1); - n = np_serialize_stat(&wstat, buf, count - 1, fid->conn->dotu); - } - - ret = np_create_rread(n, buf); - - out: - free(buf); - return ret; - } - - static Npfcall* - nullfs_write(Npfid *fid, u64 offset, u32 count, u8 *data) - { - return np_create_rwrite(count); - } - - static Npfcall* - nullfs_clunk(Npfid *fid) - { - np_fid_decref(fid); - // fprintf(stderr, "fid %d refcount %d\n", fid->fid, fid->refcount); - return np_create_rclunk(); - } - - static Npfcall* - nullfs_remove(Npfid *fid) - { - np_werror("permission denied", EPERM); - return NULL; - } - - static Npfcall* - nullfs_stat(Npfid *fid) - { - Fid *f; - Npwstat wstat; - - f = fid->aux; - fillwstat(&wstat, f->isnull); - return np_create_rstat(&wstat, fid->conn->dotu); - } - - - static Npfcall* - nullfs_wstat(Npfid *fid, Npstat *stat) - { - return np_create_rwstat(); - // return np_werror("permission denided", EPERM); - } - - void usage() { --- 32,57 ---- #include "npfs.h" ! static Npfile* null_first(Npfile *); ! static Npfile* null_next(Npfile *, Npfile *); ! static u32 null_read(Npfilefid *, u64, u32, u8*); ! static u32 null_write(Npfilefid *, u64, u32, u8*); ! static int null_wstat(Npfile *, Npstat *); ! static void null_connclose(Npconn *); static Npsrv *srv; ! static Npfile *root; ! static Npfile * null; ! static Npdirops rootops = { ! .first = null_first, ! .next = null_next, ! }; ! static Npfileops nullops = { ! .read = null_read, ! .write = null_write, ! .wstat = null_wstat, ! }; static void usage() { *************** *** 273,276 **** --- 88,94 ---- } + if (optind >= argc) + usage(); + if (!user) { fprintf(stderr, "invalid user\n"); *************** *** 278,313 **** } srv = np_pipesrv_create(nwthreads); if (!srv) return -1; - srv->dotu = 1; - srv->attach = nullfs_attach; - srv->clone = nullfs_clone; - srv->walk = nullfs_walk; - srv->open = nullfs_open; - srv->create = nullfs_create; - srv->read = nullfs_read; - srv->write = nullfs_write; - srv->clunk = nullfs_clunk; - srv->remove = nullfs_remove; - srv->stat = nullfs_stat; - srv->wstat = nullfs_wstat; srv->debuglevel = debuglevel; ! ! if (optind >= argc) ! usage(); np_pipesrv_mount(srv, argv[optind], user->uname, 0, opts); ! /* ! pid = fork(); ! if (pid < 0) ! return -1; ! else if (pid != 0) ! return 0; ! setsid(); ! chdir("/"); ! */ while (1) { sleep(100); --- 96,136 ---- } + close(0); + close(1); + close(2); + pid = fork(); + if (pid < 0) + return -1; + else if (pid != 0) + return 0; + + setsid(); + chdir("/"); + + root = npfile_alloc(NULL, strdup(""), 0755|Dmdir, 0, &rootops, NULL); + root->parent = root; + npfile_incref(root); + root->atime = time(NULL); + root->mtime = root->atime; + root->uid = user; + root->gid = user->dfltgroup; + root->muid = user; + + null = npfile_alloc(root, strdup("null"), 0644, 1, &nullops, NULL); + npfile_incref(null); + root->dirfirst = null; + root->dirlast = null; + srv = np_pipesrv_create(nwthreads); if (!srv) return -1; srv->debuglevel = debuglevel; ! srv->connclose = null_connclose; ! npfile_init_srv(srv, root); np_pipesrv_mount(srv, argv[optind], user->uname, 0, opts); ! while (1) { sleep(100); *************** *** 316,317 **** --- 139,183 ---- return 0; } + + static void + null_connclose(Npconn *conn) + { + exit(0); + } + + static Npfile* + null_first(Npfile *dir) + { + if (dir->dirfirst) + npfile_incref(dir->dirfirst); + + return dir->dirfirst; + } + + static Npfile* + null_next(Npfile *dir, Npfile *prevchild) + { + if (prevchild->next) + npfile_incref(prevchild->next); + + return prevchild->next; + } + + static u32 + null_read(Npfilefid* file, u64 offset, u32 count, u8* data) + { + memset(data, 0, count); + return count; + } + + static u32 + null_write(Npfilefid* file, u64 offset, u32 count, u8* data) + { + return count; + } + + static int + null_wstat(Npfile* file, Npstat* stat) + { + return 1; + } Index: ufs.c =================================================================== RCS file: /cvsroot/v9fs/npfs/fs/ufs.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ufs.c 2 Jan 2006 02:12:48 -0000 1.3 --- ufs.c 21 Jan 2006 00:34:52 -0000 1.4 *************** *** 120,124 **** } ! srv = np_socksrv_create_tcp(nwthreads, port); if (!srv) --- 120,124 ---- } ! srv = np_socksrv_create_tcp(nwthreads, &port); if (!srv) *************** *** 151,155 **** fidstat(Fid *fid) { ! if (stat(fid->path, &fid->stat) < 0) return errno; --- 151,155 ---- fidstat(Fid *fid) { ! if (lstat(fid->path, &fid->stat) < 0) return errno; *************** *** 470,474 **** path[n + wname->len + 1] = '\0'; ! if (stat(path, &st) < 0) { free(path); create_rerror(errno); --- 470,474 ---- path[n + wname->len + 1] = '\0'; ! if (lstat(path, &st) < 0) { free(path); create_rerror(errno); *************** *** 537,541 **** npath[n + name->len + 1] = '\0'; ! if (stat(npath, &st)==0 || errno!=ENOENT) { np_werror(Eexist, EEXIST); goto out; --- 537,541 ---- npath[n + name->len + 1] = '\0'; ! if (lstat(npath, &st)==0 || errno!=ENOENT) { np_werror(Eexist, EEXIST); goto out; *************** *** 656,660 **** sprintf(path, "%s/%s", f->path, dname); ! if (stat(path, &st) < 0) { free(path); create_rerror(errno); --- 656,660 ---- sprintf(path, "%s/%s", f->path, dname); ! if (lstat(path, &st) < 0) { free(path); create_rerror(errno); |
From: Latchesar I. <li...@us...> - 2006-01-21 00:35:07
|
Update of /cvsroot/v9fs/npfs/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2347/include Modified Files: npfs.h Log Message: various fixes, (not very useful at the moment) implementation of cpu command for Linux Index: npfs.h =================================================================== RCS file: /cvsroot/v9fs/npfs/include/npfs.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** npfs.h 2 Jan 2006 02:12:48 -0000 1.3 --- npfs.h 21 Jan 2006 00:34:52 -0000 1.4 *************** *** 168,172 **** /* file metadata (stat) structure used to create Twstat message ! The is similar to v9fs_stat, but the strings don't point to the same memory block and should be freed separately */ --- 168,172 ---- /* file metadata (stat) structure used to create Twstat message ! It is similar to Npstat, but the strings don't point to the same memory block and should be freed separately */ *************** *** 252,261 **** pthread_mutex_t lock; int connected; ! Npbuf* tbuf; ! Npbuf* rbuf; void* aux; ! void (*setrbuf)(Nptrans *); ! void (*settbuf)(Nptrans *); void (*error)(Nptrans *); void (*destroy)(Nptrans *); --- 252,261 ---- pthread_mutex_t lock; int connected; ! Npbuf* txbuf; ! Npbuf* rxbuf; void* aux; ! void (*settxbuf)(Nptrans *); ! void (*setrxbuf)(Nptrans *); void (*error)(Nptrans *); void (*destroy)(Nptrans *); *************** *** 280,284 **** void* aux; ! Npconn* next; /* list of connections within server */ }; --- 280,284 ---- void* aux; ! Npconn* next; /* list of connections within a server */ }; *************** *** 293,297 **** Npreq* next; /* list of all outstanding requests */ Npreq* prev; /* used for requests that are worked on */ ! Npwthread* wthread; /* for threads that are worked on */ }; --- 293,297 ---- Npreq* next; /* list of all outstanding requests */ Npreq* prev; /* used for requests that are worked on */ ! Npwthread* wthread;/* for requests that are worked on */ }; *************** *** 315,324 **** struct Npsrv { - pthread_mutex_t lock; - pthread_cond_t reqcond; - pthread_cond_t conncond; /* connection created/destroyed */ u32 msize; int dotu; /* 9P2000.u support flag */ - int shuttingdown; void* srvaux; void* treeaux; --- 315,320 ---- *************** *** 349,352 **** --- 345,351 ---- /* implementation specific */ + pthread_mutex_t lock; + pthread_cond_t reqcond; + int shuttingdown; Npconn* conns; Npwthread* wthreads; *************** *** 389,393 **** void* aux; ! /* not used -- provided for implementations convenience */ Npfile* next; Npfile* prev; --- 388,392 ---- void* aux; ! /* not used -- provided for user's convenience */ Npfile* next; Npfile* prev; *************** *** 463,468 **** Nptrans *np_trans_create(void); void np_trans_destroy(Nptrans *); ! void np_trans_set_tbuf(Nptrans *, Npbuf *); ! void np_trans_set_rbuf(Nptrans *, Npbuf *); int np_deserialize(Npfcall*, u8*, int); --- 462,467 ---- Nptrans *np_trans_create(void); void np_trans_destroy(Nptrans *); ! void np_trans_set_txbuf(Nptrans *, Npbuf *); ! void np_trans_set_rxbuf(Nptrans *, Npbuf *); int np_deserialize(Npfcall*, u8*, int); *************** *** 500,504 **** Nptrans *np_fdtrans_create(int, int); ! Npsrv *np_socksrv_create_tcp(int, int); Npsrv *np_pipesrv_create(int nwthreads); int np_pipesrv_mount(Npsrv *srv, char *mntpt, char *user, int mntflags, char *opts); --- 499,503 ---- Nptrans *np_fdtrans_create(int, int); ! Npsrv *np_socksrv_create_tcp(int, int*); Npsrv *np_pipesrv_create(int nwthreads); int np_pipesrv_mount(Npsrv *srv, char *mntpt, char *user, int mntflags, char *opts); |