ShingledFS 2.0
SMR-AwareFUSE-basedFileSystem
|
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 }