ShingledFS 2.0
SMR-AwareFUSE-basedFileSystem

inode.c

Go to the documentation of this file.
00001 
00010 #define _XOPEN_SOURCE 500
00011 #include <unistd.h>
00012 #include <sys/types.h>
00013 #include <sys/stat.h>
00014 #include <fcntl.h>
00015 #include <limits.h>
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include "helper.h"
00019 #include "common.h"
00020 
00021 
00022 #include "inode.h"
00023 
00024 
00025 #define FILE_INODE_BITMAP                               "/.smr_inode_bitmap"
00026 #define FILE_INODE_LIST                                 "/.smr_inode_list"
00027 
00028 static int fd_bitmap;
00029 static int fd_list;
00030 
00031 
00032 
00033 /*
00034  * @brief Fetchs the inode information from the inode file
00035  *
00036  * @param inode_num The INode number
00037  * @param node Pointer to buffer to hold the inode data
00038  *
00039  * @return 0 on success; -1 on error
00040  */
00041 
00042 int get_inode (int inode_num, inode_t *node)
00043 {
00044     int offset;
00045 
00046     if (inode_num <= 0 || node == NULL || fd_list < 0) {
00047         return -1;
00048     }
00049 
00050     offset = get_offset(inode_num);
00051     if (pread(fd_list, node, sizeof(inode_t), offset) < 0) {
00052         dbg("Error reading inode in get_inode \n");
00053         return -1;
00054     }
00055 
00056     return 0;
00057 }
00058 
00059 
00060 
00061 /*
00062  * @brief Writes inode data to the inodes file
00063  *
00064  * @param inode_num The INode number
00065  * @param node Pointer to buffer holding the inode data
00066  *
00067  * @return 0 on success; -1 on error
00068  */
00069 
00070 int put_inode (int inode_num, inode_t *node)
00071 {
00072     int offset;
00073     if (inode_num <= 0 || node == NULL || fd_list < 0) {
00074         return -1;
00075     }
00076 
00077     offset = get_offset(inode_num);
00078     if (pwrite(fd_list, node, sizeof(inode_t), offset) < 0) {
00079         dbg("Error writing inode to inode list in put_inode \n");
00080         return -1;
00081     }
00082 
00083     return 0;
00084 }
00085 
00086 
00087 
00096 int get_offset(int inode_num)
00097 {
00098     return (sizeof(inode_t) * (inode_num - 1));
00099 }
00100 
00101 
00102 
00110 int init_inodebitmap(void)
00111 {
00112     char path[PATH_MAX]; 
00113     int max_inodes;
00114     char bit = 0;
00115     int i;
00116 
00117 
00118     translate_path(FILE_INODE_BITMAP, SFSDATA.path_unshingled, path);
00119 
00120     fd_bitmap = open(path, O_RDWR | O_CREAT | O_EXCL, 0644);
00121 
00122     if (fd_bitmap < 0) {
00123         //inode bitmap already exists.
00124         fd_bitmap = open(path, O_RDWR);
00125         if (fd_bitmap < 0) {
00126             dbg("Error opening inode bitmap file \n");
00127             return -1;
00128         }
00129         return 0;
00130     }
00131 
00132     max_inodes = MAX_NUM_INODES / 8;
00133 
00134     for (i = 0; i < max_inodes; i++) {
00135         if (pwrite(fd_bitmap, &bit, 1, i) < 0) {
00136             dbg("Error writing to inode bitmap in init_inodebitmap \n");
00137             return -1;
00138         }
00139     }
00140 
00141     return 0;
00142 }
00143 
00144 
00158 int init_inodelist(void)
00159 {
00160     char path[PATH_MAX]; 
00161     int max_inodes;
00162     int i;
00163     inode_t node;
00164 
00165 
00166     translate_path(FILE_INODE_LIST, SFSDATA.path_unshingled, path);
00167 
00168     fd_list = open(path, O_RDWR | O_CREAT | O_EXCL, 0644);
00169 
00170     if (fd_list < 0) {
00171         //inode list already exists.
00172         fd_list = open(path, O_RDWR);
00173         if (fd_list < 0) {
00174             dbg("Error opening inode list file \n");
00175             return -1;
00176         }
00177         return 0;
00178     }
00179 
00180     max_inodes = MAX_NUM_INODES / 8;
00181     node.avail = 0;
00182 
00183     for (i = 0; i < max_inodes; i++) {
00184         node.inode_num = i + 1;
00185         if (pwrite(fd_list, &node, sizeof(inode_t),
00186                i * sizeof(inode_t)) < 0) {
00187             return -1;
00188         }
00189     }
00190 
00191     return 0;
00192 }
00193 
00194 
00195 /*
00196  * @brief : Get next free inode and update the inode bitmap.
00197  *
00198  * @param : None.
00199  *
00200  * @return inode number : on Success.
00201  *         0 : if no inodes are free.
00202  *
00203  */
00204 
00205 int get_freeinodenum(void)
00206 {
00207     int i,j;
00208     int max_inodes;
00209     int inode_num = 0;
00210     char bit;
00211 
00212     max_inodes = MAX_NUM_INODES / 8;
00213 
00214     for (i = 0; i < max_inodes; i++) {
00215         if (pread(fd_bitmap, &bit, 1, i) < 0) {
00216             return 0;
00217         }
00218 
00219         if(bit == 0xFF) {
00220             continue;
00221         }
00222 
00223         for (j = 0; j < 8; j++) {
00224 
00225             if ((bit & (1 << j)) == 0) {
00226                 bit = bit | (1 << j);
00227                 if (pwrite(fd_bitmap, &bit, 1, i) < 0) {
00228                     dbg("Error writing to inode bitmap in get_freeinodenum\n");
00229                     exit(1);
00230                 }
00231 
00232                 inode_num = i * 8 + j + 1;
00233                 break;
00234             }
00235         }
00236         if (inode_num != 0) {
00237             break;
00238         }
00239     }
00240 
00241     return inode_num;
00242 
00243 }
00244 
00245 
00246 /*
00247  * @brief : Free the inode by updating the inode bitmap.
00248  *
00249  * @param inode_num : inode number.
00250  *
00251  * @return : None.
00252  *
00253  */
00254 
00255 void put_freeinodenum(int inode_num)
00256 {
00257     int i, j;
00258     char bit;
00259 
00260     if (inode_num <= 0) {
00261         return;
00262     }
00263 
00264     i = (inode_num - 1) / 8;
00265     j = (inode_num - 1) % 8;
00266 
00267 
00268     if (pread(fd_bitmap, &bit, 1, i) < 0) {
00269         dbg("Error reading inode bitmap in put_freeinodenum\n");
00270         exit(1);
00271     }
00272     bit = bit & (~(1 << j));
00273     if (pwrite(fd_bitmap, &bit, 1, i) < 0) {
00274         dbg("Error writing inode bitmap in put_freeinodenum \n");
00275         exit(1);
00276     }
00277 
00278 }