int fs_rmdir(const char *path) { struct inode *dir; struct dirent *dent; uint32_t nblock, i, j; char *blk; int r; if ((r = inode_open(path, &dir)) < 0) return r; if (dir == diskaddr(super->s_root)) return -EPERM; if (!S_ISDIR(dir->i_mode)) return -ENOTDIR; nblock = dir->i_size / BLKSIZE; for (i = 0; i < nblock; i++) { if ((r = inode_get_block(dir, i, &blk)) < 0) return r; dent = (struct dirent *)blk; for (j = 0; j < BLKDIRENTS; ++j) if (dent[j].d_name[0] != '\0') return -ENOTEMPTY; } return inode_unlink(path); }
// Writes an inode to disk. static void inode_write(unsigned int inode_n, inode * n){ unsigned int locin_block_index = inode_get_block_index(inode_n); unsigned int real_block_index = inode_get_block(inode_n); block b; block_clear(&b); block_read((void *)&b, real_block_index); inode * inodes = (inode *) &b; int i = 0; for (; i < FS_INODE_SIZE / sizeof(int); i++) { ((int *)&inodes[locin_block_index])[i] = ((int*)n)[i]; } block_write((void *)&b, real_block_index); }
int fs_readlink(const char *path, char *target, size_t len) { struct inode *ino; size_t copylen; char *blk; int r; if ((r = inode_open(path, &ino)) < 0) return r; if ((r = inode_get_block(ino, 0, &blk)) < 0) return r; copylen = MIN(ino->i_size, len - 1); memcpy(target, blk, copylen); target[copylen] = '\0'; return 0; }
int fs_symlink(const char *dstpath, const char *srcpath) { struct inode *ino; struct fuse_context *ctxt; time_t curtime; size_t dstlen; char *blk; int r; if ((dstlen = strlen(dstpath)) >= PATH_MAX) return -ENAMETOOLONG; if ((r = inode_create(srcpath, &ino)) < 0) { return r; } ino->i_size = dstlen; ino->i_mode = S_IFLNK | 0777; ino->i_nlink = 1; curtime = time(NULL); ino->i_atime = curtime; ino->i_ctime = curtime; ino->i_mtime = curtime; ctxt = fuse_get_context(); ino->i_owner = ctxt->uid; ino->i_group = ctxt->gid; if ((r = inode_get_block(ino, 0, &blk)) < 0) { inode_unlink(srcpath); return r; } memcpy(blk, dstpath, dstlen); inode_flush(ino); return 0; }
void fs_test(void) { struct inode *ino, *ino2; int r; char *blk; uint32_t bits[4096]; // back up bitmap memmove(bits, bitmap, 4096); // allocate block if ((r = alloc_block()) < 0) panic("alloc_block: %s", strerror(-r)); // check that block was free assert(bits[r/32] & (1 << (r%32))); // and is not free any more assert(!(bitmap[r/32] & (1 << (r%32)))); free_block(r); printf("alloc_block is good\n"); if ((r = inode_open("/not-found", &ino)) < 0 && r != -ENOENT) panic("inode_open /not-found: %s", strerror(-r)); else if (r == 0) panic("inode_open /not-found succeeded!"); if ((r = inode_open("/msg", &ino)) < 0) panic("inode_open /msg: %s", strerror(-r)); printf("inode_open is good\n"); if ((r = inode_get_block(ino, 0, &blk)) < 0) panic("inode_get_block: %s", strerror(-r)); if (strcmp(blk, msg) != 0) panic("inode_get_block returned wrong data"); printf("inode_get_block is good\n"); if ((r = inode_set_size(ino, 0)) < 0) panic("inode_set_size: %s", strerror(-r)); assert(ino->i_direct[0] == 0); printf("inode_truncate is good\n"); if ((r = inode_set_size(ino, strlen(msg))) < 0) panic("inode_set_size 2: %s", strerror(-r)); if ((r = inode_get_block(ino, 0, &blk)) < 0) panic("inode_get_block 2: %s", strerror(-r)); strcpy(blk, msg); printf("file rewrite is good\n"); if ((r = inode_link("/msg", "/linkmsg")) < 0) panic("inode_link /msg /linkmsg: %s", strerror(-r)); if ((r = inode_open("/msg", &ino)) < 0) panic("inode_open /msg: %s", strerror(-r)); if ((r = inode_open("/linkmsg", &ino2)) < 0) panic("inode_open /linkmsg: %s", strerror(-r)); if (ino != ino2) panic("linked files do not point to same inode"); if (ino->i_nlink != 2) panic("link count incorrect: %u, expected 2", ino->i_nlink); printf("inode_link is good\n"); if ((r = inode_unlink("/linkmsg")) < 0) panic("inode_unlink /linkmsg: %s", strerror(-r)); if ((r = inode_open("/linkmsg", &ino2)) < 0 && r != -ENOENT) panic("inode_open /linkmsg after unlink: %s", strerror(-r)); else if (r == 0) panic("inode_open /linkmsg after unlink succeeded!"); if ((r = inode_open("/msg", &ino)) < 0) panic("inode_open /msg after /linkmsg unlinked: %s", strerror(-r)); if (ino->i_nlink != 1) panic("link count incorrect: %u, expected 1", ino->i_nlink); printf("inode_unlink is good\n"); }