24.01.2014 Views

Codice

Codice

Codice

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

«<br />

236 volume VI os16<br />

104.4.45 kernel/fs/path_umount.c<br />

Si veda la sezione 103.3.41.<br />

880001 |#include <br />

880002 |#include <br />

880003 |#include <br />

880004 |//----------------------------------------------------------------------<br />

880005 |int<br />

880006 |path_umount (pid_t pid, const char *path_mnt)<br />

880007 |{<br />

880008 | proc_t *ps;<br />

880009 | dev_t device; // Device to mount.<br />

880010 | inode_t *inode_mount_point; // Original mount point.<br />

880011 | inode_t *inode; // Inode table.<br />

880012 | int i; // Inode table index.<br />

880013 | //<br />

880014 | // Get process.<br />

880015 | //<br />

880016 | ps = proc_reference (pid);<br />

880017 | //<br />

880018 | // Verify to be the super user.<br />

880019 | //<br />

880020 | if (ps->euid != 0)<br />

880021 | {<br />

880022 | errset (EPERM); // Operation not permitted.<br />

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

880024 | }<br />

880025 | //<br />

880026 | // Get the directory mount point.<br />

880027 | //<br />

880028 | inode_mount_point = path_inode (pid, path_mnt);<br />

880029 | if (inode_mount_point == NULL)<br />

880030 | {<br />

880031 | errset (ENOENT); // No such file or directory.<br />

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

880033 | }<br />

880034 | //<br />

880035 | // Verify that the path is a directory.<br />

880036 | //<br />

880037 | if (!S_ISDIR (inode_mount_point->mode))<br />

880038 | {<br />

880039 | inode_put (inode_mount_point);<br />

880040 | errset (ENOTDIR); // Not a directory.<br />

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

880042 | }<br />

880043 | //<br />

880044 | // Verify that there is something attached.<br />

880045 | //<br />

880046 | device = inode_mount_point->sb_attached->device;<br />

880047 | if (device == 0)<br />

880048 | {<br />

880049 | //<br />

880050 | // There is nothing to unmount.<br />

880051 | //<br />

880052 | inode_put (inode_mount_point);<br />

880053 | errset (E_NOT_MOUNTED); // Not mounted.<br />

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

880055 | }<br />

880056 | //<br />

880057 | // Are there exactly two internal references? Let’s explain:<br />

880058 | // the directory that act as mount point, should have one reference<br />

880059 | // because it is mounting something and another because it was just<br />

880060 | // opened again, a few lines above. If there are more references<br />

880061 | // it is wrong; if there are less, it is also wrong at this point.<br />

880062 | //<br />

880063 | if (inode_mount_point->references != 2)<br />

880064 | {<br />

880065 | inode_put (inode_mount_point);<br />

880066 | errset (EUNKNOWN); // Unknown error.<br />

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

880068 | }<br />

880069 | //<br />

880070 | // All data is available: find if there are open file inside<br />

880071 | // the file system to unmount. But first load the inode table<br />

880072 | // pointer.<br />

880073 | //<br />

880074 | inode = inode_reference ((dev_t) 0, (ino_t) 0);<br />

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

880076 | {<br />

880077 | //<br />

880078 | // This error should not happen.<br />

880079 | //<br />

880080 | inode_put (inode_mount_point);<br />

880081 | errset (EUNKNOWN); // Unknown error.<br />

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

880083 | }<br />

880084 | //<br />

880085 | // Scan the inode table.<br />

880086 | //<br />

880087 | for (i = 0; i < INODE_MAX_SLOTS; i++)<br />

880088 | {<br />

880089 | if (inode[i].sb == inode_mount_point->sb_attached &&<br />

880090 | inode[i].references > 0)<br />

880091 | {<br />

880092 | //<br />

880093 | // At least one file is open inside the super block to<br />

880094 | // release: cannot unmount.<br />

880095 | //<br />

880096 | inode_put (inode_mount_point);<br />

880097 | errset (EBUSY); // Device or resource busy.<br />

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

880099 | }<br />

880100 | }<br />

880101 | //<br />

880102 | // Can unmount: save and remove the super block memory;<br />

880103 | // clear the mount point reference and put inode.<br />

880104 | //<br />

880105 | inode_mount_point->sb_attached->changed = 1;<br />

880106 | sb_save (inode_mount_point->sb_attached);<br />

880107 | //<br />

880108 | inode_mount_point->sb_attached->device = 0;<br />

880109 | inode_mount_point->sb_attached->inode_mounted_on = NULL;<br />

880110 | inode_mount_point->sb_attached->blksize = 0;<br />

880111 | inode_mount_point->sb_attached->options = 0;<br />

880112 | //<br />

880113 | inode_mount_point->sb_attached = NULL;<br />

880114 | inode_mount_point->references = 0;<br />

Script e sorgenti del kernel 237<br />

880115 | inode_put (inode_mount_point);<br />

880116 | //<br />

880117 | inode_put (inode_mount_point);<br />

880118 | //<br />

880119 | return (0);<br />

880120 |}<br />

104.4.46 kernel/fs/path_unlink.c<br />

Si veda la sezione 103.3.44.<br />

890001 |#include <br />

890002 |#include <br />

890003 |#include <br />

890004 |#include <br />

890005 |#include <br />

890006 |//----------------------------------------------------------------------<br />

890007 |int<br />

890008 |path_unlink (pid_t pid, const char *path)<br />

890009 |{<br />

890010 | proc_t *ps;<br />

890011 | inode_t *inode_unlink;<br />

890012 | inode_t *inode_directory;<br />

890013 | char path_unlink[PATH_MAX];<br />

890014 | char path_copy[PATH_MAX];<br />

890015 | char *path_directory;<br />

890016 | char *name_unlink;<br />

890017 | dev_t device;<br />

890018 | off_t start;<br />

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

890020 | directory_t *dir = (directory_t *) buffer;<br />

890021 | int status;<br />

890022 | ssize_t size_read;<br />

890023 | ssize_t size_written;<br />

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

890025 | //<br />

890026 | // Get process.<br />

890027 | //<br />

890028 | ps = proc_reference (pid);<br />

890029 | //<br />

890030 | // Get full paths.<br />

890031 | //<br />

890032 | path_full (path, ps->path_cwd, path_unlink);<br />

890033 | strncpy (path_copy, path_unlink, PATH_MAX);<br />

890034 | path_directory = dirname (path_copy);<br />

890035 | //<br />

890036 | // Get the inode to be unlinked.<br />

890037 | //<br />

890038 | inode_unlink = path_inode (pid, path_unlink);<br />

890039 | if (inode_unlink == NULL)<br />

890040 | {<br />

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

890042 | }<br />

890043 | //<br />

890044 | // If it is a directory, verify that it is empty.<br />

890045 | //<br />

890046 | if (S_ISDIR (inode_unlink->mode))<br />

890047 | {<br />

890048 | if (!inode_dir_empty (inode_unlink))<br />

890049 | {<br />

890050 | inode_put (inode_unlink);<br />

890051 | errset (ENOTEMPTY); // Directory not empty.<br />

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

890053 | }<br />

890054 | }<br />

890055 | //<br />

890056 | // Get the inode of the directory containing it.<br />

890057 | //<br />

890058 | inode_directory = path_inode (pid, path_directory);<br />

890059 | if (inode_directory == NULL)<br />

890060 | {<br />

890061 | inode_put (inode_unlink);<br />

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

890063 | }<br />

890064 | //<br />

890065 | // Check if something is mounted on the directory.<br />

890066 | //<br />

890067 | if (inode_directory->sb_attached != NULL)<br />

890068 | {<br />

890069 | //<br />

890070 | // Must select the right directory.<br />

890071 | //<br />

890072 | device = inode_directory->sb_attached->device;<br />

890073 | inode_put (inode_directory);<br />

890074 | inode_directory = inode_get (device, 1);<br />

890075 | if (inode_directory == NULL)<br />

890076 | {<br />

890077 | inode_put (inode_unlink);<br />

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

890079 | }<br />

890080 | }<br />

890081 | //<br />

890082 | // Check if write is allowed for the file system.<br />

890083 | //<br />

890084 | if (inode_directory->sb->options & MOUNT_RO)<br />

890085 | {<br />

890086 | errset (EROFS); // Read-only file system.<br />

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

890088 | }<br />

890089 | //<br />

890090 | // Verify access permissions for the directory. The number "3" means<br />

890091 | // that the user must have access permission and write permission:<br />

890092 | // "-wx" == 2+1 == 3.<br />

890093 | //<br />

890094 | status = inode_check (inode_directory, S_IFDIR, 3, ps->uid);<br />

890095 | if (status != 0)<br />

890096 | {<br />

890097 | errset (EPERM); // Operation not permitted.<br />

890098 | inode_put (inode_unlink);<br />

890099 | inode_put (inode_directory);<br />

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

890101 | }<br />

890102 | //<br />

890103 | // Get the base name to be unlinked: this will alter the<br />

890104 | // original path.<br />

890105 | //<br />

«

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

Saved successfully!

Ooh no, something went wrong!