Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
216 volume VI os16<br />
Script e sorgenti del kernel 217<br />
670025 | {<br />
670026 | //<br />
670027 | // The file system root directory inode is not yet loaded:<br />
670028 | // get the first super block.<br />
670029 | //<br />
670030 | sb = sb_reference ((dev_t) 0);<br />
670031 | if (sb == NULL || sb->device == 0)<br />
670032 | {<br />
670033 | //<br />
670034 | // This error should never happen.<br />
670035 | //<br />
670036 | errset (EUNKNOWN); // Unknown error.<br />
670037 | return (NULL);<br />
670038 | }<br />
670039 | //<br />
670040 | // Load the file system root directory inode (recursive<br />
670041 | // call).<br />
670042 | //<br />
670043 | inode = inode_get (sb->device, (ino_t) 1);<br />
670044 | if (inode == NULL)<br />
670045 | {<br />
670046 | //<br />
670047 | // This error should never happen.<br />
670048 | //<br />
670049 | return (NULL);<br />
670050 | }<br />
670051 | //<br />
670052 | // Return the directory inode.<br />
670053 | //<br />
670054 | return (inode);<br />
670055 | }<br />
670056 | else<br />
670057 | {<br />
670058 | //<br />
670059 | // The file system root directory inode is already<br />
670060 | // available.<br />
670061 | //<br />
670062 | if (inode->references >= INODE_MAX_REFERENCES)<br />
670063 | {<br />
670064 | errset (ENFILE); // Too many files open in system.<br />
670065 | return (NULL);<br />
670066 | }<br />
670067 | else<br />
670068 | {<br />
670069 | inode->references++;<br />
670070 | return (inode);<br />
670071 | }<br />
670072 | }<br />
670073 | }<br />
670074 | //<br />
670075 | // A common device-inode pair was requested: try to find an already<br />
670076 | // cached inode.<br />
670077 | //<br />
670078 | inode = inode_reference (device, ino);<br />
670079 | if (inode != NULL)<br />
670080 | {<br />
670081 | if (inode->references >= INODE_MAX_REFERENCES)<br />
670082 | {<br />
670083 | errset (ENFILE); // Too many files open in system.<br />
670084 | return (NULL);<br />
670085 | }<br />
670086 | else<br />
670087 | {<br />
670088 | inode->references++;<br />
670089 | return (inode);<br />
670090 | }<br />
670091 | }<br />
670092 | //<br />
670093 | // The inode is not yet available: get super block.<br />
670094 | //<br />
670095 | sb = sb_reference (device);<br />
670096 | if (sb == NULL)<br />
670097 | {<br />
670098 | errset (ENODEV); // No such device.<br />
670099 | return (NULL);<br />
670100 | }<br />
670101 | //<br />
670102 | // The super block is available, but the inode is not yet cached.<br />
670103 | // Verify if the inode map reports it as allocated.<br />
670104 | //<br />
670105 | status = sb_inode_status (sb, ino);<br />
670106 | if (!status)<br />
670107 | {<br />
670108 | //<br />
670109 | // The inode is not allocated and cannot be loaded.<br />
670110 | //<br />
670111 | errset (ENOENT); // No such file or directory.<br />
670112 | return (NULL);<br />
670113 | }<br />
670114 | //<br />
670115 | // The inode was not already cached, but is considered as allocated<br />
670116 | // inside the inode map. Find a free slot to load the inode inside<br />
670117 | // the inode table (in memory).<br />
670118 | //<br />
670119 | inode = inode_reference ((dev_t) -1, (ino_t) -1);<br />
670120 | if (inode == NULL)<br />
670121 | {<br />
670122 | errset (ENFILE); // Too many files open in system.<br />
670123 | return (NULL);<br />
670124 | }<br />
670125 | //<br />
670126 | // A free inode slot was found. The inode must be loaded.<br />
670127 | // Calculate the memory inode size, to be saved inside the file<br />
670128 | // system: the administrative inode data, as it is saved inside<br />
670129 | // the file system. The ‘inode_t’ type is bigger than the real<br />
670130 | // inode administrative size, because it contains more data, that is<br />
670131 | // not saved on disk.<br />
670132 | //<br />
670133 | size = offsetof (inode_t, sb);<br />
670134 | //<br />
670135 | // Calculating start position for read.<br />
670136 | //<br />
670137 | // [1] Boot block.<br />
670138 | // [2] Super block.<br />
670139 | // [3] Inode bit map.<br />
670140 | // [4] Zone bit map.<br />
670141 | // [5] Previous inodes: consider that the inode zero is<br />
670142 | // present in the inode map, but not in the inode<br />
670143 | // table.<br />
670144 | //<br />
670145 | start = 1024; // [1]<br />
670146 | start += 1024; // [2]<br />
670147 | start += (sb->map_inode_blocks * 1024); // [3]<br />
670148 | start += (sb->map_zone_blocks * 1024); // [4]<br />
670149 | start += ((ino -1) * size); // [5]<br />
670150 | //<br />
670151 | // Read inode from disk.<br />
670152 | //<br />
670153 | n = dev_io ((pid_t) -1, device, DEV_READ, start, inode, size, NULL);<br />
670154 | if (n != size)<br />
670155 | {<br />
670156 | errset (EIO); // I/O error.<br />
670157 | return (NULL);<br />
670158 | }<br />
670159 | //<br />
670160 | // The inode was read: add some data to the working copy in memory.<br />
670161 | //<br />
670162 | inode->sb = sb;<br />
670163 | inode->sb_attached = NULL;<br />
670164 | inode->ino = ino;<br />
670165 | inode->references = 1;<br />
670166 | inode->changed = 0;<br />
670167 | //<br />
670168 | inode->blkcnt = inode->size;<br />
670169 | inode->blkcnt /= sb->blksize;<br />
670170 | if (inode->size % sb->blksize)<br />
670171 | {<br />
670172 | inode->blkcnt++;<br />
670173 | }<br />
670174 | //<br />
670175 | // Return the inode pointer.<br />
670176 | //<br />
670177 | return (inode);<br />
670178 |}<br />
104.4.25 kernel/fs/inode_put.c<br />
Si veda la sezione 103.3.24.<br />
680001 |#include <br />
680002 |#include <br />
680003 |#include <br />
680004 |//----------------------------------------------------------------------<br />
680005 |int<br />
680006 |inode_put (inode_t *inode)<br />
680007 |{<br />
680008 | int status;<br />
680009 | //<br />
680010 | // Check for valid argument.<br />
680011 | //<br />
680012 | if (inode == NULL)<br />
680013 | {<br />
680014 | errset (EINVAL); // Invalid argument.<br />
680015 | return (-1);<br />
680016 | }<br />
680017 | //<br />
680018 | // Check for valid references.<br />
680019 | //<br />
680020 | if (inode->references sb->device == 0 && inode->ino != 0)<br />
680029 | {<br />
680030 | k_printf ("kernel alert: trying to close inode with device "<br />
680031 | "zero, but a number different than zero!\n");<br />
680032 | errset (EUNKNOWN); // Cannot put an inode with<br />
680033 | return (-1); // zero or negative references.<br />
680034 | }<br />
680035 | //<br />
680036 | // There is at least one reference: now the references value is<br />
680037 | // reduced.<br />
680038 | //<br />
680039 | inode->references--;<br />
680040 | inode->changed = 1;<br />
680041 | //<br />
680042 | // If ‘inode->ino’ is zero, it means that the inode was created in<br />
680043 | // memory, but there is no file system for it. For example, it might<br />
680044 | // be a standard I/O inode create automatically for a process.<br />
680045 | // Inodes with number zero cannot be removed from a file system.<br />
680046 | //<br />
680047 | if (inode->ino == 0)<br />
680048 | {<br />
680049 | //<br />
680050 | // Nothing to do: just return.<br />
680051 | //<br />
680052 | return (0);<br />
680053 | }<br />
680054 | //<br />
680055 | // References counter might be zero.<br />
680056 | //<br />
680057 | if (inode->references == 0)<br />
680058 | {<br />
680059 | //<br />
680060 | // Check if the inode is to be deleted (until there are<br />
680061 | // run time references, the inode cannot be removed).<br />
680062 | //<br />
680063 | if (inode->links == 0<br />
680064 | || (S_ISDIR (inode->mode) && inode->links == 1))<br />
680065 | {<br />
680066 | //<br />
680067 | // The inode has no more run time references and file system<br />
680068 | // links are also zero (or one for a directory): remove it!<br />
680069 | //<br />
680070 | status = inode_truncate (inode);<br />
680071 | if (status != 0)<br />
680072 | {<br />
680073 | k_perror (NULL);<br />
«