{"id":62,"date":"2024-03-09T15:10:58","date_gmt":"2024-03-09T07:10:58","guid":{"rendered":"http:\/\/104.46.213.183\/?p=62"},"modified":"2024-03-09T15:10:58","modified_gmt":"2024-03-09T07:10:58","slug":"lab-file-system","status":"publish","type":"post","link":"https:\/\/www.yewpo.top\/index.php\/62\/","title":{"rendered":"Lab file system"},"content":{"rendered":"<h1>Lab file system<\/h1>\n<h2>1 Large files (moderate)<\/h2>\n<blockquote>\n<p>\u4fee\u6539xv6\u73b0\u6709\u7684\u6587\u4ef6\u7cfb\u7edf\u7684inode\u76f8\u5173\u4ee3\u7801\uff0c\u4f7f\u8be5\u6587\u4ef6\u7cfb\u7edf\u6700\u5927\u80fd\u591f\u652f\u6301\u519965803\u4e2a\u5757\u3002<\/p>\n<\/blockquote>\n<h3>1.1 \u539fiNode<\/h3>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221122210216963.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221122210216963.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"image-20221122210216963\" \/><\/div><\/p>\n<p>\u539fiNode\u670912\u4e2a\u76f4\u63a5\u8bbf\u95ee\u5757\uff0c\u5916\u52a0\u4e00\u4e2a\u95f4\u63a5\u8bbf\u95ee\u5757\uff1b\u800c\u8fd9\u4e2a\u95f4\u63a5\u8bbf\u95ee\u5757\u53ef\u4ee5\u8bbf\u95ee256\u4e2a\u5757\u3002\u6240\u4ee5\u539fiNode\u8bbe\u8ba1\u53ef\u4ee5\u8bbf\u95ee\uff0812+256\uff09\u4e2a\u5757\u3002\u800c\u6211\u4eec\u73b0\u5728\u51cf\u5c11\u4e00\u4e2a\u76f4\u63a5\u8bbf\u95ee\u5757\uff0c\u589e\u52a0\u4e00\u4e2a\u4e8c\u7ea7\u95f4\u63a5\u8bbf\u95ee\u5757\u3002\u4e00\u4e2a\u4e8c\u7ea7\u95f4\u63a5\u8bbf\u95ee\u5757\uff0c\u53ef\u4ee5\u8bbf\u95ee\uff08256*256\uff09\u4e2a\u5757\u3002\u6781\u5927\u7684\u589e\u52a0\u4e86\u53ef\u4ee5\u8bbf\u95ee\u7684\u5757\u6570\u3002<\/p>\n<h3>1.3 \u65b0iNode<\/h3>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221122212836417.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221122212836417.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"image-20221122212836417\" \/><\/div><\/p>\n<p>\u65b0\u7684iNode\u76f8\u6bd4\u4e8e\u539fiNode\u4e5f\u5c31\u662f\u5220\u53bb\u4e86\u4e00\u4e2a\u76f4\u63a5\u8bbf\u95ee\u5757\uff0c\u589e\u52a0\u4e86\u4e00\u4e2a\u95f4\u63a5\u8bbf\u95ee\u5757\u3002<\/p>\n<h3>1.4 \u5b9e\u73b0\u65b0iNode<\/h3>\n<h4>1.4.1 \u4fee\u6539\u76f8\u5173\u5b8f\u548c\u7ed3\u6784\u4f53<\/h4>\n<p>\u4fee\u6539\u76f4\u63a5\u8bbf\u95ee\u5757\u7684\u6570\u91cf\uff0c\u589e\u52a0\u4e8c\u7ea7\u95f4\u63a5\u8bbf\u95ee\u5b8f\uff0c\u4fee\u6539\u6700\u5927\u6587\u4ef6\u5927\u5c0f\u3002<\/p>\n<pre><code class=\"language-C\">#define NDIRECT 11 \/\/direct\n#define NINDIRECT (BSIZE \/ sizeof(uint)) \/\/single direct\n#define NDINDIRECT (NINDIRECT * NINDIRECT) \/\/double direct\n#define MAXFILE (NDIRECT + NINDIRECT + NDINDIRECT)<\/code><\/pre>\n<p>\u4fee\u6539iNode\u548cdinode\u7ed3\u6784\u4f53\u7684data block addresses\u7684\u5927\u5c0f\uff1a<\/p>\n<pre><code class=\"language-C\">struct dinode {\n  short type;           \/\/ File type\n  short major;          \/\/ Major device number (T_DEVICE only)\n  short minor;          \/\/ Minor device number (T_DEVICE only)\n  short nlink;          \/\/ Number of links to inode in file system\n  uint size;            \/\/ Size of file (bytes)\n  uint addrs[NDIRECT+2];   \/\/ Data block addresses\n};<\/code><\/pre>\n<pre><code class=\"language-C\">struct inode {\n  uint dev;           \/\/ Device number\n  uint inum;          \/\/ Inode number\n  int ref;            \/\/ Reference count\n  struct sleeplock lock; \/\/ protects everything below here\n  int valid;          \/\/ inode has been read from disk?\n\n  short type;         \/\/ copy of disk inode\n  short major;\n  short minor;\n  short nlink;\n  uint size;\n  uint addrs[NDIRECT+2];\n};<\/code><\/pre>\n<h4>1.4.2 \u4fee\u6539bmap\u51fd\u6570<\/h4>\n<p>\u589e\u52a0\u5904\u7406\u4e8c\u7ea7\u95f4\u63a5\u8bbf\u95ee\u5373\u53ef\uff0c\u53ef\u6a21\u4eff\u4e00\u7ea7\u95f4\u63a5\u8bbf\u95ee\u7684\u5199\u6cd5\uff0c\u5982\u679c\u5730\u5740\u4e0d\u5b58\u5728\uff0c\u5c31\u5206\u914d\u65b0\u7684\u5757\uff1b<strong>\u5982\u679c\u8fd9\u4e2a\u65b0\u7684\u5757\u88ab\u4fee\u6539\uff0c\u8981\u4f7f\u7528<code>log_write()<\/code>\u51fd\u6570\uff0c\u4f7f\u4e4b\u80fd\u66f4\u65b0\u5230\u78c1\u76d8\u4e2d<\/strong>\u3002<\/p>\n<p>\u90e8\u5206\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-C\">bn -= NINDIRECT;\n\nif (bn &lt; NDINDIRECT) {\n    if ((addr = ip-&gt;addrs[NDIRECT + 1]) == 0) {\n        addr = balloc(ip-&gt;dev);\n        if (addr == 0)\n            return 0;\n        ip-&gt;addrs[NDIRECT + 1] = addr;\n    }\n    bp = bread(ip-&gt;dev, addr);\n    a = (uint*)bp-&gt;data;\n    if ((addr = a[bn \/ NINDIRECT]) == 0) {\n        addr = balloc(ip-&gt;dev);\n        if (addr == 0)\n            return 0;\n        a[bn \/ NINDIRECT] = addr;\n        log_write(bp);\n    }\n    cp = bread(ip-&gt;dev, addr);\n    b = (uint*)cp-&gt;data;\n    if ((addr = b[bn % NINDIRECT]) == 0) {\n        addr = balloc(ip-&gt;dev);\n        if (addr) {\n            b[bn % NINDIRECT] = addr;\n            log_write(cp);\n        }\n    }\n    brelse(cp);\n    brelse(bp);\n    return addr;\n}<\/code><\/pre>\n<h4>1.4.3 \u4fee\u6539itrunc\u51fd\u6570<\/h4>\n<p>\u589e\u52a0\u5220\u9664\u4e8c\u7ea7\u95f4\u5740\u5757\u7684\u529f\u80fd\uff0c\u8be5\u90e8\u5206\u4ee3\u7801\u4e5f\u53ef\u4ee5\u4eff\u7167\u4e00\u7ea7\u95f4\u5740\u6765\u5199\u3002<\/p>\n<p>\u90e8\u5206\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-C\">if(ip-&gt;addrs[NDIRECT + 1]) {\n    bp = bread(ip-&gt;dev, ip-&gt;addrs[NDIRECT + 1]);\n    a = (uint*)bp-&gt;data;\n    for (i = 0; i &lt; NINDIRECT; ++i) {\n        if (a[i]) {\n            cp = bread(ip-&gt;dev, a[i]);\n            b = (uint *) cp-&gt;data;\n            for (j = 0; j &lt; NINDIRECT; ++j) {\n                if (b[j])\n                    bfree(ip-&gt;dev, b[j]);\n            }\n            brelse(cp);\n            bfree(ip-&gt;dev, a[i]);\n        }\n    }\n    brelse(bp);\n    bfree(ip-&gt;dev, ip-&gt;addrs[NDIRECT + 1]);\n    ip-&gt;addrs[NDIRECT + 1] = 0;\n}<\/code><\/pre>\n<p>\u7136\u540ebigfile\u6d4b\u8bd5\u901a\u8fc7\u3002<\/p>\n<h2>2 Symbolic links (moderate)<\/h2>\n<blockquote>\n<p>\u5b9e\u73b0<code>symlink<\/code>\u7684\u7cfb\u7edf\u8c03\u7528\uff1b\u53e6\u4e00\u79cd\u8bf4\u6cd5\u662f\uff0c\u4f7fxv6\u652f\u6301\u8f6f\u94fe\u63a5(symbolic link)\u3002<\/p>\n<p><code>symlink<\/code>\u5728<code>C programmer&#039;s manual<\/code>(RTFM)\u4e2d\u63cf\u8ff0\u5982\u4e0b\uff1a<\/p>\n<pre><code>symlink() creates a symbolic link named linkpath which contains the string target.\n\nSymbolic links are interpreted at run time as if the contents of the link had been substituted into the path being followed to find a file or directory.\n\nSymbolic links may contain ..  path components, which (if used at the start of the link) refer to the parent directories of that in which the link resides.\n\nA symbolic link (also known as a soft link) may point to an existing file or to a nonexistent one; the latter case is known as a dangling link.\n\nThe  permissions  of  a symbolic link are irrelevant; the ownership is ignored when following the link, but is checked when removal or renaming of the link is requested and the\nlink is in a directory with the sticky bit (S_ISVTX) set.\n\nIf linkpath exists, it will not be overwritten.\n<\/code><\/pre>\n<p>\u5927\u81f4\u9700\u8981\u8fd9\u4e48\u51e0\u70b9\u529f\u80fd\uff1a<\/p>\n<ul>\n<li>\u8be5\u8f6f\u94fe\u63a5\u7684\u540d\u5b57\u53eb\u505a<code>linkpath<\/code>\uff0c\u94fe\u63a5\u7684\u4e8b\u7269\u7684\u540d\u5b57\u53eb\u505a<code>target<\/code>\uff0c\u8fd9\u4e2a\u4e8b\u7269\u4e0d\u4e00\u5b9a\u9700\u8981\u5b58\u5728\u3002\uff08\u4f60\u53ea\u9700\u8981\u767b\u8bb0\u4fe1\u606f\u5c31\u884c\uff0c\u767b\u8bb0\u6210\u529f\u5c31\u8fd4\u56de\u6210\u529f\u4fe1\u606f\uff0c\u767b\u8bb0\u5931\u8d25\u8fd4\u56de\u5931\u8d25\u4fe1\u606f\uff09<\/li>\n<li>\u88ab\u94fe\u63a5\u7684\u4e8b\u7269\u662f\u4e00\u4e2a\u6587\u4ef6\u6216\u8005\u662f\u4e00\u4e2a\u6587\u4ef6\u5939<\/li>\n<li>linkpath\u4e0d\u53ef\u4ee5\u91cd\u65b0\uff0c\u4e5f\u5c31\u662f\u8c03\u7528\u8fd9\u4e2a\u7cfb\u7edf\u8c03\u7528\u65f6\uff0c\u8fd9\u4e2alinkpath\u4e0d\u53ef\u4ee5\u5b58\u5728\u3002<\/li>\n<\/ul>\n<\/blockquote>\n<h3>2.1 \u5b9e\u73b0symlink<\/h3>\n<h4>2.1.1 \u68c0\u67e5\u8be5\u7cfb\u7edf\u8c03\u7528\u7684\u524d\u63d0\u6761\u4ef6<\/h4>\n<p>\u7528\u6237\u662f\u5426\u63d0\u4f9b\u4e86\u6709\u6548\u7684\u4e24\u4e2a\u53c2\u6570\uff0c\u4ee5\u53ca\u8fd9\u4e2a<code>linkpath<\/code>\u662f\u5426\u4e0d\u5b58\u5728\u3002\u5982\u679c\u4e0a\u8ff0\u6761\u4ef6\u4e0d\u6ee1\u8db3\uff0c\u8fd4\u56de\u9519\u8bef\u7801-1\u3002<\/p>\n<h4>2.1.2 \u65b0\u5efaiNode<\/h4>\n<p>\u6839\u636e\u5b9e\u9a8c\u63d0\u4f9b\u7684\u63d0\u793a\uff1a\u6211\u4eec\u53ef\u4ee5\u5c06\u8fd9\u4e2a\u8f6f\u94fe\u63a5\u4fdd\u5b58\u5728\u4e00\u4e2aiNode\u4e2d\uff0ctarget\u4fdd\u5b58\u5728iiNode\u7684<code>data block<\/code>\u4e2d\u3002<\/p>\n<p>\u4f60\u53ef\u80fd\u4f1a\u53d1\u73b0<code>ialloc<\/code>\u51fd\u6570\u53ef\u4ee5\u5206\u914d\u4e00\u4e2aiNode\u8282\u70b9\uff0c\u4f46\u662f\u8fd9\u4e2a\u8282\u70b9\u4e0d\u4f1a\u6709\u6570\u636e\u5757\uff0c\u9700\u8981\u7528<code>balloc<\/code>\u51fd\u6570\u5206\u914d\u4e00\u4e2a\uff0c\u4f46\u662f\u4f60\u4f1a\u53d1\u73b0\uff0c<code>balloc<\/code>\u51fd\u6570\u6ca1\u6cd5\u5728\u7cfb\u7edf\u8c03\u7528\u51fd\u6570\u4e2d\u4f7f\u7528\u3002<\/p>\n<p>\u6240\u4ee5\u901a\u8fc7<code>RTFSC<\/code>\u6cd5\u5219\u53d1\u73b0\uff0c<code>sysfile.c<\/code>\u4e2d\u7684<code>create<\/code>\u51fd\u6570\u8d77\u5230\u4e86\u5206\u914d\u4e00\u4e2aiNode\u7684\u4f5c\u7528\uff0c\u5e76\u4e14\u8fd4\u56de\u4e00\u4e2a<strong>\u4e0a\u4e86\u9501<\/strong>\u7684iNode\u3002<\/p>\n<h4>2.1.3 \u5199\u5165target<\/h4>\n<p>\u5f53\u7136\uff0c\u4f60\u901a\u8fc7<code>create<\/code>\u5206\u914d\u5230\u4e86\u4e00\u4e2a\u4e0a\u9501\u7684iNode\u4e4b\u540e\uff0c\u8fd8\u662f\u53d1\u73b0\u8fd9\u4e2aiNode\u6ca1\u6709\u5206\u914d\u6570\u636e\u5757\uff0c\u4f46\u662f\u4f60\u53c8\u4e00\u6b21\u7684\u5c1d\u8bd5\u4e86\u4f7f\u7528\u4e86balloc\u5206\u914d\u4e00\u4e2a\u6570\u636e\u5757\uff0c\u800c\u4e14\u60f3\u7528bread\u6765\u8bfb\u8fd9\u4e2a\u6570\u636e\u5757\u3002\u4f46\u662f\uff0c\u4e24\u4e2a\u95ee\u9898\uff0c\u7b2c\u4e00\uff0cballoc\u51fd\u6570\u4f60\u8fd8\u662f\u65e0\u6cd5\u4f7f\u7528\uff1b\u7b2c\u4e8c\uff0cbread\u8fd4\u56de\u7684buf\u7ed3\u6784\u4f53\u4e0d\u77e5\u9053\u4e3a\u5565\u5728\u7cfb\u7edf\u8c03\u7528\u91cc\u4e0d\u80fd\u4f7f\u7528\u4e86\u3002<strong>Compile Error<\/strong><\/p>\n<p>\u518d\u6b21\u901a\u8fc7<strong>RTFSC<\/strong>\u6cd5\u5219\u53d1\u73b0\uff0c<code>fs.c<\/code>\u4e2d\u7684<code>writei<\/code>\u51fd\u6570\u652f\u6301\u4f60\u5411iNode\u4e2d\u5199\u5165\u4fe1\u606f\uff0c\u800c\u4e14\u7cfb\u7edf\u8c03\u7528\u53ef\u4ee5\u6b63\u5e38\u7684\u8c03\u7528\uff0c\u6240\u4ee5\u95ee\u9898\u89e3\u51b3\u5566\u3002<\/p>\n<p>\u770b\u770b<code>writei<\/code>\u51fd\u6570\uff1a<\/p>\n<pre><code class=\"language-C\">\/\/ Write data to inode.\n\/\/ Caller must hold ip-&gt;lock.\n\/\/ If user_src==1, then src is a user virtual address;\n\/\/ otherwise, src is a kernel address.\n\/\/ Returns the number of bytes successfully written.\n\/\/ If the return value is less than the requested n,\n\/\/ there was an error of some kind.\nint\nwritei(struct inode *ip, int user_src, uint64 src, uint off, uint n)<\/code><\/pre>\n<p>\u901a\u8fc7\u8fd9\u4e2a\u6ce8\u91ca\u63cf\u8ff0\uff0c\u5c31\u53ef\u4ee5\u77e5\u9053\u8fd9\u4e2a\u51fd\u6570\u7684\u7528\u6cd5\u4e86\u3002off\u662f\u6307\u5728iNode\u4e2d\u504f\u79fb\u591a\u5c11\u7684\u4f4d\u7f6e\u5f00\u59cb\u5199\u5165\u6570\u636e\u3002\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u5c31\u5e0c\u671b\u5728\u504f\u79fb\u91cf\u4e3a0\uff0c\u5373\u4ece\u5934\u5f00\u59cb\u5199\u5165\u6570\u636e\u3002<\/p>\n<h4>2.1.4 \u4ee3\u7801<\/h4>\n<pre><code class=\"language-C\">uint64\nsys_symlink(void)\n{\n  char target[MAXPATH], path[MAXPATH];\n\n  struct inode *ip;\n\n  if(argstr(0, target, MAXPATH) &lt; 0 || argstr(1, path, MAXPATH) &lt; 0)\n    return -1;\n\n  if (namei(path) != 0) {\n    return -1;\n  }\n\n  begin_op();\n  if ((ip = create(path, T_SYMLINK, 0, 0)) == 0) {\n    end_op();\n    return -1;\n  }\n\n  if (writei(ip, 0, (uint64)target, 0, MAXPATH) &lt; 0) {\n    ip-&gt;nlink = 0;\n    iupdate(ip);\n    iunlockput(ip);\n    end_op();\n    return -1;\n  }\n  iunlockput(ip);\n  end_op();\n\n  return 0;\n}<\/code><\/pre>\n<h3>2.2 \u4fee\u6539sys_open<\/h3>\n<blockquote>\n<p>\u5728\u4e4b\u524d\u7684open\u7cfb\u7edf\u8c03\u7528\u4e2d\uff0c\u5e76\u6ca1\u6709\u652f\u6301\u5bf9inode\u7c7b\u578b\u4e3a<code>T_SYMLINK<\/code>\u7684\u652f\u6301\uff0c\u4fee\u6539sys_open\uff0c\u4ee5\u652f\u6301symlink\u3002<\/p>\n<\/blockquote>\n<h4>2.2.1 O_NOFOLLOW<\/h4>\n<p>\u76f2\u731c\uff0co_nofollow\u5728unix\u4e0a\u4e5f\u6709\uff0c\u4e14\u4e5f\u5728open\u8c03\u7528\u4e2d\u4f7f\u7528\uff0c\u4e8e\u662f\u6211\u4eec<code>man open<\/code>\u6765\u770b\u770b\u6587\u6863\u3002<\/p>\n<p>\u6587\u6863\u4e2d\u5bf9<code>O_NOFOLLOW<\/code>\u7684\u63cf\u8ff0\u5982\u4e0b\uff1a<\/p>\n<pre><code>O_NOFOLLOW\nIf  pathname is a symbolic link, then the open fails, with the error ELOOP.  Symbolic links in earlier components of the pathname will still be followed.  (Note that the\nELOOP error that can occur in this case is indistinguishable from the case where an open fails because there are too many symbolic links found while resolving components\nin the prefix part of the pathname.)\n\nThis flag is a FreeBSD extension, which was added to Linux in version 2.1.126, and has subsequently been standardized in POSIX.1-2008.<\/code><\/pre>\n<p>\u6587\u6863\u4e2d\u63cf\u8ff0\u7684\u610f\u601d\u662f\uff0c\u5982\u679c\u8fd9\u4e2a\u6807\u7b7e\u88ab\u8bbe\u7f6e\uff0c\u5219\u8def\u5f84\u662f\u4e00\u4e2a\u8f6f\u94fe\u63a5\u7684\u8bdd\uff0c\u5c31\u6253\u5f00\u9519\u8bef\u3002<\/p>\n<p><strong>\u4f46\u662f\u5728\u9898\u76ee\u4e2d\u7684hints\u4e2d\uff0c\u8be5\u6807\u7b7e\u7684\u610f\u601d\u662f\uff0c\u76f4\u63a5\u8fd4\u56de\u8fd9\u4e2a\u8f6f\u94fe\u63a5\u5373\u53ef\uff0c\u6240\u4ee5\u6211\u4eec\u53ea\u80fd\u6309\u7167\u5b9e\u9a8c\u7684\u610f\u601d\u5199\u4e86\u3002<\/strong><\/p>\n<h4>2.2.2 \u5b9e\u73b0O_NOFOLLOW<\/h4>\n<p>\u5f53\u7cfb\u7edf\u8c03\u7528\u5224\u65ad\u4e86\u6ca1\u6709\u521b\u5efa\u6807\u8bb0\u65f6\uff0c\u4e14\u540c\u65f6\u6253\u5f00\u4e86\u8def\u5f84\u5bf9\u5e94\u7684inode\u65f6\u5019(sysfile.c: 335)\uff0c\u6211\u4eec\u5224\u65ad\u8be5inode\u662f\u4e0d\u662f\u4e00\u4e2a\u8f6f\u94fe\u63a5\u3002\u5982\u679c\u662f\u8f6f\u94fe\u63a5\uff0c\u6211\u4eec\u8fdb\u884c\u4ee5\u4e0b\u5904\u7406\uff1a<\/p>\n<p>\u5224\u65ad\u662f\u5426\u6709<code>O_NOFOLLOW<\/code>\u6807\u8bb0\uff0c\u5982\u679c\u6709\uff0c\u76f4\u63a5\u8fd4\u56de\u8fd9\u4e2a\u8f6f\u6807\u8bb0\u3002<\/p>\n<p>\u5982\u679c\u6709\u8be5\u6807\u8bb0\uff0c\u6253\u5f00\u8f6f\u94fe\u63a5\u4e2dtarget\uff0c\u5982\u679ctarget\u4e5f\u662f\u4e00\u4e2a\u8f6f\u94fe\u63a5\uff0c\u91cd\u590d\u8be5\u64cd\u4f5c\uff0c\u76f4\u5230\u94fe\u63a5\u5230\u4e00\u4e2a\u975e\u8f6f\u94fe\u63a5\u7684inode\u3002<\/p>\n<p><strong>\u6309\u7167hints\uff0c\u5982\u679c\u8f6f\u94fe\u63a5\u523010\u6b21\uff0c\u5219\u8fd4\u56de\u9519\u8bef<\/strong><\/p>\n<h4>2.2.4 \u4ee3\u7801<\/h4>\n<pre><code class=\"language-C\">uint64\nsys_open(void)\n{\n  char path[MAXPATH];\n  int fd, omode;\n  struct file *f;\n  struct inode *ip;\n  int n;\n\n  argint(1, &amp;omode);\n  if((n = argstr(0, path, MAXPATH)) &lt; 0)\n    return -1;\n\n  begin_op();\n\n  if(omode &amp; O_CREATE){\n    ip = create(path, T_FILE, 0, 0);\n    if(ip == 0){\n      end_op();\n      return -1;\n    }\n  } else {\n    if((ip = namei(path)) == 0){\n      end_op();\n      return -1;\n    }\n    ilock(ip);\n    if(ip-&gt;type == T_DIR &amp;&amp; omode != O_RDONLY){\n      iunlockput(ip);\n      end_op();\n      return -1;\n    }\n\n      \/\/ change here\n    if (ip-&gt;type == T_SYMLINK) {\n      if (!(omode &amp; O_NOFOLLOW)) {\n        int deep = 0;\n\n        while (1) {\n          deep++;\n\n          if (deep == 10) {\n            iunlockput(ip);\n            end_op();\n            return -1;\n          }\n\n          if (readi(ip, 0, (uint64)path, 0, MAXPATH) &lt; 0) {\n            iunlockput(ip);\n            end_op();\n            return -1;\n          }\n          iunlockput(ip);\n\n          if ((ip = namei(path)) == 0) {\n            end_op();\n            return -1;\n          }\n\n          ilock(ip);\n          if (ip-&gt;type != T_SYMLINK) {\n            break;\n          }\n        }\n      }\n    }\n\n      \/\/ end here\n  }\n\n  if(ip-&gt;type == T_DEVICE &amp;&amp; (ip-&gt;major &lt; 0 || ip-&gt;major &gt;= NDEV)){\n    iunlockput(ip);\n    end_op();\n    return -1;\n  }\n\n  if((f = filealloc()) == 0 || (fd = fdalloc(f)) &lt; 0){\n    if(f)\n      fileclose(f);\n    iunlockput(ip);\n    end_op();\n    return -1;\n  }\n\n  if(ip-&gt;type == T_DEVICE){\n    f-&gt;type = FD_DEVICE;\n    f-&gt;major = ip-&gt;major;\n  } else {\n    f-&gt;type = FD_INODE;\n    f-&gt;off = 0;\n  }\n  f-&gt;ip = ip;\n  f-&gt;readable = !(omode &amp; O_WRONLY);\n  f-&gt;writable = (omode &amp; O_WRONLY) || (omode &amp; O_RDWR);\n\n  if((omode &amp; O_TRUNC) &amp;&amp; ip-&gt;type == T_FILE){\n    itrunc(ip);\n  }\n\n  iunlock(ip);\n  end_op();\n\n  return fd;\n}<\/code><\/pre>\n<p>\u5176\u5b9e\u8fd9\u4e2a\u5b9e\u9a8c\u6ca1\u6709\u8003\u8651\u592a\u591a\u7684\u7ec6\u8282\uff0c\u672c\u6765\u60f3\u770b\u770b\u7f16\u8bd1\u80fd\u4e0d\u80fd\u8fc7\uff0c\u7ed3\u679c\u76f4\u63a5\u628a\u6d4b\u8bd5\u8fc7\u4e86\uff0c\u6bd4\u8f83\u610f\u5916\u3002<\/p>\n<h2>3 END<\/h2>\n<p>\u610f\u5916\u7684\u7ed3\u675f\u4e86\u5b9e\u9a8c\uff0c\u6d4b\u8bd5\u7ed3\u679c\u5982\u4e0b\uff1a<\/p>\n<pre><code>== Test running bigfile ==\n$ make qemu-gdb\nrunning bigfile: OK (133.9s)\n== Test running symlinktest ==\n$ make qemu-gdb\n(0.9s)\n== Test   symlinktest: symlinks ==\n  symlinktest: symlinks: OK\n== Test   symlinktest: concurrent symlinks ==\n  symlinktest: concurrent symlinks: OK\n== Test usertests ==\n$ make qemu-gdb\nusertests: OK (218.3s)\n== Test time ==\ntime: OK\nScore: 100\/100<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>xv6\u64cd\u4f5c\u7cfb\u7edf\u5b9e\u9a8c9\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[14],"class_list":["post-62","post","type-post","status-publish","format-standard","hentry","category-os","tag-xv6"],"_links":{"self":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/posts\/62","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/comments?post=62"}],"version-history":[{"count":0,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/posts\/62\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/media?parent=62"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/categories?post=62"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/tags?post=62"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}