{"id":1616,"date":"2012-04-03T11:08:40","date_gmt":"2012-04-03T02:08:40","guid":{"rendered":"http:\/\/peta.okechan.net\/blog\/?p=1616"},"modified":"2012-04-03T12:31:20","modified_gmt":"2012-04-03T03:31:20","slug":"xv6-59-chapter-5-file-system-code-logging","status":"publish","type":"post","link":"https:\/\/peta.okechan.net\/blog\/archives\/1616","title":{"rendered":"[xv6 #59] Chapter 5 &#8211; File system &#8211; Code: logging"},"content":{"rendered":"<p>\u30c6\u30ad\u30b9\u30c8\u306e68\u301c69\u30da\u30fc\u30b8<\/p>\n<h3>\u672c\u6587<\/h3>\n<p>\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u306b\u304a\u3051\u308b\u30ed\u30b0\u306e\u5178\u578b\u7684\u306a\u4f7f\u3044\u65b9\u306f\u6b21\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">begin_trans();\r\n\u2026\r\nbp = bread(\u2026);\r\nbp-&gt;data&#x5B;\u2026] = \u2026;\r\nlog_write(bp);\r\n\u2026\r\ncommit_trans();<\/pre>\n<p>begin_trans\u95a2\u6570\u306f\u3001\u30ed\u30b0\u3078\u72ec\u5360\u7684\u306b\u66f8\u304d\u8fbc\u3080\u305f\u3081\u306e\u30ed\u30c3\u30af\u3092\u7372\u5f97\u3067\u304d\u308b\u307e\u3067\u5f85\u3061\u3001\u7372\u5f97\u3067\u304d\u305f\u3089\u547c\u3073\u51fa\u3057\u5143\u3078\u8fd4\u308b\u3002<br \/>\nlog_write\u95a2\u6570\u306f\u3001\u5185\u90e8\u3067bwrite\u95a2\u6570\u3092\u4f7f\u3044\u3001\u66f8\u304d\u3053\u3082\u3046\u3068\u3057\u3066\u308b\u30d6\u30ed\u30c3\u30af\u306e\u5185\u5bb9\u3092\u30ed\u30b0\u306b\u8ffd\u52a0\u3057\u3001\u30bb\u30af\u30bf\u756a\u53f7\u3092\u8a18\u9332\u3059\u308b\u3002<br \/>\nlog_write\u95a2\u6570\u306f\u3001\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u306a\u3044\u306e\u3067\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u7d9a\u3051\u3066\u305d\u306e\u30d6\u30ed\u30c3\u30af\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3082\u540c\u3058\u5185\u5bb9\u304c\u8aad\u307f\u53d6\u308c\u308b\u3002<br \/>\nlog_write\u306f\u3001\u4e00\u3064\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u7279\u5b9a\u306e\u30d6\u30ed\u30c3\u30af\u3078\u306e\u66f8\u304d\u8fbc\u307f\u304c\u8907\u6570\u3042\u308b\u5834\u5408\u306b\u6ce8\u610f\u3057\u3001\u30ed\u30b0\u306b\u5bfe\u3059\u308b\u305d\u306e\u30d6\u30ed\u30c3\u30af\u306e\u76f4\u524d\u306e\u66f8\u304d\u8fbc\u307f\u3092\u4e0a\u66f8\u304d\u3059\u308b\u3002<\/p>\n<p>log.c<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">#include &quot;types.h&quot;\r\n#include &quot;defs.h&quot;\r\n#include &quot;param.h&quot;\r\n#include &quot;spinlock.h&quot;\r\n#include &quot;fs.h&quot;\r\n#include &quot;buf.h&quot;\r\n\r\n\/\/ Simple logging. Each system call that might write the file system\r\n\/\/ should be surrounded with begin_trans() and commit_trans() calls.\r\n\/\/\r\n\/\/ The log holds at most one transaction at a time. Commit forces\r\n\/\/ the log (with commit record) to disk, then installs the affected\r\n\/\/ blocks to disk, then erases the log. begin_trans() ensures that\r\n\/\/ only one system call can be in a transaction; others must wait.\r\n\/\/ \r\n\/\/ Allowing only one transaction at a time means that the file\r\n\/\/ system code doesn't have to worry about the possibility of\r\n\/\/ one transaction reading a block that another one has modified,\r\n\/\/ for example an i-node block.\r\n\/\/\r\n\/\/ Read-only system calls don't need to use transactions, though\r\n\/\/ this means that they may observe uncommitted data. I-node and\r\n\/\/ buffer locks prevent read-only calls from seeing inconsistent data.\r\n\/\/\r\n\/\/ The log is a physical re-do log containing disk blocks.\r\n\/\/ The on-disk log format:\r\n\/\/   header block, containing sector #s for block A, B, C, ...\r\n\/\/   block A\r\n\/\/   block B\r\n\/\/   block C\r\n\/\/   ...\r\n\/\/ Log appends are synchronous.\r\n\r\n\/\/ Contents of the header block, used for both the on-disk header block\r\n\/\/ and to keep track in memory of logged sector #s before commit.\r\nstruct logheader {\r\n  int n;   \r\n  int sector&#x5B;LOGSIZE];\r\n};\r\n\r\nstruct log {\r\n  struct spinlock lock;\r\n  int start;\r\n  int size;\r\n  int intrans;\r\n  int dev;\r\n  struct logheader lh;\r\n};\r\nstruct log log;\r\n\r\nstatic void recover_from_log(void);\r\n\r\nvoid\r\ninitlog(void)\r\n{\r\n  if (sizeof(struct logheader) &gt;= BSIZE)\r\n    panic(&quot;initlog: too big logheader&quot;);\r\n\r\n  struct superblock sb;\r\n  initlock(&amp;log.lock, &quot;log&quot;);\r\n  readsb(ROOTDEV, &amp;sb);\r\n  log.start = sb.size - sb.nlog;\r\n  log.size = sb.nlog;\r\n  log.dev = ROOTDEV;\r\n  recover_from_log();\r\n}\r\n\r\n\/\/ Copy committed blocks from log to their home location\r\nstatic void \r\ninstall_trans(void)\r\n{\r\n  int tail;\r\n\r\n  for (tail = 0; tail &lt; log.lh.n; tail++) {\r\n    struct buf *lbuf = bread(log.dev, log.start+tail+1); \/\/ read log block\r\n    struct buf *dbuf = bread(log.dev, log.lh.sector&#x5B;tail]); \/\/ read dst\r\n    memmove(dbuf-&gt;data, lbuf-&gt;data, BSIZE);  \/\/ copy block to dst\r\n    bwrite(dbuf);  \/\/ flush dst to disk\r\n    brelse(lbuf); \r\n    brelse(dbuf);\r\n  }\r\n}\r\n\r\n\/\/ Read the log header from disk into the in-memory log header\r\nstatic void\r\nread_head(void)\r\n{\r\n  struct buf *buf = bread(log.dev, log.start);\r\n  struct logheader *lh = (struct logheader *) (buf-&gt;data);\r\n  int i;\r\n  log.lh.n = lh-&gt;n;\r\n  for (i = 0; i &lt; log.lh.n; i++) {\r\n    log.lh.sector&#x5B;i] = lh-&gt;sector&#x5B;i];\r\n  }\r\n  brelse(buf);\r\n}\r\n\r\n\/\/ Write in-memory log header to disk, committing log entries till head\r\nstatic void\r\nwrite_head(void)\r\n{\r\n  struct buf *buf = bread(log.dev, log.start);\r\n  struct logheader *hb = (struct logheader *) (buf-&gt;data);\r\n  int i;\r\n  hb-&gt;n = log.lh.n;\r\n  for (i = 0; i &lt; log.lh.n; i++) {\r\n    hb-&gt;sector&#x5B;i] = log.lh.sector&#x5B;i];\r\n  }\r\n  bwrite(buf);\r\n  brelse(buf);\r\n}\r\n\r\nstatic void\r\nrecover_from_log(void)\r\n{\r\n  read_head();      \r\n  install_trans(); \/\/ if committed, copy from log to disk\r\n  log.lh.n = 0;\r\n  write_head(); \/\/ clear the log\r\n}\r\n\r\nvoid\r\nbegin_trans(void)\r\n{\r\n  acquire(&amp;log.lock);\r\n  while (log.intrans) {\r\n    sleep(&amp;log, &amp;log.lock);\r\n  }\r\n  log.intrans = 1;\r\n  release(&amp;log.lock);\r\n}\r\n\r\nvoid\r\ncommit_trans(void)\r\n{\r\n  if (log.lh.n &gt; 0) {\r\n    write_head();    \/\/ Causes all blocks till log.head to be commited\r\n    install_trans(); \/\/ Install all the transactions till head\r\n    log.lh.n = 0; \r\n    write_head();    \/\/ Reclaim log\r\n  }\r\n  \r\n  acquire(&amp;log.lock);\r\n  log.intrans = 0;\r\n  wakeup(&amp;log);\r\n  release(&amp;log.lock);\r\n}\r\n\r\n\/\/ Caller has modified b-&gt;data and is done with the buffer.\r\n\/\/ Append the block to the log and record the block number, \r\n\/\/ but don't write the log header (which would commit the write).\r\n\/\/ log_write() replaces bwrite(); a typical use is:\r\n\/\/   bp = bread(...)\r\n\/\/   modify bp-&gt;data&#x5B;]\r\n\/\/   log_write(bp)\r\n\/\/   brelse(bp)\r\nvoid\r\nlog_write(struct buf *b)\r\n{\r\n  int i;\r\n\r\n  if (log.lh.n &gt;= LOGSIZE || log.lh.n &gt;= log.size - 1)\r\n    panic(&quot;too big a transaction&quot;);\r\n  if (!log.intrans)\r\n    panic(&quot;write outside of trans&quot;);\r\n\r\n  for (i = 0; i &lt; log.lh.n; i++) {\r\n    if (log.lh.sector&#x5B;i] == b-&gt;sector)   \/\/ log absorbtion?\r\n      break;\r\n  }\r\n  log.lh.sector&#x5B;i] = b-&gt;sector;\r\n  struct buf *lbuf = bread(b-&gt;dev, log.start+i+1);\r\n  memmove(lbuf-&gt;data, b-&gt;data, BSIZE);\r\n  bwrite(lbuf);\r\n  brelse(lbuf);\r\n  if (i == log.lh.n)\r\n    log.lh.n++;\r\n}\r\n\r\n\/\/PAGEBREAK!\r\n\/\/ Blank page.<\/pre>\n<p>commit_trans\u95a2\u6570\u306f\u3001\u307e\u305a\u30c7\u30a3\u30b9\u30af\u3078\u30ed\u30b0\u306e\u30d8\u30c3\u30c0\u30d6\u30ed\u30c3\u30af\u3092\u66f8\u304d\u8fbc\u3080\u306e\u3067\u3001\u3053\u306e\u6642\u70b9\u306e\u76f4\u5f8c\u306b\u304a\u3051\u308b\u30af\u30e9\u30c3\u30b7\u30e5\u306f\u3001\u30ea\u30ab\u30d0\u30ea\u51e6\u7406\u306e\u5b9f\u884c\uff08\u30ed\u30b0\u306b\u8a18\u9332\u3055\u308c\u3066\u3044\u308b\u30d6\u30ed\u30c3\u30af\u3092\u518d\u66f8\u304d\u8fbc\u307f\u3059\u308b\uff09\u3092\u5f15\u304d\u8d77\u3053\u3059\u3060\u308d\u3046\u3002<br \/>\ncommit_trans\u95a2\u6570\u306f\u3001\u305d\u308c\u304b\u3089install_trans\u95a2\u6570\u3092\u547c\u3073\u3001\u30ed\u30b0\u306b\u8a18\u9332\u3055\u308c\u3066\u3044\u308b\u305d\u308c\u305e\u308c\u306e\u30d6\u30ed\u30c3\u30af\u3092\u8aad\u307f\u8fbc\u307f\u3001\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u4e0a\u306e\u3042\u308b\u3079\u304d\u5834\u6240\u305d\u308c\u3092\u66f8\u304d\u8fbc\u3080\u3002<br \/>\n\u6700\u5f8c\u306b\u3001commit_trans\u306f\u30ed\u30b0\u30d8\u30c3\u30c0\u306b\u30bc\u30ed\u3092\u66f8\u304d\u3053\u3080\u306e\u3067\u3001\u6b21\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u958b\u59cb\u3057\u305f\u5f8c\u306b\u30af\u30e9\u30c3\u30b7\u30e5\u3057\u3066\u3082\u3001\u30ea\u30ab\u30d0\u30ea\u306e\u30b3\u30fc\u30c9\u306b\u3088\u3063\u3066\u305d\u306e\u30ed\u30b0\u306f\u7121\u8996\u3055\u308c\u308b\u3002<\/p>\n<p>recover_from_log\u95a2\u6570\u306f\u3001\u8d77\u52d5\u4e2d\u3001\u6700\u521d\u306e\u30e6\u30fc\u30b6\u30d7\u30ed\u30bb\u30b9\u304c\u958b\u59cb\u3055\u308c\u308b\u524d\u306b\u5b9f\u884c\u3055\u308c\u308binitlog\u95a2\u6570\u304b\u3089\u547c\u3070\u308c\u308b\u3002<br \/>\nrecover_from_log\u95a2\u6570\u306f\u3001\u30ed\u30b0\u30d8\u30c3\u30c0\u3092\u8aad\u307f\u8fbc\u307f\u3001\u305d\u306e\u30d8\u30c3\u30c0\u304c\u30b3\u30df\u30c3\u30c8\u6e08\u307f\u306e\u30ed\u30b0\u304c\u3042\u308b\u3053\u3068\u3092\u793a\u3057\u3066\u3044\u305f\u3089\u3001commit_trans\u3068\u540c\u3058\u3088\u3046\u306a\u51e6\u7406\u3092\u884c\u3046\u3002<\/p>\n<p>filewrite\u95a2\u6570\u306b\u3001\u30ed\u30b0\u306e\u4f7f\u3044\u65b9\u306e\u4f8b\u304c\u3042\u308b\u3002<br \/>\n\u305d\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306f\u3053\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">begin_trans();\r\nilock(f-&gt;ip);\r\nr = writei(f-&gt;ip, \u2026);\r\niunlock(f-&gt;ip);\r\ncommit_trans();<\/pre>\n<p>\u3053\u306e\u30b3\u30fc\u30c9\u306f\u3001\u30ed\u30b0\u6ea2\u308c\u3092\u56de\u907f\u3059\u308b\u305f\u3081\u3001\u5de8\u5927\u306a\u66f8\u304d\u8fbc\u307f\u3092\u4e00\u5ea6\u306b\u5c11\u3057\u306e\u30bb\u30af\u30bf\u3060\u3051\u306b\u9650\u5b9a\u3057\u3001\u500b\u5225\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u5206\u5272\u3059\u308b\u30eb\u30fc\u30d7\u5185\u3067\u5b9f\u884c\u3055\u308c\u308b\u3002<br \/>\nwritei\u95a2\u6570\u306e\u547c\u3073\u51fa\u3057\u306f\u3001\u3053\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u4e00\u90e8\u3068\u3057\u3066\u3001\u591a\u6570\u306e\u30d6\u30ed\u30c3\u30af\uff08\u30d5\u30a1\u30a4\u30eb\u306einode, \u4e00\u3064\u4ee5\u4e0a\u306e\u30d3\u30c3\u30c8\u30de\u30c3\u30d7\u30d6\u30ed\u30c3\u30af\u3001\u3044\u304f\u3064\u304b\u306e\u30c7\u30fc\u30bf\u30d6\u30ed\u30c3\u30af\uff09\u3092\u66f8\u304d\u8fbc\u3080\u3002<br \/>\n\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u3092\u907f\u3051\u308b\u6226\u7565\u306e\u4e00\u74b0\u3068\u3057\u3066\u3001begin_trans\u306e\u5f8c\u306bilock\u3092\u547c\u3073\u51fa\u3059\u3002<br \/>\n\u5404\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u5468\u308a\u306b\u52b9\u679c\u7684\u306a\u30ed\u30c3\u30af\u304c\u3042\u308b\u306e\u3067\uff08\uff1f\uff09\u3001\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u306b\u306a\u3089\u306a\u3044\u30ed\u30c3\u30af\u9806\u306f\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u30ed\u30c3\u30af\u2192inode\u306e\u30ed\u30c3\u30af\u3067\u3042\u308b\u3002<\/p>\n<p>file.c\u306efilewrite\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ Write to file f.  Addr is kernel address.\r\nint\r\nfilewrite(struct file *f, char *addr, int n)\r\n{\r\n  int r;\r\n\r\n  if(f-&gt;writable == 0)\r\n    return -1;\r\n  if(f-&gt;type == FD_PIPE)\r\n    return pipewrite(f-&gt;pipe, addr, n);\r\n  if(f-&gt;type == FD_INODE){\r\n    \/\/ write a few blocks at a time to avoid exceeding\r\n    \/\/ the maximum log transaction size, including\r\n    \/\/ i-node, indirect block, allocation blocks,\r\n    \/\/ and 2 blocks of slop for non-aligned writes.\r\n    \/\/ this really belongs lower down, since writei()\r\n    \/\/ might be writing a device like the console.\r\n    int max = ((LOGSIZE-1-1-2) \/ 2) * 512;\r\n    int i = 0;\r\n    while(i &lt; n){\r\n      int n1 = n - i;\r\n      if(n1 &gt; max)\r\n        n1 = max;\r\n\r\n      begin_trans();\r\n      ilock(f-&gt;ip);\r\n      if ((r = writei(f-&gt;ip, addr + i, f-&gt;off, n1)) &gt; 0)\r\n        f-&gt;off += r;\r\n      iunlock(f-&gt;ip);\r\n      commit_trans();\r\n\r\n      if(r &lt; 0)\r\n        break;\r\n      if(r != n1)\r\n        panic(&quot;short filewrite&quot;);\r\n      i += r;\r\n    }\r\n    return i == n ? n : -1;\r\n  }\r\n  panic(&quot;filewrite&quot;);\r\n}<\/pre>\n<h3>\u611f\u60f3<\/h3>\n<p>\u30ed\u30b0\u306e\u30b3\u30fc\u30c9\u306e\u8aac\u660e\u3067\u3059\u3002<\/p>\n<p>\u300clog_write\u95a2\u6570\u306f\u3001\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u306a\u3044\u306e\u3067\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u7d9a\u3051\u3066\u305d\u306e\u30d6\u30ed\u30c3\u30af\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3082\u540c\u3058\u5185\u5bb9\u304c\u8aad\u307f\u53d6\u308c\u308b\u3002\u300d\u306e\u90e8\u5206\u306e\u88dc\u8db3\u3002<br \/>\n\u30a2\u30d7\u30ea\u30ec\u30d9\u30eb\u306e\u51e6\u7406\u3068\u3057\u3066\u3001\u30d6\u30ed\u30c3\u30af\u306e\u5185\u5bb9\u3092\u8aad\u307f\u8fbc\u3080\u2192\u305d\u306e\u5185\u5bb9\u3092\u5909\u66f4\u3059\u308b\u2192\u30c7\u30a3\u30b9\u30af\u306b\u53cd\u6620\u3001\u3068\u3044\u3046\u6d41\u308c\u3092\u8003\u3048\u308b\u3068\u3001\u6700\u5f8c\u306e\u300c\u30c7\u30a3\u30b9\u30af\u306b\u53cd\u6620\u300d\u3059\u308b\u51e6\u7406\u306e\u6700\u521d\u306e\u65b9\u3067log_write\u306f\u547c\u3070\u308c\u308b\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002<br \/>\nlog_write\u304c\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u306a\u3044\u3068\u3044\u3046\u3053\u3068\u306f\u3001\u30e1\u30e2\u30ea\u4e0a\u306e\u30d0\u30c3\u30d5\u30a1\u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u3042\u308b\u3001\u3068\u3042\u308b\u30d6\u30ed\u30c3\u30af\u306e\u5909\u66f4\u3055\u308c\u305f\u5185\u5bb9\uff08\u672a\u3060\u30c7\u30a3\u30b9\u30af\u306b\u306f\u53cd\u6620\u3055\u308c\u3066\u3044\u306a\u3044\uff09\u304c\u305d\u306e\u307e\u307e\u30e1\u30e2\u30ea\u4e0a\u306b\u6b8b\u308b\u3053\u3068\u306b\u306a\u308b\u306e\u3067\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u305d\u306e\u30d6\u30ed\u30c3\u30af\u306e\u5185\u5bb9\u3092\u8aad\u307f\u53d6\u3063\u3066\u3082\u3001\u3061\u3083\u3093\u3068\u5909\u66f4\u3055\u308c\u305f\u5185\u5bb9\uff08\u672a\u3060\u30c7\u30a3\u30b9\u30af\u306b\u306f\u53cd\u6620\u3055\u308c\u3066\u306a\u3044\u3002\u30ed\u30b0\u306b\u306f\u53cd\u6620\u3055\u308c\u3066\u3044\u308b\u3051\u3069\uff09\u3092\u8aad\u307f\u53d6\u308c\u308b\u3068\u3044\u3046\u4e8b\u306b\u306a\u308a\u307e\u3059\u3002<br \/>\n\u3082\u3057log_write\u304c\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u305f\u5834\u5408\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306e\u540c\u3058\u30d6\u30ed\u30c3\u30af\u3078\u306e\u8aad\u307f\u8fbc\u307f\u3067\u3042\u3063\u3066\u3082\u3001\u30c7\u30a3\u30b9\u30af\u306b\u5909\u66f4\u524d\u306e\u30c7\u30fc\u30bf\u3092\u53d6\u308a\u306b\u884c\u3063\u3066\u3057\u307e\u3044\u3001\u591a\u5206\u304a\u304b\u3057\u306a\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u524d\u56de\u3001xv6\u306b\u306f\u30d3\u30c3\u30c8\u30de\u30c3\u30d7\u30d6\u30ed\u30c3\u30af\u304c\u4e00\u3064\u3057\u304b\u306a\u3044\u3093\u3058\u3083\u306a\u3044\u304b\u3001\u7684\u306a\u3053\u3068\u3092\u66f8\u304d\u307e\u3057\u305f\u304c\u3001\u4eca\u56de\u672c\u6587\u3067\u300c\u4e00\u3064\u4ee5\u4e0a\u306e\u30d3\u30c3\u30c8\u30de\u30c3\u30d7\u30d6\u30ed\u30c3\u30af\u300d\u3068\u66f8\u304b\u308c\u3066\u308b\u90e8\u5206\u304c\u3042\u308b\u306e\u3067\u3001\u4e88\u60f3\u304c\u5916\u308c\u305f\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002<br \/>\n\u305d\u306e\u3042\u305f\u308a\u306f\u3001\u4ee5\u964d\u3067\u3060\u3093\u3060\u3093\u4e0a\u306e\u5c64\u306b\u767b\u3063\u3066\u3044\u304f\u306b\u3064\u308c\u3066\u660e\u3089\u304b\u306b\u306a\u308b\u3093\u3058\u3083\u306a\u3044\u304b\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p>\u300c\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u306b\u306a\u3089\u306a\u3044\u30ed\u30c3\u30af\u9806\u306f\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u30ed\u30c3\u30af\u2192inode\u306e\u30ed\u30c3\u30af\u3067\u3042\u308b\u3002\u300d\u306e\u90e8\u5206\u306b\u3064\u3044\u3066\u3002<br \/>\n\u6b63\u76f4\u306a\u305c\u306a\u306e\u304b\u306f\u3088\u304f\u5206\u304b\u308a\u307e\u305b\u3093\u3002<br \/>\nbegin_tans\u306e\u69cb\u9020\u3068\u3057\u3066\u306f\u3001\u30ed\u30c3\u30af\u3092\u7372\u5f97\u2192\u4ed6\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u7d42\u308f\u308b\u307e\u3067\u5f85\u3064\u2192\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u958b\u59cb\u30d5\u30e9\u30b0\u3092\u7acb\u3066\u308b\u2192\u30ed\u30c3\u30af\u3092\u89e3\u653e\u3001\u3068\u3044\u3046\u6d41\u308c\u306b\u306a\u3063\u3066\u3044\u3066\u3001ilock\u306e\u65b9\u3082\u7c92\u5ea6\u306f\u9055\u3046\u3051\u3069\u540c\u3058\u3088\u3046\u306a\u69cb\u9020\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002<br \/>\n\u7c92\u5ea6\u304c\u5c0f\u3055\u3044\u30ed\u30c3\u30af\u2192\u7c92\u5ea6\u304c\u5927\u304d\u3044\u30ed\u30c3\u30af\u3001\u3088\u308a\u306f\u3001\u7c92\u5ea6\u304c\u5927\u304d\u3044\u30ed\u30c3\u30af\u2192\u7c92\u5ea6\u304c\u5c0f\u3055\u3044\u30ed\u30c3\u30af\u3001\u306e\u65b9\u304c\u3088\u308a\u5b89\u5168\u3067\u3042\u308b\u306e\u306f\u4f55\u3068\u306a\u304f\u308f\u304b\u308b\u6c17\u304c\u3057\u307e\u3059\u3002<br \/>\n\u305f\u3060\u3001\u500b\u5225\u306e\u9806\u756a\u3067\u306f\u306a\u304f\u3066\u5168\u4f53\u3067\u9806\u756a\u3092\u7d71\u4e00\u3055\u308c\u3066\u308b\u304b\u3069\u3046\u304b\u306b\u5f71\u97ff\u3055\u308c\u308b\u6c17\u306f\u3057\u307e\u3059\u304c\u3002<br \/>\n\u672c\u6587\u3067\u3082\u305f\u3044\u3057\u3066\u8aac\u660e\u3055\u308c\u3066\u306a\u3044\u306e\u3067\u3001\u3082\u3057\u304b\u3057\u305f\u3089\u3053\u306e\u5f8c\u306e\u7bc0\u3067\u8aac\u660e\u304c\u3042\u308b\u306e\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u30c6\u30ad\u30b9\u30c8\u306e68\u301c69\u30da\u30fc\u30b8<\/p>\n<h3>\u672c\u6587<\/h3>\n<p>\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u306b\u304a\u3051\u308b\u30ed\u30b0\u306e\u5178\u578b\u7684\u306a\u4f7f\u3044\u65b9\u306f\u6b21\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">begin_trans();\r\n\u2026\r\nbp = bread(\u2026);\r\nbp-&gt;data&#x5B;\u2026] = \u2026;\r\nlog_write(bp);\r\n\u2026\r\ncommit_trans();<\/pre>\n<p>begin_trans\u95a2\u6570\u306f\u3001\u30ed\u30b0\u3078\u72ec\u5360\u7684\u306b\u66f8\u304d\u8fbc\u3080\u305f\u3081\u306e\u30ed\u30c3\u30af\u3092\u7372\u5f97\u3067\u304d\u308b\u307e\u3067\u5f85\u3061\u3001\u7372\u5f97\u3067\u304d\u305f\u3089\u547c\u3073\u51fa\u3057\u5143\u3078\u8fd4\u308b\u3002<br \/>\nlog_write\u95a2\u6570\u306f\u3001\u5185\u90e8\u3067bwrite\u95a2\u6570\u3092\u4f7f\u3044\u3001\u66f8\u304d\u3053\u3082\u3046\u3068\u3057\u3066\u308b\u30d6\u30ed\u30c3\u30af\u306e\u5185\u5bb9\u3092\u30ed\u30b0\u306b\u8ffd\u52a0\u3057\u3001\u30bb\u30af\u30bf\u756a\u53f7\u3092\u8a18\u9332\u3059\u308b\u3002<br \/>\nlog_write\u95a2\u6570\u306f\u3001\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u306a\u3044\u306e\u3067\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u7d9a\u3051\u3066\u305d\u306e\u30d6\u30ed\u30c3\u30af\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3082\u540c\u3058\u5185\u5bb9\u304c\u8aad\u307f\u53d6\u308c\u308b\u3002<br \/>\nlog_write\u306f\u3001\u4e00\u3064\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u7279\u5b9a\u306e\u30d6\u30ed\u30c3\u30af\u3078\u306e\u66f8\u304d\u8fbc\u307f\u304c\u8907\u6570\u3042\u308b\u5834\u5408\u306b\u6ce8\u610f\u3057\u3001\u30ed\u30b0\u306b\u5bfe\u3059\u308b\u305d\u306e\u30d6\u30ed\u30c3\u30af\u306e\u76f4\u524d\u306e\u66f8\u304d\u8fbc\u307f\u3092\u4e0a\u66f8\u304d\u3059\u308b\u3002<\/p>\n<p>log.c<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">#include &quot;types.h&quot;\r\n#include &quot;defs.h&quot;\r\n#include &quot;param.h&quot;\r\n#include &quot;spinlock.h&quot;\r\n#include &quot;fs.h&quot;\r\n#include &quot;buf.h&quot;\r\n\r\n\/\/ Simple logging. Each system call that might write the file system\r\n\/\/ should be surrounded with begin_trans() and commit_trans() calls.\r\n\/\/\r\n\/\/ The log holds at most one transaction at a time. Commit forces\r\n\/\/ the log (with commit record) to disk, then installs the affected\r\n\/\/ blocks to disk, then erases the log. begin_trans() ensures that\r\n\/\/ only one system call can be in a transaction; others must wait.\r\n\/\/ \r\n\/\/ Allowing only one transaction at a time means that the file\r\n\/\/ system code doesn't have to worry about the possibility of\r\n\/\/ one transaction reading a block that another one has modified,\r\n\/\/ for example an i-node block.\r\n\/\/\r\n\/\/ Read-only system calls don't need to use transactions, though\r\n\/\/ this means that they may observe uncommitted data. I-node and\r\n\/\/ buffer locks prevent read-only calls from seeing inconsistent data.\r\n\/\/\r\n\/\/ The log is a physical re-do log containing disk blocks.\r\n\/\/ The on-disk log format:\r\n\/\/   header block, containing sector #s for block A, B, C, ...\r\n\/\/   block A\r\n\/\/   block B\r\n\/\/   block C\r\n\/\/   ...\r\n\/\/ Log appends are synchronous.\r\n\r\n\/\/ Contents of the header block, used for both the on-disk header block\r\n\/\/ and to keep track in memory of logged sector #s before commit.\r\nstruct logheader {\r\n  int n;   \r\n  int sector&#x5B;LOGSIZE];\r\n};\r\n\r\nstruct log {\r\n  struct spinlock lock;\r\n  int start;\r\n  int size;\r\n  int intrans;\r\n  int dev;\r\n  struct logheader lh;\r\n};\r\nstruct log log;\r\n\r\nstatic void recover_from_log(void);\r\n\r\nvoid\r\ninitlog(void)\r\n{\r\n  if (sizeof(struct logheader) &gt;= BSIZE)\r\n    panic(&quot;initlog: too big logheader&quot;);\r\n\r\n  struct superblock sb;\r\n  initlock(&amp;log.lock, &quot;log&quot;);\r\n  readsb(ROOTDEV, &amp;sb);\r\n  log.start = sb.size - sb.nlog;\r\n  log.size = sb.nlog;\r\n  log.dev = ROOTDEV;\r\n  recover_from_log();\r\n}\r\n\r\n\/\/ Copy committed blocks from log to their home location\r\nstatic void \r\ninstall_trans(void)\r\n{\r\n  int tail;\r\n\r\n  for (tail = 0; tail &lt; log.lh.n; tail++) {\r\n    struct buf *lbuf = bread(log.dev, log.start+tail+1); \/\/ read log block\r\n    struct buf *dbuf = bread(log.dev, log.lh.sector&#x5B;tail]); \/\/ read dst\r\n    memmove(dbuf-&gt;data, lbuf-&gt;data, BSIZE);  \/\/ copy block to dst\r\n    bwrite(dbuf);  \/\/ flush dst to disk\r\n    brelse(lbuf); \r\n    brelse(dbuf);\r\n  }\r\n}\r\n\r\n\/\/ Read the log header from disk into the in-memory log header\r\nstatic void\r\nread_head(void)\r\n{\r\n  struct buf *buf = bread(log.dev, log.start);\r\n  struct logheader *lh = (struct logheader *) (buf-&gt;data);\r\n  int i;\r\n  log.lh.n = lh-&gt;n;\r\n  for (i = 0; i &lt; log.lh.n; i++) {\r\n    log.lh.sector&#x5B;i] = lh-&gt;sector&#x5B;i];\r\n  }\r\n  brelse(buf);\r\n}\r\n\r\n\/\/ Write in-memory log header to disk, committing log entries till head\r\nstatic void\r\nwrite_head(void)\r\n{\r\n  struct buf *buf = bread(log.dev, log.start);\r\n  struct logheader *hb = (struct logheader *) (buf-&gt;data);\r\n  int i;\r\n  hb-&gt;n = log.lh.n;\r\n  for (i = 0; i &lt; log.lh.n; i++) {\r\n    hb-&gt;sector&#x5B;i] = log.lh.sector&#x5B;i];\r\n  }\r\n  bwrite(buf);\r\n  brelse(buf);\r\n}\r\n\r\nstatic void\r\nrecover_from_log(void)\r\n{\r\n  read_head();      \r\n  install_trans(); \/\/ if committed, copy from log to disk\r\n  log.lh.n = 0;\r\n  write_head(); \/\/ clear the log\r\n}\r\n\r\nvoid\r\nbegin_trans(void)\r\n{\r\n  acquire(&amp;log.lock);\r\n  while (log.intrans) {\r\n    sleep(&amp;log, &amp;log.lock);\r\n  }\r\n  log.intrans = 1;\r\n  release(&amp;log.lock);\r\n}\r\n\r\nvoid\r\ncommit_trans(void)\r\n{\r\n  if (log.lh.n &gt; 0) {\r\n    write_head();    \/\/ Causes all blocks till log.head to be commited\r\n    install_trans(); \/\/ Install all the transactions till head\r\n    log.lh.n = 0; \r\n    write_head();    \/\/ Reclaim log\r\n  }\r\n  \r\n  acquire(&amp;log.lock);\r\n  log.intrans = 0;\r\n  wakeup(&amp;log);\r\n  release(&amp;log.lock);\r\n}\r\n\r\n\/\/ Caller has modified b-&gt;data and is done with the buffer.\r\n\/\/ Append the block to the log and record the block number, \r\n\/\/ but don't write the log header (which would commit the write).\r\n\/\/ log_write() replaces bwrite(); a typical use is:\r\n\/\/   bp = bread(...)\r\n\/\/   modify bp-&gt;data&#x5B;]\r\n\/\/   log_write(bp)\r\n\/\/   brelse(bp)\r\nvoid\r\nlog_write(struct buf *b)\r\n{\r\n  int i;\r\n\r\n  if (log.lh.n &gt;= LOGSIZE || log.lh.n &gt;= log.size - 1)\r\n    panic(&quot;too big a transaction&quot;);\r\n  if (!log.intrans)\r\n    panic(&quot;write outside of trans&quot;);\r\n\r\n  for (i = 0; i &lt; log.lh.n; i++) {\r\n    if (log.lh.sector&#x5B;i] == b-&gt;sector)   \/\/ log absorbtion?\r\n      break;\r\n  }\r\n  log.lh.sector&#x5B;i] = b-&gt;sector;\r\n  struct buf *lbuf = bread(b-&gt;dev, log.start+i+1);\r\n  memmove(lbuf-&gt;data, b-&gt;data, BSIZE);\r\n  bwrite(lbuf);\r\n  brelse(lbuf);\r\n  if (i == log.lh.n)\r\n    log.lh.n++;\r\n}\r\n\r\n\/\/PAGEBREAK!\r\n\/\/ Blank page.<\/pre>\n<p>commit_trans\u95a2\u6570\u306f\u3001\u307e\u305a\u30c7\u30a3\u30b9\u30af\u3078\u30ed\u30b0\u306e\u30d8\u30c3\u30c0\u30d6\u30ed\u30c3\u30af\u3092\u66f8\u304d\u8fbc\u3080\u306e\u3067\u3001\u3053\u306e\u6642\u70b9\u306e\u76f4\u5f8c\u306b\u304a\u3051\u308b\u30af\u30e9\u30c3\u30b7\u30e5\u306f\u3001\u30ea\u30ab\u30d0\u30ea\u51e6\u7406\u306e\u5b9f\u884c\uff08\u30ed\u30b0\u306b\u8a18\u9332\u3055\u308c\u3066\u3044\u308b\u30d6\u30ed\u30c3\u30af\u3092\u518d\u66f8\u304d\u8fbc\u307f\u3059\u308b\uff09\u3092\u5f15\u304d\u8d77\u3053\u3059\u3060\u308d\u3046\u3002<br \/>\ncommit_trans\u95a2\u6570\u306f\u3001\u305d\u308c\u304b\u3089install_trans\u95a2\u6570\u3092\u547c\u3073\u3001\u30ed\u30b0\u306b\u8a18\u9332\u3055\u308c\u3066\u3044\u308b\u305d\u308c\u305e\u308c\u306e\u30d6\u30ed\u30c3\u30af\u3092\u8aad\u307f\u8fbc\u307f\u3001\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u4e0a\u306e\u3042\u308b\u3079\u304d\u5834\u6240\u305d\u308c\u3092\u66f8\u304d\u8fbc\u3080\u3002<br \/>\n\u6700\u5f8c\u306b\u3001commit_trans\u306f\u30ed\u30b0\u30d8\u30c3\u30c0\u306b\u30bc\u30ed\u3092\u66f8\u304d\u3053\u3080\u306e\u3067\u3001\u6b21\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u958b\u59cb\u3057\u305f\u5f8c\u306b\u30af\u30e9\u30c3\u30b7\u30e5\u3057\u3066\u3082\u3001\u30ea\u30ab\u30d0\u30ea\u306e\u30b3\u30fc\u30c9\u306b\u3088\u3063\u3066\u305d\u306e\u30ed\u30b0\u306f\u7121\u8996\u3055\u308c\u308b\u3002<\/p>\n<p>recover_from_log\u95a2\u6570\u306f\u3001\u8d77\u52d5\u4e2d\u3001\u6700\u521d\u306e\u30e6\u30fc\u30b6\u30d7\u30ed\u30bb\u30b9\u304c\u958b\u59cb\u3055\u308c\u308b\u524d\u306b\u5b9f\u884c\u3055\u308c\u308binitlog\u95a2\u6570\u304b\u3089\u547c\u3070\u308c\u308b\u3002<br \/>\nrecover_from_log\u95a2\u6570\u306f\u3001\u30ed\u30b0\u30d8\u30c3\u30c0\u3092\u8aad\u307f\u8fbc\u307f\u3001\u305d\u306e\u30d8\u30c3\u30c0\u304c\u30b3\u30df\u30c3\u30c8\u6e08\u307f\u306e\u30ed\u30b0\u304c\u3042\u308b\u3053\u3068\u3092\u793a\u3057\u3066\u3044\u305f\u3089\u3001commit_trans\u3068\u540c\u3058\u3088\u3046\u306a\u51e6\u7406\u3092\u884c\u3046\u3002<\/p>\n<p>filewrite\u95a2\u6570\u306b\u3001\u30ed\u30b0\u306e\u4f7f\u3044\u65b9\u306e\u4f8b\u304c\u3042\u308b\u3002<br \/>\n\u305d\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306f\u3053\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">begin_trans();\r\nilock(f-&gt;ip);\r\nr = writei(f-&gt;ip, \u2026);\r\niunlock(f-&gt;ip);\r\ncommit_trans();<\/pre>\n<p>\u3053\u306e\u30b3\u30fc\u30c9\u306f\u3001\u30ed\u30b0\u6ea2\u308c\u3092\u56de\u907f\u3059\u308b\u305f\u3081\u3001\u5de8\u5927\u306a\u66f8\u304d\u8fbc\u307f\u3092\u4e00\u5ea6\u306b\u5c11\u3057\u306e\u30bb\u30af\u30bf\u3060\u3051\u306b\u9650\u5b9a\u3057\u3001\u500b\u5225\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u5206\u5272\u3059\u308b\u30eb\u30fc\u30d7\u5185\u3067\u5b9f\u884c\u3055\u308c\u308b\u3002<br \/>\nwritei\u95a2\u6570\u306e\u547c\u3073\u51fa\u3057\u306f\u3001\u3053\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u4e00\u90e8\u3068\u3057\u3066\u3001\u591a\u6570\u306e\u30d6\u30ed\u30c3\u30af\uff08\u30d5\u30a1\u30a4\u30eb\u306einode, \u4e00\u3064\u4ee5\u4e0a\u306e\u30d3\u30c3\u30c8\u30de\u30c3\u30d7\u30d6\u30ed\u30c3\u30af\u3001\u3044\u304f\u3064\u304b\u306e\u30c7\u30fc\u30bf\u30d6\u30ed\u30c3\u30af\uff09\u3092\u66f8\u304d\u8fbc\u3080\u3002<br \/>\n\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u3092\u907f\u3051\u308b\u6226\u7565\u306e\u4e00\u74b0\u3068\u3057\u3066\u3001begin_trans\u306e\u5f8c\u306bilock\u3092\u547c\u3073\u51fa\u3059\u3002<br \/>\n\u5404\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u5468\u308a\u306b\u52b9\u679c\u7684\u306a\u30ed\u30c3\u30af\u304c\u3042\u308b\u306e\u3067\uff08\uff1f\uff09\u3001\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u306b\u306a\u3089\u306a\u3044\u30ed\u30c3\u30af\u9806\u306f\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u30ed\u30c3\u30af\u2192inode\u306e\u30ed\u30c3\u30af\u3067\u3042\u308b\u3002<\/p>\n<p>file.c\u306efilewrite\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ Write to file f.  Addr is kernel address.\r\nint\r\nfilewrite(struct file *f, char *addr, int n)\r\n{\r\n  int r;\r\n\r\n  if(f-&gt;writable == 0)\r\n    return -1;\r\n  if(f-&gt;type == FD_PIPE)\r\n    return pipewrite(f-&gt;pipe, addr, n);\r\n  if(f-&gt;type == FD_INODE){\r\n    \/\/ write a few blocks at a time to avoid exceeding\r\n    \/\/ the maximum log transaction size, including\r\n    \/\/ i-node, indirect block, allocation blocks,\r\n    \/\/ and 2 blocks of slop for non-aligned writes.\r\n    \/\/ this really belongs lower down, since writei()\r\n    \/\/ might be writing a device like the console.\r\n    int max = ((LOGSIZE-1-1-2) \/ 2) * 512;\r\n    int i = 0;\r\n    while(i &lt; n){\r\n      int n1 = n - i;\r\n      if(n1 &gt; max)\r\n        n1 = max;\r\n\r\n      begin_trans();\r\n      ilock(f-&gt;ip);\r\n      if ((r = writei(f-&gt;ip, addr + i, f-&gt;off, n1)) &gt; 0)\r\n        f-&gt;off += r;\r\n      iunlock(f-&gt;ip);\r\n      commit_trans();\r\n\r\n      if(r &lt; 0)\r\n        break;\r\n      if(r != n1)\r\n        panic(&quot;short filewrite&quot;);\r\n      i += r;\r\n    }\r\n    return i == n ? n : -1;\r\n  }\r\n  panic(&quot;filewrite&quot;);\r\n}<\/pre>\n<h3>\u611f\u60f3<\/h3>\n<p>\u30ed\u30b0\u306e\u30b3\u30fc\u30c9\u306e\u8aac\u660e\u3067\u3059\u3002<\/p>\n<p>\u300clog_write\u95a2\u6570\u306f\u3001\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u306a\u3044\u306e\u3067\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u7d9a\u3051\u3066\u305d\u306e\u30d6\u30ed\u30c3\u30af\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3082\u540c\u3058\u5185\u5bb9\u304c\u8aad\u307f\u53d6\u308c\u308b\u3002\u300d\u306e\u90e8\u5206\u306e\u88dc\u8db3\u3002<br \/>\n\u30a2\u30d7\u30ea\u30ec\u30d9\u30eb\u306e\u51e6\u7406\u3068\u3057\u3066\u3001\u30d6\u30ed\u30c3\u30af\u306e\u5185\u5bb9\u3092\u8aad\u307f\u8fbc\u3080\u2192\u305d\u306e\u5185\u5bb9\u3092\u5909\u66f4\u3059\u308b\u2192\u30c7\u30a3\u30b9\u30af\u306b\u53cd\u6620\u3001\u3068\u3044\u3046\u6d41\u308c\u3092\u8003\u3048\u308b\u3068\u3001\u6700\u5f8c\u306e\u300c\u30c7\u30a3\u30b9\u30af\u306b\u53cd\u6620\u300d\u3059\u308b\u51e6\u7406\u306e\u6700\u521d\u306e\u65b9\u3067log_write\u306f\u547c\u3070\u308c\u308b\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002<br \/>\nlog_write\u304c\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u306a\u3044\u3068\u3044\u3046\u3053\u3068\u306f\u3001\u30e1\u30e2\u30ea\u4e0a\u306e\u30d0\u30c3\u30d5\u30a1\u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u3042\u308b\u3001\u3068\u3042\u308b\u30d6\u30ed\u30c3\u30af\u306e\u5909\u66f4\u3055\u308c\u305f\u5185\u5bb9\uff08\u672a\u3060\u30c7\u30a3\u30b9\u30af\u306b\u306f\u53cd\u6620\u3055\u308c\u3066\u3044\u306a\u3044\uff09\u304c\u305d\u306e\u307e\u307e\u30e1\u30e2\u30ea\u4e0a\u306b\u6b8b\u308b\u3053\u3068\u306b\u306a\u308b\u306e\u3067\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306b\u305d\u306e\u30d6\u30ed\u30c3\u30af\u306e\u5185\u5bb9\u3092\u8aad\u307f\u53d6\u3063\u3066\u3082\u3001\u3061\u3083\u3093\u3068\u5909\u66f4\u3055\u308c\u305f\u5185\u5bb9\uff08\u672a\u3060\u30c7\u30a3\u30b9\u30af\u306b\u306f\u53cd\u6620\u3055\u308c\u3066\u306a\u3044\u3002\u30ed\u30b0\u306b\u306f\u53cd\u6620\u3055\u308c\u3066\u3044\u308b\u3051\u3069\uff09\u3092\u8aad\u307f\u53d6\u308c\u308b\u3068\u3044\u3046\u4e8b\u306b\u306a\u308a\u307e\u3059\u3002<br \/>\n\u3082\u3057log_write\u304c\u6e21\u3055\u308c\u305f\u30d0\u30c3\u30d5\u30a1\u3092\u89e3\u653e\u3057\u305f\u5834\u5408\u3001\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u306e\u540c\u3058\u30d6\u30ed\u30c3\u30af\u3078\u306e\u8aad\u307f\u8fbc\u307f\u3067\u3042\u3063\u3066\u3082\u3001\u30c7\u30a3\u30b9\u30af\u306b\u5909\u66f4\u524d\u306e\u30c7\u30fc\u30bf\u3092\u53d6\u308a\u306b\u884c\u3063\u3066\u3057\u307e\u3044\u3001\u591a\u5206\u304a\u304b\u3057\u306a\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u524d\u56de\u3001xv6\u306b\u306f\u30d3\u30c3\u30c8\u30de\u30c3\u30d7\u30d6\u30ed\u30c3\u30af\u304c\u4e00\u3064\u3057\u304b\u306a\u3044\u3093\u3058\u3083\u306a\u3044\u304b\u3001\u7684\u306a\u3053\u3068\u3092\u66f8\u304d\u307e\u3057\u305f\u304c\u3001\u4eca\u56de\u672c\u6587\u3067\u300c\u4e00\u3064\u4ee5\u4e0a\u306e\u30d3\u30c3\u30c8\u30de\u30c3\u30d7\u30d6\u30ed\u30c3\u30af\u300d\u3068\u66f8\u304b\u308c\u3066\u308b\u90e8\u5206\u304c\u3042\u308b\u306e\u3067\u3001\u4e88\u60f3\u304c\u5916\u308c\u305f\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002<br \/>\n\u305d\u306e\u3042\u305f\u308a\u306f\u3001\u4ee5\u964d\u3067\u3060\u3093\u3060\u3093\u4e0a\u306e\u5c64\u306b\u767b\u3063\u3066\u3044\u304f\u306b\u3064\u308c\u3066\u660e\u3089\u304b\u306b\u306a\u308b\u3093\u3058\u3083\u306a\u3044\u304b\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p>\u300c\u30c7\u30c3\u30c9\u30ed\u30c3\u30af\u306b\u306a\u3089\u306a\u3044\u30ed\u30c3\u30af\u9806\u306f\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u30ed\u30c3\u30af\u2192inode\u306e\u30ed\u30c3\u30af\u3067\u3042\u308b\u3002\u300d\u306e\u90e8\u5206\u306b\u3064\u3044\u3066\u3002<br \/>\n\u6b63\u76f4\u306a\u305c\u306a\u306e\u304b\u306f\u3088\u304f\u5206\u304b\u308a\u307e\u305b\u3093\u3002<br \/>\nbegin_tans\u306e\u69cb\u9020\u3068\u3057\u3066\u306f\u3001\u30ed\u30c3\u30af\u3092\u7372\u5f97\u2192\u4ed6\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u7d42\u308f\u308b\u307e\u3067\u5f85\u3064\u2192\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u958b\u59cb\u30d5\u30e9\u30b0\u3092\u7acb\u3066\u308b\u2192\u30ed\u30c3\u30af\u3092\u89e3\u653e\u3001\u3068\u3044\u3046\u6d41\u308c\u306b\u306a\u3063\u3066\u3044\u3066\u3001ilock\u306e\u65b9\u3082\u7c92\u5ea6\u306f\u9055\u3046\u3051\u3069\u540c\u3058\u3088\u3046\u306a\u69cb\u9020\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002<br \/>\n\u7c92\u5ea6\u304c\u5c0f\u3055\u3044\u30ed\u30c3\u30af\u2192\u7c92\u5ea6\u304c\u5927\u304d\u3044\u30ed\u30c3\u30af\u3001\u3088\u308a\u306f\u3001\u7c92\u5ea6\u304c\u5927\u304d\u3044\u30ed\u30c3\u30af\u2192\u7c92\u5ea6\u304c\u5c0f\u3055\u3044\u30ed\u30c3\u30af\u3001\u306e\u65b9\u304c\u3088\u308a\u5b89\u5168\u3067\u3042\u308b\u306e\u306f\u4f55\u3068\u306a\u304f\u308f\u304b\u308b\u6c17\u304c\u3057\u307e\u3059\u3002<br \/>\n\u305f\u3060\u3001\u500b\u5225\u306e\u9806\u756a\u3067\u306f\u306a\u304f\u3066\u5168\u4f53\u3067\u9806\u756a\u3092\u7d71\u4e00\u3055\u308c\u3066\u308b\u304b\u3069\u3046\u304b\u306b\u5f71\u97ff\u3055\u308c\u308b\u6c17\u306f\u3057\u307e\u3059\u304c\u3002<br \/>\n\u672c\u6587\u3067\u3082\u305f\u3044\u3057\u3066\u8aac\u660e\u3055\u308c\u3066\u306a\u3044\u306e\u3067\u3001\u3082\u3057\u304b\u3057\u305f\u3089\u3053\u306e\u5f8c\u306e\u7bc0\u3067\u8aac\u660e\u304c\u3042\u308b\u306e\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32],"tags":[405],"class_list":["post-1616","post","type-post","status-publish","format-standard","hentry","category-tech","tag-xv6"],"_links":{"self":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/posts\/1616","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/comments?post=1616"}],"version-history":[{"count":0,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/posts\/1616\/revisions"}],"wp:attachment":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/media?parent=1616"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/categories?post=1616"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/tags?post=1616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}