Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- +----------------------------------------------------------+
- | +------------------------------------------------------+ |
- | | Quafios Kernel 1.0.1. | |
- | | -> Temporary Filesystem Driver. | |
- | +------------------------------------------------------+ |
- +----------------------------------------------------------+
- */
- // This file is part of Quafios 1.0.1 source code.
- // Copyright (C) 2012 Mostafa Abd El-Aziz Mohamed.
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License
- // along with Quafios. If not, see <http://www.gnu.org/licenses/>.
- // Visit http://www.quafios.com/ for contact information.
- /* ======================================================================================
- tmpfs structures
- ====================================================================================== */
- // Data:
- // -------
- #define BLOCK_SIZE (4*1024) // 4 KB.
- typedef struct tmpfs_block_str {
- struct block_str *next;
- unsigned int size;
- char *data;
- } __attribute__((packed)) tmpfs_block;
- typedef struct tmpfs_blocklist_str {
- tmpfs_block *fist;
- tmpfs_block *last;
- unsigned int count;
- } tmpfs_blocklist;
- // Nodes:
- // -------
- typedef struct tmpfs_nodelist_str {
- struct tmpfs_node_str *first;
- struct tmpfs_node_str *last;
- unsigned int count;
- } tmpfs_nodelist;
- typedef struct tmpfs_node_str {
- struct tmpfs_node_str *next;
- char *name;
- mode_t mode;
- unsigned long long size;
- struct tmpfs_nodelist_str sub;
- tmpfs_blocklist blocks;
- } tmpfs_node;
- // Instances:
- // -----------
- tmpfs_node *tmpfs_rootdir[1000] = {0};
- path_t *tmpfs_mntpoint[1000];
- /* ======================================================================================
- Nodal Analysis
- ====================================================================================== */
- tmpfs_node *tmpfs_getnod(tmpfs_node *parent, char *path) {
- if (!path[0]) return parent;
- tmpfs_node *cnode = parent->sub.first; // sub directories.
- // Loop on all sub directories:
- while (cnode != (tmpfs_node *) NULLNODE) {
- // check name:
- unsigned int i = 0;
- char *name1 = &path[1]; // skip '/'.
- char *name2 = cnode->name;
- // loop on characters (compare name1 with name2)
- while (name1[i] && name1[i] != '/' && name2[i] && name1[i] == name2[i]) i++;
- // check comparison results:
- if (((!name1[i]) || name1[i] == '/') && (!name2[i])) {
- if (name1[i] == '/' && (cnode->mode & 0xF000) != MODE_TYPE_DIR)
- break; // not dir.
- return tmpfs_getnod(cnode, &name1[i]);
- }
- cnode = cnode->next;
- }
- // not found:
- return (tmpfs_node *) NULLNODE;
- }
- int tmpfs_mknod(unsigned int subid, char *path, unsigned int psize, mode_t mode, void *data) {
- tmpfs_node *rootdir = tmpfs_rootdir[subid];
- if (rootdir == (tmpfs_node *) 0) return -1;
- // 1- check if "path" already exists:
- if (tmpfs_getnod(rootdir, path) != (tmpfs_node *) NULLNODE)
- return -1; // file exists.
- // 2- Get parent:
- unsigned int i = psize;
- while(path[--i] != '/'); // make path[i] refers to the end of parent path.
- path[i] = 0;
- tmpfs_node *parent = tmpfs_getnod(rootdir, path);
- path[i] = '/';
- if (parent == (tmpfs_node *) NULLNODE) return -1; // invalid path.
- if ((parent->mode & 0xF000) != MODE_TYPE_DIR) return -1; // parent not directory.
- // 3- make node:
- tmpfs_node *nnode = (tmpfs_node *) kmalloc(sizeof(tmpfs_node));
- unsigned int namesize = psize - i; // with \0 in account.
- nnode->name = (char *) kmalloc(namesize);
- for (unsigned int j = 0; j < namesize; j++) nnode->name[j] = path[++i];
- nnode->mode = mode;
- nnode->size = 0;
- linkedlist_init((linkedlist *) &(nnode->sub));
- linkedlist_init((linkedlist *) &(nnode->blocks));
- // 4- add the node to the parent directory:
- linkedlist_add((linkedlist *) &(parent->sub), (linknode *) nnode);
- // 5- return:
- return 0;
- }
- void tmpfs_ls(int i, char *path) {
- tmpfs_node *rootdir = tmpfs_rootdir[i];
- printk("$ ls %s\n", path);
- tmpfs_node *x = tmpfs_getnod(rootdir, path);
- if (x == (tmpfs_node *) NULLNODE) {
- printk("No such file or directory.\n\n");
- return;
- }
- x = x->sub.first;
- while (x != (tmpfs_node *) NULLNODE) {
- unsigned char u = (x->mode & 0x000F) >> 0;
- unsigned char g = (x->mode & 0x00F0) >> 4;
- unsigned char o = (x->mode & 0x0F00) >> 8;
- unsigned char t = (x->mode & 0xF000) >>12;
- printk("%c", "-dlm"[t]);
- printk("%c%c%c", "-r"[(u>>0)&1], "-w"[(u>>1)&1], "-x"[(u>>2)&1]);
- printk("%c%c%c", "-r"[(g>>0)&1], "-w"[(g>>1)&1], "-x"[(g>>2)&1]);
- printk("%c%c%c", "-r"[(o>>0)&1], "-w"[(o>>1)&1], "-x"[(o>>2)&1]);
- printk(" %d\t%a%s%a\t\n", (int) x->size, 0x02, x->name, 0x0F);
- x = x->next;
- }
- printk("\n");
- }
- /* =====================================================================================
- Multi-Instance Support
- ===================================================================================== */
- int tmpfs_mkinst(unsigned int inst, mkinst_data *data) {
- // make instance of tmpfs.
- int i;
- // make new instance:
- for (i = 0; i < 100 && (tmpfs_rootdir[i] != (tmpfs_node *) 0); i++)
- if (i == 100) return ENOMEM;
- // Create Root Directory Structure:
- tmpfs_node *rootdir = (tmpfs_node *) kmalloc(sizeof(tmpfs_node));
- if (rootdir == (tmpfs_node *) NULLPTR) return ENOMEM;
- tmpfs_rootdir[i] = rootdir;
- tmpfs_mntpoint[i] = data->mntpoint;
- rootdir->next = (tmpfs_node *) NULLNODE;
- rootdir->name = "";
- rootdir->mode = MODE_TYPE_DIR;
- rootdir->size = 0;
- linkedlist_init((linkedlist *) &rootdir->sub);
- linkedlist_init((linkedlist *) &rootdir->blocks);
- *(data->new_inst) = i;
- return 0;
- };
- int tmpfs_rminst(unsigned int inst, void *data) {
- // Remove root directory structure:
- if (tmpfs_rootdir[inst] != (tmpfs_node *) 0)
- kfree(tmpfs_rootdir[inst]);
- tmpfs_rootdir[inst] = 0;
- tmpfs_mntpoint[inst] = 0;
- return 0;
- }
- /* ======================================================================================
- Main Interface
- ====================================================================================== */
- unsigned int tmpfs_interface(unsigned int cmd, unsigned int inst, void *data) {
- switch (cmd) {
- case FSC_MKINST:
- return tmpfs_mkinst(inst, data);
- break;
- default:
- return EBUSY;
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement