]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Add write zeroes command
authorKeith Busch <keith.busch@intel.com>
Wed, 2 Mar 2016 15:14:13 +0000 (08:14 -0700)
committerKeith Busch <keith.busch@intel.com>
Wed, 2 Mar 2016 15:14:13 +0000 (08:14 -0700)
As part of this, moving the namespace id error handling to a common
function, as this has become a common repitition.

Signed-off-by: Keith Busch <keith.busch@intel.com>
Documentation/cmds-main.txt
Documentation/nvme-write-zeroes.1 [new file with mode: 0644]
Documentation/nvme-write-zeroes.html [new file with mode: 0644]
Documentation/nvme-write-zeroes.txt [new file with mode: 0644]
Documentation/nvme-write.1
Documentation/nvme-write.html
Documentation/nvme-write.txt
Documentation/nvme.1
Documentation/nvme.html
nvme-ioctl.c
nvme.c

index 88c7c6a5200f326e603e2f3ab24f2880af0a2dde..d21e47369daf3fd32618952eda0139a90c3689d8 100644 (file)
@@ -76,6 +76,9 @@ linknvme:nvme-read[1]::
 linknvme:nvme-write[1]::
        Issue IO Write Command
 
+linknvme:nvme-write-zeroes[1]::
+       Issue IO Write Zeroes Command
+
 linknvme:nvme-resv-acquire[1]::
        Acquire Namespace Reservation
 
diff --git a/Documentation/nvme-write-zeroes.1 b/Documentation/nvme-write-zeroes.1
new file mode 100644 (file)
index 0000000..1f526cb
--- /dev/null
@@ -0,0 +1,58 @@
+'\" t
+.\"     Title: nvme-zeroes
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
+.\"      Date: 03/02/2016
+.\"    Manual: NVMe Manual
+.\"    Source: NVMe
+.\"  Language: English
+.\"
+.TH "NVME\-ZEROES" "1" "03/02/2016" "NVMe" "NVMe Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+nvme-write-zeroes \- Send an NVMe write zeroes command, return results
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme\-write\-zeroes\fR <device> [\-\-start\-block=<slba> | \-s <slba>]
+                        [\-\-block\-count=<nlb> | \-c <nlb>]
+                        [\-\-ref\-tag=<reftag> | \-r <reftag>]
+                        [\-\-prinfo=<prinfo> | \-p <prinfo>]
+                        [\-\-app\-tag\-mask=<appmask> | \-m <appmask>]
+                        [\-\-app\-tag=<apptag> | \-a <apptag>]
+                        [\-\-limited\-retry | \-l]
+                        [\-\-force\-unit\-access | \-f]
+.fi
+.SH "DESCRIPTION"
+.sp
+The Write Zeroes command is used to set a range of logical blocks to 0\&.
+.SH "OPTIONS"
+.PP
+\-\-start\-block=<slba>, \-s <slba>
+.RS 4
+Start block\&.
+.RE
+.SH "EXAMPLES"
+.sp
+No examples yet\&.
+.SH "NVME"
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-write-zeroes.html b/Documentation/nvme-write-zeroes.html
new file mode 100644 (file)
index 0000000..0603e4f
--- /dev/null
@@ -0,0 +1,811 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
+<head>\r
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />\r
+<meta name="generator" content="AsciiDoc 8.6.7" />\r
+<title>nvme-zeroes(1)</title>\r
+<style type="text/css">\r
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */\r
+\r
+/* Default font. */\r
+body {\r
+  font-family: Georgia,serif;\r
+}\r
+\r
+/* Title font. */\r
+h1, h2, h3, h4, h5, h6,\r
+div.title, caption.title,\r
+thead, p.table.header,\r
+#toctitle,\r
+#author, #revnumber, #revdate, #revremark,\r
+#footer {\r
+  font-family: Arial,Helvetica,sans-serif;\r
+}\r
+\r
+body {\r
+  margin: 1em 5% 1em 5%;\r
+}\r
+\r
+a {\r
+  color: blue;\r
+  text-decoration: underline;\r
+}\r
+a:visited {\r
+  color: fuchsia;\r
+}\r
+\r
+em {\r
+  font-style: italic;\r
+  color: navy;\r
+}\r
+\r
+strong {\r
+  font-weight: bold;\r
+  color: #083194;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6 {\r
+  color: #527bbd;\r
+  margin-top: 1.2em;\r
+  margin-bottom: 0.5em;\r
+  line-height: 1.3;\r
+}\r
+\r
+h1, h2, h3 {\r
+  border-bottom: 2px solid silver;\r
+}\r
+h2 {\r
+  padding-top: 0.5em;\r
+}\r
+h3 {\r
+  float: left;\r
+}\r
+h3 + * {\r
+  clear: left;\r
+}\r
+h5 {\r
+  font-size: 1.0em;\r
+}\r
+\r
+div.sectionbody {\r
+  margin-left: 0;\r
+}\r
+\r
+hr {\r
+  border: 1px solid silver;\r
+}\r
+\r
+p {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0.5em;\r
+}\r
+\r
+ul, ol, li > p {\r
+  margin-top: 0;\r
+}\r
+ul > li     { color: #aaa; }\r
+ul > li > * { color: black; }\r
+\r
+pre {\r
+  padding: 0;\r
+  margin: 0;\r
+}\r
+\r
+#author {\r
+  color: #527bbd;\r
+  font-weight: bold;\r
+  font-size: 1.1em;\r
+}\r
+#email {\r
+}\r
+#revnumber, #revdate, #revremark {\r
+}\r
+\r
+#footer {\r
+  font-size: small;\r
+  border-top: 2px solid silver;\r
+  padding-top: 0.5em;\r
+  margin-top: 4.0em;\r
+}\r
+#footer-text {\r
+  float: left;\r
+  padding-bottom: 0.5em;\r
+}\r
+#footer-badges {\r
+  float: right;\r
+  padding-bottom: 0.5em;\r
+}\r
+\r
+#preamble {\r
+  margin-top: 1.5em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.imageblock, div.exampleblock, div.verseblock,\r
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,\r
+div.admonitionblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.admonitionblock {\r
+  margin-top: 2.0em;\r
+  margin-bottom: 2.0em;\r
+  margin-right: 10%;\r
+  color: #606060;\r
+}\r
+\r
+div.content { /* Block element content. */\r
+  padding: 0;\r
+}\r
+\r
+/* Block element titles. */\r
+div.title, caption.title {\r
+  color: #527bbd;\r
+  font-weight: bold;\r
+  text-align: left;\r
+  margin-top: 1.0em;\r
+  margin-bottom: 0.5em;\r
+}\r
+div.title + * {\r
+  margin-top: 0;\r
+}\r
+\r
+td div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content + div.title {\r
+  margin-top: 0.0em;\r
+}\r
+\r
+div.sidebarblock > div.content {\r
+  background: #ffffee;\r
+  border: 1px solid #dddddd;\r
+  border-left: 4px solid #f0f0f0;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.listingblock > div.content {\r
+  border: 1px solid #dddddd;\r
+  border-left: 5px solid #f0f0f0;\r
+  background: #f8f8f8;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.quoteblock, div.verseblock {\r
+  padding-left: 1.0em;\r
+  margin-left: 1.0em;\r
+  margin-right: 10%;\r
+  border-left: 5px solid #f0f0f0;\r
+  color: #888;\r
+}\r
+\r
+div.quoteblock > div.attribution {\r
+  padding-top: 0.5em;\r
+  text-align: right;\r
+}\r
+\r
+div.verseblock > pre.content {\r
+  font-family: inherit;\r
+  font-size: inherit;\r
+}\r
+div.verseblock > div.attribution {\r
+  padding-top: 0.75em;\r
+  text-align: left;\r
+}\r
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */\r
+div.verseblock + div.attribution {\r
+  text-align: left;\r
+}\r
+\r
+div.admonitionblock .icon {\r
+  vertical-align: top;\r
+  font-size: 1.1em;\r
+  font-weight: bold;\r
+  text-decoration: underline;\r
+  color: #527bbd;\r
+  padding-right: 0.5em;\r
+}\r
+div.admonitionblock td.content {\r
+  padding-left: 0.5em;\r
+  border-left: 3px solid #dddddd;\r
+}\r
+\r
+div.exampleblock > div.content {\r
+  border-left: 3px solid #dddddd;\r
+  padding-left: 0.5em;\r
+}\r
+\r
+div.imageblock div.content { padding-left: 0; }\r
+span.image img { border-style: none; }\r
+a.image:visited { color: white; }\r
+\r
+dl {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+dt {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0;\r
+  font-style: normal;\r
+  color: navy;\r
+}\r
+dd > *:first-child {\r
+  margin-top: 0.1em;\r
+}\r
+\r
+ul, ol {\r
+    list-style-position: outside;\r
+}\r
+ol.arabic {\r
+  list-style-type: decimal;\r
+}\r
+ol.loweralpha {\r
+  list-style-type: lower-alpha;\r
+}\r
+ol.upperalpha {\r
+  list-style-type: upper-alpha;\r
+}\r
+ol.lowerroman {\r
+  list-style-type: lower-roman;\r
+}\r
+ol.upperroman {\r
+  list-style-type: upper-roman;\r
+}\r
+\r
+div.compact ul, div.compact ol,\r
+div.compact p, div.compact p,\r
+div.compact div, div.compact div {\r
+  margin-top: 0.1em;\r
+  margin-bottom: 0.1em;\r
+}\r
+\r
+tfoot {\r
+  font-weight: bold;\r
+}\r
+td > div.verse {\r
+  white-space: pre;\r
+}\r
+\r
+div.hdlist {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+div.hdlist tr {\r
+  padding-bottom: 15px;\r
+}\r
+dt.hdlist1.strong, td.hdlist1.strong {\r
+  font-weight: bold;\r
+}\r
+td.hdlist1 {\r
+  vertical-align: top;\r
+  font-style: normal;\r
+  padding-right: 0.8em;\r
+  color: navy;\r
+}\r
+td.hdlist2 {\r
+  vertical-align: top;\r
+}\r
+div.hdlist.compact tr {\r
+  margin: 0;\r
+  padding-bottom: 0;\r
+}\r
+\r
+.comment {\r
+  background: yellow;\r
+}\r
+\r
+.footnote, .footnoteref {\r
+  font-size: 0.8em;\r
+}\r
+\r
+span.footnote, span.footnoteref {\r
+  vertical-align: super;\r
+}\r
+\r
+#footnotes {\r
+  margin: 20px 0 20px 0;\r
+  padding: 7px 0 0 0;\r
+}\r
+\r
+#footnotes div.footnote {\r
+  margin: 0 0 5px 0;\r
+}\r
+\r
+#footnotes hr {\r
+  border: none;\r
+  border-top: 1px solid silver;\r
+  height: 1px;\r
+  text-align: left;\r
+  margin-left: 0;\r
+  width: 20%;\r
+  min-width: 100px;\r
+}\r
+\r
+div.colist td {\r
+  padding-right: 0.5em;\r
+  padding-bottom: 0.3em;\r
+  vertical-align: top;\r
+}\r
+div.colist td img {\r
+  margin-top: 0.3em;\r
+}\r
+\r
+@media print {\r
+  #footer-badges { display: none; }\r
+}\r
+\r
+#toc {\r
+  margin-bottom: 2.5em;\r
+}\r
+\r
+#toctitle {\r
+  color: #527bbd;\r
+  font-size: 1.1em;\r
+  font-weight: bold;\r
+  margin-top: 1.0em;\r
+  margin-bottom: 0.1em;\r
+}\r
+\r
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {\r
+  margin-top: 0;\r
+  margin-bottom: 0;\r
+}\r
+div.toclevel2 {\r
+  margin-left: 2em;\r
+  font-size: 0.9em;\r
+}\r
+div.toclevel3 {\r
+  margin-left: 4em;\r
+  font-size: 0.9em;\r
+}\r
+div.toclevel4 {\r
+  margin-left: 6em;\r
+  font-size: 0.9em;\r
+}\r
+\r
+span.aqua { color: aqua; }\r
+span.black { color: black; }\r
+span.blue { color: blue; }\r
+span.fuchsia { color: fuchsia; }\r
+span.gray { color: gray; }\r
+span.green { color: green; }\r
+span.lime { color: lime; }\r
+span.maroon { color: maroon; }\r
+span.navy { color: navy; }\r
+span.olive { color: olive; }\r
+span.purple { color: purple; }\r
+span.red { color: red; }\r
+span.silver { color: silver; }\r
+span.teal { color: teal; }\r
+span.white { color: white; }\r
+span.yellow { color: yellow; }\r
+\r
+span.aqua-background { background: aqua; }\r
+span.black-background { background: black; }\r
+span.blue-background { background: blue; }\r
+span.fuchsia-background { background: fuchsia; }\r
+span.gray-background { background: gray; }\r
+span.green-background { background: green; }\r
+span.lime-background { background: lime; }\r
+span.maroon-background { background: maroon; }\r
+span.navy-background { background: navy; }\r
+span.olive-background { background: olive; }\r
+span.purple-background { background: purple; }\r
+span.red-background { background: red; }\r
+span.silver-background { background: silver; }\r
+span.teal-background { background: teal; }\r
+span.white-background { background: white; }\r
+span.yellow-background { background: yellow; }\r
+\r
+span.big { font-size: 2em; }\r
+span.small { font-size: 0.6em; }\r
+\r
+span.underline { text-decoration: underline; }\r
+span.overline { text-decoration: overline; }\r
+span.line-through { text-decoration: line-through; }\r
+\r
+div.unbreakable { page-break-inside: avoid; }\r
+\r
+\r
+/*\r
+ * xhtml11 specific\r
+ *\r
+ * */\r
+\r
+tt {\r
+  font-family: "Courier New", Courier, monospace;\r
+  font-size: inherit;\r
+  color: navy;\r
+}\r
+\r
+div.tableblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.tableblock > table {\r
+  border: 3px solid #527bbd;\r
+}\r
+thead, p.table.header {\r
+  font-weight: bold;\r
+  color: #527bbd;\r
+}\r
+p.table {\r
+  margin-top: 0;\r
+}\r
+/* Because the table frame attribute is overriden by CSS in most browsers. */\r
+div.tableblock > table[frame="void"] {\r
+  border-style: none;\r
+}\r
+div.tableblock > table[frame="hsides"] {\r
+  border-left-style: none;\r
+  border-right-style: none;\r
+}\r
+div.tableblock > table[frame="vsides"] {\r
+  border-top-style: none;\r
+  border-bottom-style: none;\r
+}\r
+\r
+\r
+/*\r
+ * html5 specific\r
+ *\r
+ * */\r
+\r
+.monospaced {\r
+  font-family: "Courier New", Courier, monospace;\r
+  font-size: inherit;\r
+  color: navy;\r
+}\r
+\r
+table.tableblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+thead, p.tableblock.header {\r
+  font-weight: bold;\r
+  color: #527bbd;\r
+}\r
+p.tableblock {\r
+  margin-top: 0;\r
+}\r
+table.tableblock {\r
+  border-width: 3px;\r
+  border-spacing: 0px;\r
+  border-style: solid;\r
+  border-color: #527bbd;\r
+  border-collapse: collapse;\r
+}\r
+th.tableblock, td.tableblock {\r
+  border-width: 1px;\r
+  padding: 4px;\r
+  border-style: solid;\r
+  border-color: #527bbd;\r
+}\r
+\r
+table.tableblock.frame-topbot {\r
+  border-left-style: hidden;\r
+  border-right-style: hidden;\r
+}\r
+table.tableblock.frame-sides {\r
+  border-top-style: hidden;\r
+  border-bottom-style: hidden;\r
+}\r
+table.tableblock.frame-none {\r
+  border-style: hidden;\r
+}\r
+\r
+th.tableblock.halign-left, td.tableblock.halign-left {\r
+  text-align: left;\r
+}\r
+th.tableblock.halign-center, td.tableblock.halign-center {\r
+  text-align: center;\r
+}\r
+th.tableblock.halign-right, td.tableblock.halign-right {\r
+  text-align: right;\r
+}\r
+\r
+th.tableblock.valign-top, td.tableblock.valign-top {\r
+  vertical-align: top;\r
+}\r
+th.tableblock.valign-middle, td.tableblock.valign-middle {\r
+  vertical-align: middle;\r
+}\r
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {\r
+  vertical-align: bottom;\r
+}\r
+\r
+\r
+/*\r
+ * manpage specific\r
+ *\r
+ * */\r
+\r
+body.manpage h1 {\r
+  padding-top: 0.5em;\r
+  padding-bottom: 0.5em;\r
+  border-top: 2px solid silver;\r
+  border-bottom: 2px solid silver;\r
+}\r
+body.manpage h2 {\r
+  border-style: none;\r
+}\r
+body.manpage div.sectionbody {\r
+  margin-left: 3em;\r
+}\r
+\r
+@media print {\r
+  body.manpage div#toc { display: none; }\r
+}\r
+</style>\r
+<script type="text/javascript">\r
+/*<![CDATA[*/\r
+var asciidoc = {  // Namespace.\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Table Of Contents generator\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+/* Author: Mihai Bazon, September 2002\r
+ * http://students.infoiasi.ro/~mishoo\r
+ *\r
+ * Table Of Content generator\r
+ * Version: 0.4\r
+ *\r
+ * Feel free to use this script under the terms of the GNU General Public\r
+ * License, as long as you do not remove or alter this notice.\r
+ */\r
+\r
+ /* modified by Troy D. Hanson, September 2006. License: GPL */\r
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */\r
+\r
+// toclevels = 1..4.\r
+toc: function (toclevels) {\r
+\r
+  function getText(el) {\r
+    var text = "";\r
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.\r
+        text += i.data;\r
+      else if (i.firstChild != null)\r
+        text += getText(i);\r
+    }\r
+    return text;\r
+  }\r
+\r
+  function TocEntry(el, text, toclevel) {\r
+    this.element = el;\r
+    this.text = text;\r
+    this.toclevel = toclevel;\r
+  }\r
+\r
+  function tocEntries(el, toclevels) {\r
+    var result = new Array;\r
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');\r
+    // Function that scans the DOM tree for header elements (the DOM2\r
+    // nodeIterator API would be a better technique but not supported by all\r
+    // browsers).\r
+    var iterate = function (el) {\r
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {\r
+          var mo = re.exec(i.tagName);\r
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {\r
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);\r
+          }\r
+          iterate(i);\r
+        }\r
+      }\r
+    }\r
+    iterate(el);\r
+    return result;\r
+  }\r
+\r
+  var toc = document.getElementById("toc");\r
+  if (!toc) {\r
+    return;\r
+  }\r
+\r
+  // Delete existing TOC entries in case we're reloading the TOC.\r
+  var tocEntriesToRemove = [];\r
+  var i;\r
+  for (i = 0; i < toc.childNodes.length; i++) {\r
+    var entry = toc.childNodes[i];\r
+    if (entry.nodeName.toLowerCase() == 'div'\r
+     && entry.getAttribute("class")\r
+     && entry.getAttribute("class").match(/^toclevel/))\r
+      tocEntriesToRemove.push(entry);\r
+  }\r
+  for (i = 0; i < tocEntriesToRemove.length; i++) {\r
+    toc.removeChild(tocEntriesToRemove[i]);\r
+  }\r
+\r
+  // Rebuild TOC entries.\r
+  var entries = tocEntries(document.getElementById("content"), toclevels);\r
+  for (var i = 0; i < entries.length; ++i) {\r
+    var entry = entries[i];\r
+    if (entry.element.id == "")\r
+      entry.element.id = "_toc_" + i;\r
+    var a = document.createElement("a");\r
+    a.href = "#" + entry.element.id;\r
+    a.appendChild(document.createTextNode(entry.text));\r
+    var div = document.createElement("div");\r
+    div.appendChild(a);\r
+    div.className = "toclevel" + entry.toclevel;\r
+    toc.appendChild(div);\r
+  }\r
+  if (entries.length == 0)\r
+    toc.parentNode.removeChild(toc);\r
+},\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Footnotes generator\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+/* Based on footnote generation code from:\r
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html\r
+ */\r
+\r
+footnotes: function () {\r
+  // Delete existing footnote entries in case we're reloading the footnodes.\r
+  var i;\r
+  var noteholder = document.getElementById("footnotes");\r
+  if (!noteholder) {\r
+    return;\r
+  }\r
+  var entriesToRemove = [];\r
+  for (i = 0; i < noteholder.childNodes.length; i++) {\r
+    var entry = noteholder.childNodes[i];\r
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")\r
+      entriesToRemove.push(entry);\r
+  }\r
+  for (i = 0; i < entriesToRemove.length; i++) {\r
+    noteholder.removeChild(entriesToRemove[i]);\r
+  }\r
+\r
+  // Rebuild footnote entries.\r
+  var cont = document.getElementById("content");\r
+  var spans = cont.getElementsByTagName("span");\r
+  var refs = {};\r
+  var n = 0;\r
+  for (i=0; i<spans.length; i++) {\r
+    if (spans[i].className == "footnote") {\r
+      n++;\r
+      var note = spans[i].getAttribute("data-note");\r
+      if (!note) {\r
+        // Use [\s\S] in place of . so multi-line matches work.\r
+        // Because JavaScript has no s (dotall) regex flag.\r
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];\r
+        spans[i].innerHTML =\r
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +\r
+          "' title='View footnote' class='footnote'>" + n + "</a>]";\r
+        spans[i].setAttribute("data-note", note);\r
+      }\r
+      noteholder.innerHTML +=\r
+        "<div class='footnote' id='_footnote_" + n + "'>" +\r
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +\r
+        n + "</a>. " + note + "</div>";\r
+      var id =spans[i].getAttribute("id");\r
+      if (id != null) refs["#"+id] = n;\r
+    }\r
+  }\r
+  if (n == 0)\r
+    noteholder.parentNode.removeChild(noteholder);\r
+  else {\r
+    // Process footnoterefs.\r
+    for (i=0; i<spans.length; i++) {\r
+      if (spans[i].className == "footnoteref") {\r
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");\r
+        href = href.match(/#.*/)[0];  // Because IE return full URL.\r
+        n = refs[href];\r
+        spans[i].innerHTML =\r
+          "[<a href='#_footnote_" + n +\r
+          "' title='View footnote' class='footnote'>" + n + "</a>]";\r
+      }\r
+    }\r
+  }\r
+},\r
+\r
+install: function(toclevels) {\r
+  var timerId;\r
+\r
+  function reinstall() {\r
+    asciidoc.footnotes();\r
+    if (toclevels) {\r
+      asciidoc.toc(toclevels);\r
+    }\r
+  }\r
+\r
+  function reinstallAndRemoveTimer() {\r
+    clearInterval(timerId);\r
+    reinstall();\r
+  }\r
+\r
+  timerId = setInterval(reinstall, 500);\r
+  if (document.addEventListener)\r
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);\r
+  else\r
+    window.onload = reinstallAndRemoveTimer;\r
+}\r
+\r
+}\r
+asciidoc.install();\r
+/*]]>*/\r
+</script>\r
+</head>\r
+<body class="manpage">\r
+<div id="header">\r
+<h1>\r
+nvme-zeroes(1) Manual Page\r
+</h1>\r
+<h2>NAME</h2>\r
+<div class="sectionbody">\r
+<p>nvme-write-zeroes -\r
+   Send an NVMe write zeroes command, return results\r
+</p>\r
+</div>\r
+</div>\r
+<div id="content">\r
+<div class="sect1">\r
+<h2 id="_synopsis">SYNOPSIS</h2>\r
+<div class="sectionbody">\r
+<div class="verseblock">\r
+<pre class="content"><em>nvme-write-zeroes</em> &lt;device&gt; [--start-block=&lt;slba&gt; | -s &lt;slba&gt;]\r
+                        [--block-count=&lt;nlb&gt; | -c &lt;nlb&gt;]\r
+                        [--ref-tag=&lt;reftag&gt; | -r &lt;reftag&gt;]\r
+                        [--prinfo=&lt;prinfo&gt; | -p &lt;prinfo&gt;]\r
+                        [--app-tag-mask=&lt;appmask&gt; | -m &lt;appmask&gt;]\r
+                        [--app-tag=&lt;apptag&gt; | -a &lt;apptag&gt;]\r
+                        [--limited-retry | -l]\r
+                        [--force-unit-access | -f]</pre>\r
+<div class="attribution">\r
+</div></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_description">DESCRIPTION</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>The Write Zeroes command is used to set a range of logical blocks to 0.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_options">OPTIONS</h2>\r
+<div class="sectionbody">\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+--start-block=&lt;slba&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+-s &lt;slba&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+        Start block.\r
+</p>\r
+</dd>\r
+</dl></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_examples">EXAMPLES</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>No examples yet.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_nvme">NVME</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div id="footnotes"><hr /></div>\r
+<div id="footer">\r
+<div id="footer-text">\r
+Last updated 2016-03-02 08:06:42 MST\r
+</div>\r
+</div>\r
+</body>\r
+</html>\r
diff --git a/Documentation/nvme-write-zeroes.txt b/Documentation/nvme-write-zeroes.txt
new file mode 100644 (file)
index 0000000..6225a28
--- /dev/null
@@ -0,0 +1,36 @@
+nvme-zeroes(1)
+==============
+
+NAME
+----
+nvme-write-zeroes - Send an NVMe write zeroes command, return results
+
+SYNOPSIS
+--------
+[verse]
+'nvme-write-zeroes' <device> [--start-block=<slba> | -s <slba>]
+                       [--block-count=<nlb> | -c <nlb>]
+                       [--ref-tag=<reftag> | -r <reftag>]
+                       [--prinfo=<prinfo> | -p <prinfo>]
+                       [--app-tag-mask=<appmask> | -m <appmask>]
+                       [--app-tag=<apptag> | -a <apptag>]
+                       [--limited-retry | -l]
+                       [--force-unit-access | -f]
+
+DESCRIPTION
+-----------
+The Write Zeroes command is used to set a range of logical blocks to 0.
+
+OPTIONS
+-------
+--start-block=<slba>::
+-s <slba>::
+       Start block.
+
+EXAMPLES
+--------
+No examples yet.
+
+NVME
+----
+Part of the nvme-user suite
index 0cf5730ed1c248ed129a41bbedb27ea435ee488d..06988c5e06ea76412f5202c7e3812f38f4c57508 100644 (file)
@@ -1,13 +1,13 @@
 '\" t
-.\"     Title: nvme-compare
+.\"     Title: nvme-write
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 10/21/2015
+.\"      Date: 03/02/2016
 .\"    Manual: NVMe Manual
 .\"    Source: NVMe
 .\"  Language: English
 .\"
-.TH "NVME\-COMPARE" "1" "10/21/2015" "NVMe" "NVMe Manual"
+.TH "NVME\-WRITE" "1" "03/02/2016" "NVMe" "NVMe Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 82a2247adf946e041dccc8e8f12b3eede68834ba..52cb07fb903f79b53ab637a7e0b283443f244101 100644 (file)
@@ -4,7 +4,7 @@
 <head>\r
 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />\r
 <meta name="generator" content="AsciiDoc 8.6.7" />\r
-<title>nvme-compare(1)</title>\r
+<title>nvme-write(1)</title>\r
 <style type="text/css">\r
 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */\r
 \r
@@ -435,7 +435,7 @@ thead, p.table.header {
 p.table {\r
   margin-top: 0;\r
 }\r
-/* Because the table frame attribute is overridden by CSS in most browsers. */\r
+/* Because the table frame attribute is overriden by CSS in most browsers. */\r
 div.tableblock > table[frame="void"] {\r
   border-style: none;\r
 }\r
@@ -738,7 +738,7 @@ asciidoc.install();
 <body class="manpage">\r
 <div id="header">\r
 <h1>\r
-nvme-compare(1) Manual Page\r
+nvme-write(1) Manual Page\r
 </h1>\r
 <h2>NAME</h2>\r
 <div class="sectionbody">\r
@@ -822,7 +822,7 @@ if you don&#8217;t provide a file.</p></div>
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Last updated 2015-10-14 13:01:30 MDT\r
+Last updated 2016-03-02 08:05:01 MST\r
 </div>\r
 </div>\r
 </body>\r
index f03e76173837b39356292531b66173ab1dbd1fe9..ee3b673573bacbe9c068131824e0597cdacb64cb 100644 (file)
@@ -1,5 +1,5 @@
-nvme-compare(1)
-===============
+nvme-write(1)
+=============
 
 NAME
 ----
index 850ca06a18aa85f245fdaacadac679d206b3b971..292fec863f056c3cc8decfc1799c270d8a18f3c1 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: nvme
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/26/2016
+.\"      Date: 03/02/2016
 .\"    Manual: NVMe Manual
 .\"    Source: NVMe
 .\"  Language: English
 .\"
-.TH "NVME" "1" "02/26/2016" "NVMe" "NVMe Manual"
+.TH "NVME" "1" "03/02/2016" "NVMe" "NVMe Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -175,6 +175,11 @@ Issue IO Read Command
 Issue IO Write Command
 .RE
 .PP
+\fBnvme-write-zeroes\fR(1)
+.RS 4
+Issue IO Write Zeroes Command
+.RE
+.PP
 \fBnvme-resv-acquire\fR(1)
 .RS 4
 Acquire Namespace Reservation
index 8d7495c01339b0c51e21bfcd2676ff25a8855e59..529491ba6729eded3b763b408e162e476ef50508 100644 (file)
@@ -435,7 +435,7 @@ thead, p.table.header {
 p.table {\r
   margin-top: 0;\r
 }\r
-/* Because the table frame attribute is overridden by CSS in most browsers. */\r
+/* Because the table frame attribute is overriden by CSS in most browsers. */\r
 div.tableblock > table[frame="void"] {\r
   border-style: none;\r
 }\r
@@ -991,6 +991,14 @@ available, run "nvme help".</p></div>
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
+<a href="nvme-write-zeroes.html">nvme-write-zeroes(1)</a>\r
+</dt>\r
+<dd>\r
+<p>\r
+        Issue IO Write Zeroes Command\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
 <a href="nvme-resv-acquire.html">nvme-resv-acquire(1)</a>\r
 </dt>\r
 <dd>\r
@@ -1088,7 +1096,7 @@ NVM-Express Site</a>.</p></div>
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Last updated 2016-02-26 08:22:43 MST\r
+Last updated 2016-03-02 08:14:01 MST\r
 </div>\r
 </div>\r
 </body>\r
index fe821b45504eff17a210df0c22634dd2176bff57..6905f8bf7e7ece24cab3709ad963a2310d878177 100644 (file)
@@ -1,5 +1,6 @@
 #include <endian.h>
 #include <sys/ioctl.h>
+#include <sys/stat.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
 
 int nvme_get_nsid(int fd)
 {
+       static struct stat nvme_stat;
+       int err = fstat(fd, &nvme_stat);
+
+       if (err < 0)
+               return err;
+
+       if (!S_ISBLK(nvme_stat.st_mode)) {
+               fprintf(stderr,
+                       "requesting namespace-id from non-block device\n");
+               exit(ENOTBLK);
+       }
        return ioctl(fd, NVME_IOCTL_ID);
 }
 
diff --git a/nvme.c b/nvme.c
index 4eb210eed4959a59ffc607469d85e90d927d1e63..d439030d6879000dda9af8e4495162fff6ac29d3 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -97,6 +97,7 @@ static const char nvme_version_string[] = NVME_VERSION;
        ENTRY(COMPARE, "compare", "Submit a Compare command, return results", compare) \
        ENTRY(READ_CMD, "read", "Submit a read command, return results", read_cmd) \
        ENTRY(WRITE_CMD, "write", "Submit a write command, return results", write_cmd) \
+       ENTRY(WRITE_ZEROES_CMD, "write-zeroes", "Submit a write command, return results", write_zeroes) \
        ENTRY(REGISTERS, "show-regs", "Shows the controller registers. Requires admin character device", show_registers) \
        ENTRY(VERSION, "version", "Shows the program version", version) \
        ENTRY(HELP, "help", "Display this help", help)
@@ -943,12 +944,6 @@ static int id_ns(int argc, char **argv)
        get_dev(1, argc, argv);
 
        if (!cfg.namespace_id) {
-               if (!S_ISBLK(nvme_stat.st_mode)) {
-                       fprintf(stderr,
-                               "%s: non-block device requires namespace-id param\n",
-                               devicename);
-                       exit(ENOTBLK);
-               }
                cfg.namespace_id = nvme_get_nsid(fd);
                if (cfg.namespace_id <= 0) {
                        perror(devicename);
@@ -975,11 +970,6 @@ static int get_ns_id(int argc, char **argv)
        int nsid;
 
        open_dev(argv[1]);
-       if (!S_ISBLK(nvme_stat.st_mode)) {
-               fprintf(stderr, "%s: requesting nsid from non-block device\n",
-                                                               devicename);
-               exit(ENOTBLK);
-       }
        nsid = nvme_get_nsid(fd);
        if (nsid <= 0) {
                perror(devicename);
@@ -1538,6 +1528,91 @@ static int sec_send(int argc, char **argv)
        return err;
 }
 
+static int write_zeroes(int argc, char **argv)
+{
+       int err;
+       __u16 control = 0;
+       const char *desc = "write_zeroes: The Write Zeroes command is used to set a "\
+                       "range of logical blocks to zero.";
+       const char *namespace_id = "desired namespace";
+       const char *start_block = "64-bit addr of first block to access";
+       const char *block_count = "number of blocks on device to access";
+       const char *limited_retry = "limit num. media access attempts";
+       const char *force = "force device to commit data before command completes";
+       const char *prinfo = "PI and check field";
+       const char *ref_tag = "reference tag (for end to end PI)";
+       const char *app_tag_mask = "app tag mask (for end to end PI)";
+       const char *app_tag = "app tag (for end to end PI)";
+
+       struct config {
+               __u64 start_block;
+               __u32 namespace_id;
+               __u32 ref_tag;
+               __u32 app_tag;
+               __u16 block_count;
+               __u8  prinfo;
+               __u8  app_tag_mask;
+               __u8  limited_retry;
+               __u8  force_unit_access;
+       };
+
+       struct config cfg = {
+               .start_block     = 0,
+               .block_count     = 0,
+               .prinfo          = 0,
+               .ref_tag         = 0,
+               .app_tag_mask    = 0,
+               .app_tag         = 0,
+       };
+
+       const struct argconfig_commandline_options command_line_options[] = {
+               {"namespace-id",      'n', "NUM",  CFG_POSITIVE,    &cfg.namespace_id,      required_argument, namespace_id},
+               {"start-block",       's', "NUM",  CFG_LONG_SUFFIX, &cfg.start_block,       required_argument, start_block},
+               {"block-count",       'c', "NUM",  CFG_SHORT,       &cfg.block_count,       required_argument, block_count},
+               {"limited-retry",     'l', "",     CFG_NONE,        &cfg.limited_retry,     no_argument,       limited_retry},
+               {"force-unit-access", 'f', "",     CFG_NONE,        &cfg.force_unit_access, no_argument,       force},
+               {"prinfo",            'p', "NUM",  CFG_BYTE,        &cfg.prinfo,            required_argument, prinfo},
+               {"ref-tag",           'r', "NUM",  CFG_POSITIVE,    &cfg.ref_tag,           required_argument, ref_tag},
+               {"app-tag-mask",      'm', "NUM",  CFG_BYTE,        &cfg.app_tag_mask,      required_argument, app_tag_mask},
+               {"app-tag",           'a', "NUM",  CFG_POSITIVE,    &cfg.app_tag,           required_argument, app_tag},
+               {0}
+       };
+
+       argconfig_parse(argc, argv, desc, command_line_options,
+                       &cfg, sizeof(cfg));
+
+       get_dev(1, argc, argv);
+
+       if (cfg.prinfo > 0xf)
+               return EINVAL;
+
+       control |= (cfg.prinfo << 10);
+       if (cfg.limited_retry)
+               control |= NVME_RW_LR;
+       if (cfg.force_unit_access)
+               control |= NVME_RW_FUA;
+
+       if (!cfg.namespace_id) {
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id <= 0) {
+                       fprintf(stderr,
+                               "%s: failed to return namespace id\n",
+                               devicename);
+                       return errno;
+               }
+       }
+
+       err = nvme_write_zeros(fd, cfg.namespace_id, cfg.start_block, cfg.block_count,
+                       control, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask);
+       if (err < 0)
+               return errno;
+       else if (err != 0)
+               fprintf(stderr, "NVME Write Zeroes Command Error:%d\n", err);
+       else
+               printf("NVME Write Zeroes Success\n");
+       return err;
+}
+
 static int dsm(int argc, char **argv)
 {
        const char *desc = "dsm: The Dataset Management command is used by the host to "\
@@ -1608,12 +1683,6 @@ static int dsm(int argc, char **argv)
        }
 
        if (!cfg.namespace_id) {
-               if (!S_ISBLK(nvme_stat.st_mode)) {
-                       fprintf(stderr,
-                               "%s: non-block device requires namespace-id param\n",
-                               devicename);
-                       exit(ENOTBLK);
-               }
                cfg.namespace_id = nvme_get_nsid(fd);
                if (cfg.namespace_id <= 0) {
                        fprintf(stderr,
@@ -1728,12 +1797,6 @@ static int resv_acquire(int argc, char **argv)
        get_dev(1, argc, argv);
 
        if (!cfg.namespace_id) {
-               if (!S_ISBLK(nvme_stat.st_mode)) {
-                       fprintf(stderr,
-                               "%s: non-block device requires namespace-id param\n",
-                               devicename);
-                       exit(ENOTBLK);
-               }
                cfg.namespace_id = nvme_get_nsid(fd);
                if (cfg.namespace_id <= 0) {
                        fprintf(stderr,
@@ -1804,12 +1867,6 @@ static int resv_register(int argc, char **argv)
        get_dev(1, argc, argv);
 
        if (!cfg.namespace_id) {
-               if (!S_ISBLK(nvme_stat.st_mode)) {
-                       fprintf(stderr,
-                               "%s: non-block device requires namespace-id param\n",
-                               devicename);
-                       exit(ENOTBLK);
-               }
                cfg.namespace_id = nvme_get_nsid(fd);
                if (cfg.namespace_id <= 0) {
                        fprintf(stderr,
@@ -1882,12 +1939,6 @@ static int resv_release(int argc, char **argv)
        get_dev(1, argc, argv);
 
        if (!cfg.namespace_id) {
-               if (!S_ISBLK(nvme_stat.st_mode)) {
-                       fprintf(stderr,
-                               "%s: non-block device requires namespace-id param\n",
-                               devicename);
-                       exit(ENOTBLK);
-               }
                cfg.namespace_id = nvme_get_nsid(fd);
                if (cfg.namespace_id <= 0) {
                        fprintf(stderr,
@@ -1954,12 +2005,6 @@ static int resv_report(int argc, char **argv)
        get_dev(1, argc, argv);
 
        if (!cfg.namespace_id) {
-               if (!S_ISBLK(nvme_stat.st_mode)) {
-                       fprintf(stderr,
-                               "%s: non-block device requires namespace-id param\n",
-                               devicename);
-                       exit(ENOTBLK);
-               }
                cfg.namespace_id = nvme_get_nsid(fd);
                if (cfg.namespace_id <= 0) {
                        fprintf(stderr,
@@ -2014,7 +2059,7 @@ static int submit_io(int opcode, char *command, const char *desc,
        const char *app_tag = "app tag (for end to end PI)";
        const char *limited_retry = "limit num. media access attempts";
        const char *latency = "output latency statistics";
-       const char *force = "return data before command completes";
+       const char *force = "force device to commit data before command completes";
        const char *show = "show command before sending";
        const char *dry = "show command instead of sending";