//insert and uodate an inode to inode cache LRU void set_inodeLRU(int inode_num, inode_cache *i) { inode_cache* n = get_inode(inode_num); if (n!=NULL) { put_inode(inode_num, i); if (n!=last_inode) { if (n==first_inode) first_inode = first_inode->next; else n->prev->next = n->next; n->next->prev = n->prev; last_inode->next = n; n->prev = last_inode; n->next = NULL; last_inode = n; } } else { if (inode_cache_cnt>=INODE_CACHESIZE) { //rm_inode(first_inode->inode_num); sync(); //write back dirty inode to block cache if (first_inode->dirty) { int block_num = inode_to_block(inode_num); block_cache *b = read_block(block_num); int idx = inode_num-(block_num-1)*(BLOCKSIZE/INODESIZE); memcpy((void*)(b->data+idx*INODESIZE),(void*)(&(first_inode->data)),INODESIZE); b->dirty = 1; } rm_inode(first_inode->inode_num); inode_cache *tmp = first_inode; first_inode = first_inode->next; if (first_inode!=NULL) first_inode->prev = NULL; else last_inode = NULL; inode_cache_cnt--; free(tmp); } if (first_inode==NULL || last_inode==NULL) first_inode = i; else last_inode->next = i; i->prev = last_inode; last_inode = i; put_inode(inode_num, i); inode_cache_cnt++; } }
/* remove file/dir from fs */ int fs_unlink(const char *pathname) { struct inode_s *ino, *dir; ino = dir = NULL; dir = current_dir(); if ( (ino = find_inode(dir, pathname, FS_SEARCH_REMOVE)) == NULL) goto err; rm_inode(ino->i_num); release_inode(dir); release_inode(ino); return OK; err: release_inode(dir); release_inode(ino); return ERROR; }
/* remove directory (only if it is empty) */ int fs_rmdir(const char *pathname) { struct inode_s *ino, *dir, *tmpdir; char path[MAX_PATH], name[MAX_NAME]; ino = dir = tmpdir = NULL; process_path(pathname, path, name); tmpdir = current_dir(); /* get inode numbers from parent and new dir */ if ( (dir = find_inode(tmpdir, path, FS_SEARCH_GET)) == NULL) goto err; release_inode(tmpdir); if ( (ino = find_inode(dir, name, FS_SEARCH_ADD)) == NULL) goto err; /* check if its a dir and it is empty */ if (!IS_DIR(ino->i_mode) || ino->i_size != DIRENTRY_SIZE * 2) goto err; /* this cant give an error */ release_inode(find_inode(dir, name, FS_SEARCH_REMOVE)); /* free blocks and inode */ rm_inode(ino->i_num); release_inode(dir); release_inode(ino); return OK; err: release_inode(tmpdir); release_inode(dir); release_inode(ino); return ERROR; }