24.01.2014 Views

Codice

Codice

Codice

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

210 volume VI os16<br />

Script e sorgenti del kernel 211<br />

590048 | //<br />

590049 | // Found a free element: change the map to<br />

590050 | // allocate the inode.<br />

590051 | //<br />

590052 | sb->map_inode[map_element] |= map_mask;<br />

590053 | sb->changed = 1;<br />

590054 | ino = m; // Found a free inode:<br />

590055 | break; // exit the scan loop.<br />

590056 | }<br />

590057 | }<br />

590058 | //<br />

590059 | // Check if the scan was successful.<br />

590060 | //<br />

590061 | if (ino == 0)<br />

590062 | {<br />

590063 | errset (ENOSPC); // No space left on device.<br />

590064 | return (NULL);<br />

590065 | }<br />

590066 | //<br />

590067 | // The inode was allocated inside the map in memory.<br />

590068 | //<br />

590069 | inode = inode_get (device, ino);<br />

590070 | if (inode == NULL)<br />

590071 | {<br />

590072 | errset (ENFILE); // Too many files open in system.<br />

590073 | return (NULL);<br />

590074 | }<br />

590075 | //<br />

590076 | // Verify if the inode is really free: if it isn’t, must save<br />

590077 | // it to disk.<br />

590078 | //<br />

590079 | if (inode->size > 0 || inode->links > 0)<br />

590080 | {<br />

590081 | //<br />

590082 | // Strange: should not have a size! Check if there are even<br />

590083 | // links. Please note that 255 links (that is -1) is to be<br />

590084 | // considered a free inode, marked in a special way for some<br />

590085 | // unknown reason. Currently, ‘LINK_MAX’ is equal to 254,<br />

590086 | // for that reason.<br />

590087 | //<br />

590088 | if (inode->links > 0 && inode->links < LINK_MAX)<br />

590089 | {<br />

590090 | //<br />

590091 | // Tell something.<br />

590092 | //<br />

590093 | k_printf ("kernel alert: device %04x: "<br />

590094 | "found \"free\" inode %i "<br />

590095 | "that still has size %i "<br />

590096 | "and %i links!\n",<br />

590097 | device, ino, inode->size, inode->links);<br />

590098 | //<br />

590099 | // The inode must be set again to free, inside<br />

590100 | // the bit map.<br />

590101 | //<br />

590102 | map_element = ino / 16;<br />

590103 | map_bit = ino % 16;<br />

590104 | map_mask = 1 map_inode[map_element] &= ~map_mask;<br />

590106 | sb->changed = 1;<br />

590107 | //<br />

590108 | // Try to fix: reset all to zero.<br />

590109 | //<br />

590110 | inode->mode = 0;<br />

590111 | inode->uid = 0;<br />

590112 | inode->gid = 0;<br />

590113 | inode->time = 0;<br />

590114 | inode->links = 0;<br />

590115 | inode->size = 0;<br />

590116 | inode->direct[0] = 0;<br />

590117 | inode->direct[1] = 0;<br />

590118 | inode->direct[2] = 0;<br />

590119 | inode->direct[3] = 0;<br />

590120 | inode->direct[4] = 0;<br />

590121 | inode->direct[5] = 0;<br />

590122 | inode->direct[6] = 0;<br />

590123 | inode->indirect1 = 0;<br />

590124 | inode->indirect2 = 0;<br />

590125 | inode->changed = 1;<br />

590126 | //<br />

590127 | // Save fixed inode to disk.<br />

590128 | //<br />

590129 | inode_put (inode);<br />

590130 | continue;<br />

590131 | }<br />

590132 | else<br />

590133 | {<br />

590134 | //<br />

590135 | // Truncate the inode, save and break.<br />

590136 | //<br />

590137 | inode_truncate (inode);<br />

590138 | inode_save (inode);<br />

590139 | break;<br />

590140 | }<br />

590141 | }<br />

590142 | else<br />

590143 | {<br />

590144 | //<br />

590145 | // Considering free the inode found.<br />

590146 | //<br />

590147 | break;<br />

590148 | }<br />

590149 | }<br />

590150 | //<br />

590151 | // Put data inside the inode.<br />

590152 | //<br />

590153 | inode->mode = mode;<br />

590154 | inode->uid = uid;<br />

590155 | inode->gid = 0;<br />

590156 | inode->size = 0;<br />

590157 | inode->time = k_time (NULL);<br />

590158 | inode->links = 0;<br />

590159 | inode->changed = 1;<br />

590160 | //<br />

590161 | // Save the inode.<br />

590162 | //<br />

590163 | inode_save (inode);<br />

590164 | //<br />

590165 | // Return the inode pointer.<br />

590166 | //<br />

590167 | return (inode);<br />

590168 |}<br />

104.4.17 kernel/fs/inode_check.c<br />

Si veda la sezione 103.3.16.<br />

600001 |#include <br />

600002 |#include <br />

600003 |#include <br />

600004 |//----------------------------------------------------------------------<br />

600005 |int<br />

600006 |inode_check (inode_t *inode, mode_t type, int perm, uid_t uid)<br />

600007 |{<br />

600008 | //<br />

600009 | // Ensure that the variable ‘type’ has only the requested file type.<br />

600010 | //<br />

600011 | type = (type & S_IFMT);<br />

600012 | //<br />

600013 | // Check inode argument.<br />

600014 | //<br />

600015 | if (inode == NULL)<br />

600016 | {<br />

600017 | errset (EINVAL); // Invalid argument.<br />

600018 | return (-1);<br />

600019 | }<br />

600020 | //<br />

600021 | // The inode is not NULL: verify that the inode is of a type<br />

600022 | // allowed (the parameter ‘type’ can hold more than one<br />

600023 | // possibility).<br />

600024 | //<br />

600025 | if (!(inode->mode & type))<br />

600026 | {<br />

600027 | errset (E_FILE_TYPE); // The file type is not<br />

600028 | return (-1); // the expected one.<br />

600029 | }<br />

600030 | //<br />

600031 | // The file type is correct.<br />

600032 | //<br />

600033 | if (inode->uid != 0 && uid == 0)<br />

600034 | {<br />

600035 | return (0); // The root user has all permissions.<br />

600036 | }<br />

600037 | //<br />

600038 | // The user is not root or the inode is owned by root.<br />

600039 | //<br />

600040 | if (inode->uid == uid)<br />

600041 | {<br />

600042 | //<br />

600043 | // The user own the inode and must check user permissions.<br />

600044 | //<br />

600045 | perm = (perm mode & perm) ^ perm)<br />

600047 | {<br />

600048 | errset (EACCES); // Permission denied.<br />

600049 | return (-1);<br />

600050 | }<br />

600051 | else<br />

600052 | {<br />

600053 | return (0);<br />

600054 | }<br />

600055 | }<br />

600056 | //<br />

600057 | // The user does not own the inode: the other permissions are<br />

600058 | // checked.<br />

600059 | //<br />

600060 | if ((inode->mode & perm) ^ perm)<br />

600061 | {<br />

600062 | errset (EACCES); // Permission denied.<br />

600063 | return (-1);<br />

600064 | }<br />

600065 | else<br />

600066 | {<br />

600067 | return (0);<br />

600068 | }<br />

600069 |}<br />

104.4.18 kernel/fs/inode_dir_empty.c<br />

Si veda la sezione 103.3.17.<br />

610001 |#include <br />

610002 |#include <br />

610003 |#include <br />

610004 |//----------------------------------------------------------------------<br />

610005 |int<br />

610006 |inode_dir_empty (inode_t *inode)<br />

610007 |{<br />

610008 | off_t start;<br />

610009 | char buffer[SB_MAX_ZONE_SIZE];<br />

610010 | directory_t *dir;<br />

610011 | ssize_t size_read;<br />

610012 | int d; // Directory buffer index.<br />

610013 | //<br />

610014 | // Check argument: must be a directory.<br />

610015 | //<br />

610016 | if (inode == NULL || !S_ISDIR (inode->mode))<br />

610017 | {<br />

610018 | errset (EINVAL); // Invalid argument.<br />

610019 | return (0); // false<br />

610020 | }<br />

610021 | //<br />

610022 | // Read the directory content: if an item is present (except ‘.’ and<br />

610023 | // ‘..’), the directory is not empty.<br />

610024 | //<br />

610025 | for (start = 0;<br />

610026 | start < inode->size;<br />

610027 | start += inode->sb->blksize)<br />

610028 | {<br />

610029 | size_read = inode_file_read (inode, start, buffer,<br />

610030 | inode->sb->blksize,<br />

«<br />

«

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!