Advertisement
iocoder

tmpfs.c

Nov 23rd, 2012
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.75 KB | None | 0 0
  1. /*
  2.         +----------------------------------------------------------+
  3.         | +------------------------------------------------------+ |
  4.         | |  Quafios Kernel 1.0.1.               | |
  5.         | |  -> Temporary Filesystem Driver.             | |
  6.         | +------------------------------------------------------+ |
  7.         +----------------------------------------------------------+
  8.  
  9. */
  10.  
  11. // This file is part of Quafios 1.0.1 source code.
  12. // Copyright (C) 2012  Mostafa Abd El-Aziz Mohamed.
  13.  
  14. // This program is free software: you can redistribute it and/or modify
  15. // it under the terms of the GNU General Public License as published by
  16. // the Free Software Foundation, either version 3 of the License, or
  17. // (at your option) any later version.
  18.  
  19. // This program is distributed in the hope that it will be useful,
  20. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. // GNU General Public License for more details.
  23.  
  24. // You should have received a copy of the GNU General Public License
  25. // along with Quafios.  If not, see <http://www.gnu.org/licenses/>.
  26.  
  27. // Visit http://www.quafios.com/ for contact information.
  28.  
  29. /* ======================================================================================
  30.                          tmpfs structures                  
  31.    ====================================================================================== */
  32.  
  33. // Data:
  34. // -------
  35. #define BLOCK_SIZE (4*1024) // 4 KB.
  36.  
  37. typedef struct tmpfs_block_str {
  38.     struct block_str *next;
  39.     unsigned int size;
  40.     char *data;
  41. } __attribute__((packed)) tmpfs_block;
  42.  
  43. typedef struct tmpfs_blocklist_str {
  44.     tmpfs_block *fist;
  45.     tmpfs_block *last;
  46.     unsigned int count;
  47. } tmpfs_blocklist;
  48.  
  49. // Nodes:
  50. // -------
  51. typedef struct tmpfs_nodelist_str {
  52.     struct tmpfs_node_str *first;
  53.     struct tmpfs_node_str *last;
  54.     unsigned int count;
  55. } tmpfs_nodelist;
  56.  
  57. typedef struct tmpfs_node_str {
  58.     struct tmpfs_node_str *next;
  59.     char *name;
  60.     mode_t mode;
  61.     unsigned long long size;
  62.     struct tmpfs_nodelist_str sub;
  63.     tmpfs_blocklist blocks;
  64. } tmpfs_node;
  65.  
  66. // Instances:
  67. // -----------
  68. tmpfs_node *tmpfs_rootdir[1000] = {0};
  69. path_t *tmpfs_mntpoint[1000];  
  70.  
  71. /* ======================================================================================
  72.                          Nodal Analysis                
  73.    ====================================================================================== */
  74.  
  75. tmpfs_node *tmpfs_getnod(tmpfs_node *parent, char *path) {
  76.  
  77.     if (!path[0]) return parent;
  78.  
  79.     tmpfs_node *cnode = parent->sub.first; // sub directories.
  80.  
  81.     // Loop on all sub directories:
  82.     while (cnode != (tmpfs_node *) NULLNODE) {
  83.         // check name:
  84.         unsigned int i = 0;
  85.         char *name1 = &path[1]; // skip '/'.
  86.         char *name2 = cnode->name;
  87.  
  88.         // loop on characters (compare name1 with name2)
  89.         while (name1[i] && name1[i] != '/' && name2[i] && name1[i] == name2[i]) i++;
  90.  
  91.         // check comparison results:
  92.         if (((!name1[i]) || name1[i] == '/') && (!name2[i])) {
  93.             if (name1[i] == '/' && (cnode->mode & 0xF000) != MODE_TYPE_DIR)
  94.                     break; // not dir.
  95.             return tmpfs_getnod(cnode, &name1[i]);
  96.         }
  97.  
  98.         cnode = cnode->next;
  99.     }
  100.  
  101.     // not found:
  102.     return (tmpfs_node *) NULLNODE;
  103. }
  104.  
  105. int tmpfs_mknod(unsigned int subid, char *path, unsigned int psize, mode_t mode, void *data) {
  106.  
  107.     tmpfs_node *rootdir = tmpfs_rootdir[subid];
  108.     if (rootdir == (tmpfs_node *) 0) return -1;
  109.  
  110.     // 1- check if "path" already exists:
  111.     if (tmpfs_getnod(rootdir, path) != (tmpfs_node *) NULLNODE)
  112.         return -1; // file exists.
  113.  
  114.     // 2- Get parent:
  115.     unsigned int i = psize;
  116.     while(path[--i] != '/'); // make path[i] refers to the end of parent path.
  117.     path[i] = 0;
  118.     tmpfs_node *parent = tmpfs_getnod(rootdir, path);
  119.     path[i] = '/';
  120.     if (parent == (tmpfs_node *) NULLNODE) return -1; // invalid path.
  121.     if ((parent->mode & 0xF000) != MODE_TYPE_DIR) return -1; // parent not directory.
  122.  
  123.     // 3- make node:
  124.     tmpfs_node *nnode = (tmpfs_node *) kmalloc(sizeof(tmpfs_node));
  125.     unsigned int namesize = psize - i; // with \0 in account.
  126.     nnode->name = (char *) kmalloc(namesize);
  127.     for (unsigned int j = 0; j < namesize; j++) nnode->name[j] = path[++i];
  128.     nnode->mode = mode;
  129.     nnode->size = 0;
  130.     linkedlist_init((linkedlist *) &(nnode->sub));
  131.     linkedlist_init((linkedlist *) &(nnode->blocks));
  132.  
  133.     // 4- add the node to the parent directory:
  134.     linkedlist_add((linkedlist *) &(parent->sub), (linknode *) nnode);
  135.  
  136.     // 5- return:
  137.     return 0;
  138. }
  139.  
  140. void tmpfs_ls(int i, char *path) {
  141.    
  142.     tmpfs_node *rootdir = tmpfs_rootdir[i];
  143.    
  144.     printk("$ ls %s\n", path);
  145.     tmpfs_node *x = tmpfs_getnod(rootdir, path);
  146.     if (x == (tmpfs_node *) NULLNODE) {
  147.         printk("No such file or directory.\n\n");
  148.         return;
  149.     }
  150.     x = x->sub.first;
  151.     while (x != (tmpfs_node *) NULLNODE) {
  152.         unsigned char u = (x->mode & 0x000F) >> 0;
  153.         unsigned char g = (x->mode & 0x00F0) >> 4;
  154.         unsigned char o = (x->mode & 0x0F00) >> 8;
  155.         unsigned char t = (x->mode & 0xF000) >>12;
  156.         printk("%c", "-dlm"[t]);
  157.         printk("%c%c%c", "-r"[(u>>0)&1], "-w"[(u>>1)&1], "-x"[(u>>2)&1]);
  158.         printk("%c%c%c", "-r"[(g>>0)&1], "-w"[(g>>1)&1], "-x"[(g>>2)&1]);
  159.         printk("%c%c%c", "-r"[(o>>0)&1], "-w"[(o>>1)&1], "-x"[(o>>2)&1]);
  160.         printk("  %d\t%a%s%a\t\n", (int) x->size, 0x02, x->name, 0x0F);
  161.         x = x->next;
  162.     }
  163.     printk("\n");
  164. }
  165.  
  166. /* =====================================================================================
  167.                       Multi-Instance Support                   
  168.    ===================================================================================== */
  169.  
  170. int tmpfs_mkinst(unsigned int inst, mkinst_data *data) {
  171.     // make instance of tmpfs.
  172.     int i;
  173.  
  174.     // make new instance:
  175.     for (i = 0; i < 100 && (tmpfs_rootdir[i] != (tmpfs_node *) 0); i++)
  176.     if (i == 100) return ENOMEM;
  177.  
  178.     // Create Root Directory Structure:
  179.     tmpfs_node *rootdir = (tmpfs_node *) kmalloc(sizeof(tmpfs_node));
  180.     if (rootdir == (tmpfs_node *) NULLPTR) return ENOMEM;
  181.  
  182.     tmpfs_rootdir[i]  = rootdir;
  183.     tmpfs_mntpoint[i] = data->mntpoint;
  184.  
  185.     rootdir->next = (tmpfs_node *) NULLNODE;
  186.     rootdir->name = "";
  187.     rootdir->mode = MODE_TYPE_DIR;
  188.     rootdir->size = 0;
  189.  
  190.     linkedlist_init((linkedlist *) &rootdir->sub);
  191.     linkedlist_init((linkedlist *) &rootdir->blocks);
  192.  
  193.     *(data->new_inst) = i;
  194.     return 0;
  195. };
  196.  
  197. int tmpfs_rminst(unsigned int inst, void *data) {
  198.     // Remove root directory structure:
  199.     if (tmpfs_rootdir[inst] != (tmpfs_node *) 0)
  200.         kfree(tmpfs_rootdir[inst]);
  201.     tmpfs_rootdir[inst]  = 0;
  202.     tmpfs_mntpoint[inst] = 0;
  203.     return 0;
  204. }
  205.  
  206. /* ======================================================================================
  207.                          Main Interface                
  208.    ====================================================================================== */
  209.  
  210. unsigned int tmpfs_interface(unsigned int cmd, unsigned int inst, void *data) {
  211.     switch (cmd) {
  212.         case FSC_MKINST:
  213.             return tmpfs_mkinst(inst, data);
  214.             break;
  215.         default:
  216.             return EBUSY;
  217.             break;
  218.     }
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement