/* * This routine tries to find a RAM disk image to load, and returns the * number of blocks to read for a non-compressed image, 0 if the image * is a compressed image, and -1 if an image with the right magic * numbers could not be found. * * We currently check for the following magic numbers: * minix * ext2 * romfs * cramfs * squashfs * gzip */ static int __init identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) { const int size = 512; struct minix_super_block *minixsb; struct ext2_super_block *ext2sb; struct romfs_super_block *romfsb; struct cramfs_super *cramfsb; struct squashfs_super_block *squashfsb; int nblocks = -1; unsigned char *buf; const char *compress_name; buf = kmalloc(size, GFP_KERNEL); if (!buf) return -1; minixsb = (struct minix_super_block *) buf; ext2sb = (struct ext2_super_block *) buf; romfsb = (struct romfs_super_block *) buf; cramfsb = (struct cramfs_super *) buf; squashfsb = (struct squashfs_super_block *) buf; memset(buf, 0xe5, size); /* * Read block 0 to test for compressed kernel */ rd_lseek(fd, start_block * BLOCK_SIZE, 0); rd_read(fd, buf, size); *decompressor = decompress_method(buf, size, &compress_name); if (compress_name) { printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n", compress_name, start_block); if (!*decompressor) printk(KERN_EMERG "RAMDISK: %s decompressor not configured!\n", compress_name); nblocks = 0; goto done; } /* romfs is at block zero too */ if (romfsb->word0 == ROMSB_WORD0 && romfsb->word1 == ROMSB_WORD1) { printk(KERN_NOTICE "RAMDISK: romfs filesystem found at block %d\n", start_block); nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; goto done; }
int main () { int retval, i; int fd; int index_node_number; /* Some arbitrary data for our files */ memset (data1, '1', sizeof (data1)); memset (data2, '2', sizeof (data2)); memset (data3, '3', sizeof (data3)); #ifdef TEST1 /* ****TEST 1: MAXIMUM file creation**** */ /* Assumes the pre-existence of a root directory file "/" that is neither created nor deleted in this test sequence */ /* Generate MAXIMUM regular files */ for (i = 0; i < MAX_FILES + 1; i++) { // go beyond the limit sprintf (pathname, "/file%d", i); retval = rd_creat (pathname); if (retval < 0) { fprintf (stderr, "rd_create: File creation error! status: %d\n", retval); if (i != MAX_FILES) exit (1); } memset (pathname, 0, 80); } /* Delete all the files created */ for (i = 0; i < MAX_FILES; i++) { sprintf (pathname, "/file%d", i); retval = rd_unlink (pathname); if (retval < 0) { fprintf (stderr, "rd_unlink: File deletion error! status: %d\n", retval); exit (1); } memset (pathname, 0, 80); } #endif // TEST1 #ifdef TEST2 /* ****TEST 2: LARGEST file size**** */ /* Generate one LARGEST file */ retval = rd_creat ("/bigfile"); if (retval < 0) { fprintf (stderr, "rd_creat: File creation error! status: %d\n", retval); exit (1); } retval = rd_open ("/bigfile"); /* Open file to write to it */ if (retval < 0) { fprintf (stderr, "rd_open: File open error! status: %d\n", retval); exit (1); } fd = retval; /* Assign valid fd */ /* Try writing to all direct data blocks */ retval = rd_write (fd, data1, sizeof(data1)); if (retval < 0) { fprintf (stderr, "rd_write: File write STAGE1 error! status: %d\n", retval); exit (1); } #ifdef TEST_SINGLE_INDIRECT /* Try writing to all single-indirect data blocks */ retval = rd_write (fd, data2, sizeof(data2)); if (retval < 0) { fprintf (stderr, "rd_write: File write STAGE2 error! status: %d\n", retval); exit (1); } #ifdef TEST_DOUBLE_INDIRECT /* Try writing to all double-indirect data blocks */ retval = rd_write (fd, data3, sizeof(data3)); if (retval < 0) { fprintf (stderr, "rd_write: File write STAGE3 error! status: %d\n", retval); exit (1); } #endif // TEST_DOUBLE_INDIRECT #endif // TEST_SINGLE_INDIRECT #endif // TEST2 #ifdef TEST3 /* ****TEST 3: Seek and Read file test**** */ retval = rd_lseek (fd, 0); /* Go back to the beginning of your file */ if (retval < 0) { fprintf (stderr, "rd_lseek: File seek error! status: %d\n", retval); exit (1); } /* Try reading from all direct data blocks */ retval = rd_read (fd, addr, sizeof(data1)); if (retval < 0) { fprintf (stderr, "rd_read: File read STAGE1 error! status: %d\n", retval); exit (1); } /* Should be all 1s here... */ printf ("Data at addr: %s\n", addr); #ifdef TEST_SINGLE_INDIRECT /* Try reading from all single-indirect data blocks */ retval = rd_read (fd, addr, sizeof(data2)); if (retval < 0) { fprintf (stderr, "rd_read: File read STAGE2 error! status: %d\n", retval); exit (1); } /* Should be all 2s here... */ printf ("Data at addr: %s\n", addr); #ifdef TEST_DOUBLE_INDIRECT /* Try reading from all double-indirect data blocks */ retval = rd_read (fd, addr, sizeof(data3)); if (retval < 0) { fprintf (stderr, "rd_read: File read STAGE3 error! status: %d\n", retval); exit (1); } /* Should be all 3s here... */ printf ("Data at addr: %s\n", addr); #endif // TEST_DOUBLE_INDIRECT #endif // TEST_SINGLE_INDIRECT /* Close the bigfile */ retval = rd_close (fd); if (retval < 0) { fprintf (stderr, "rd_close: File close error! status: %d\n", retval); exit (1); } /* Remove the biggest file */ retval = rd_unlink ("/bigfile"); if (retval < 0) { fprintf (stderr, "rd_unlink: /bigfile file deletion error! status: %d\n", retval); exit (1); } #endif // TEST3 #ifdef TEST4 /* ****TEST 4: Make directory and read directory entries**** */ retval = rd_mkdir ("/dir1"); if (retval < 0) { fprintf (stderr, "rd_mkdir: Directory 1 creation error! status: %d\n", retval); exit (1); } retval = rd_mkdir ("/dir1/dir2"); if (retval < 0) { fprintf (stderr, "rd_mkdir: Directory 2 creation error! status: %d\n", retval); exit (1); } retval = rd_mkdir ("/dir1/dir3"); if (retval < 0) { fprintf (stderr, "rd_mkdir: Directory 3 creation error! status: %d\n", retval); exit (1); } retval = rd_open ("/dir1"); /* Open directory file to read its entries */ if (retval < 0) { fprintf (stderr, "rd_open: Directory open error! status: %d\n", retval); exit (1); } fd = retval; /* Assign valid fd */ memset (addr, 0, sizeof(addr)); /* Clear scratchpad memory */ while ((retval = rd_readdir (fd, addr))) { /* 0 indicates end-of-file */ if (retval < 0) { fprintf (stderr, "rd_readdir: Directory read error! status: %d\n", retval); exit (1); } index_node_number = atoi(&addr[14]); printf ("Contents at addr: [%s,%d]\n", addr, index_node_number); } #endif // TEST4 #ifdef TEST5 /* ****TEST 5: 2 process test**** */ if((retval = fork())) { if(retval == -1) { fprintf(stderr, "Failed to fork\n"); exit(1); } /* Generate 300 regular files */ for (i = 0; i < 300; i++) { sprintf (pathname, "/file_p_%d", i); retval = rd_creat (pathname); if (retval < 0) { fprintf (stderr, "(Parent) rd_create: File creation error! status: %d\n", retval); exit(1); } memset (pathname, 0, 80); } } else { /* Generate 300 regular files */ for (i = 0; i < 300; i++) { sprintf (pathname, "/file_c_%d", i); retval = rd_creat (pathname); if (retval < 0) { fprintf (stderr, "(Child) rd_create: File creation error! status: %d\n", retval); exit(1); } memset (pathname, 0, 80); } } #endif // TEST5 fprintf(stdout, "Congratulations, you have passed all tests!!\n"); return 0; }
static int ramdisk_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { char cur_path[100]; char (*list)[14]; char *pathname; int ret = ERROR; int size; int *fd; file_info_t *file_info; dirctory_entry_t *dirctory_entry; switch (cmd) { case IOCTL_PWD: strcpy(cur_path, rd_pwd()); ret = copy_to_user((char *)arg, cur_path, sizeof(cur_path)); return ret; case IOCTL_LS: list = (char *)vmalloc(sizeof(char) * 1024 * 14); memset((char *) list, 0, 1024 * 14); if ((ret = rd_ls(list)) != ERROR ) ret = copy_to_user((char **)arg, list, 1024 * 14); vfree(list); return ret; case IOCTL_CREAT: size = sizeof(char) * (strlen((char *)arg) + 1); pathname = (char*)vmalloc(size); copy_from_user(pathname, (char *)arg, size); ret = rd_creat(pathname); vfree(pathname); return ret; case IOCTL_MKDIR: size = sizeof(char) * (strlen((char *)arg) + 1); pathname = (char*)vmalloc(size); copy_from_user(pathname, (char *)arg, size); ret = rd_mkdir(pathname); vfree(pathname); return ret; case IOCTL_UNLINK: size = sizeof(char) * (strlen((char *)arg) + 1); pathname = (char*)vmalloc(size); copy_from_user(pathname, (char *)arg, size); ret = rd_unlink(pathname); vfree(pathname); return ret; case IOCTL_OPEN: size = sizeof(char) * (strlen((char *)arg) + 1); pathname = (char*)vmalloc(size); copy_from_user(pathname, (char *)arg, size); ret = rd_open(pathname); vfree(pathname); return ret; case IOCTL_CLOSE: size = sizeof(int); fd = (int *)vmalloc(size); copy_from_user(fd, (int *)arg, size); ret = rd_close(*fd); return ret; case IOCTL_WRITE: size = sizeof(file_info_t); file_info = (file_info_t *)vmalloc(size); copy_from_user(file_info, (file_info_t *)arg, size); ret = rd_write(file_info->fdt_index, file_info->input, file_info->size); vfree(file_info); return ret; case IOCTL_READ: size = sizeof(file_info_t); file_info = (file_info_t *)vmalloc(size); copy_from_user(file_info, (file_info_t *)arg, size); ret = rd_read(file_info->fdt_index, file_info->input, file_info->size); copy_to_user((file_info_t *)arg, file_info, size); vfree(file_info); return ret; case IOCTL_READDIR: size = sizeof(file_info_t); file_info = (file_info_t *)vmalloc(size); copy_from_user(file_info, (file_info_t *)arg, size); ret = rd_readdir(file_info->fdt_index, file_info->input); dirctory_entry = (dirctory_entry_t *)file_info->input; copy_to_user((file_info_t *)arg, file_info, size); vfree(file_info); return ret; case IOCTL_LSEEK: size = sizeof(file_info_t); file_info = (file_info_t *)vmalloc(size); copy_from_user(file_info, (file_info_t *)arg, size); ret = rd_lseek(file_info->position, file_info->fdt_index); vfree(file_info); default: break; } return ret; }
int main () { int retval, fd, i, offset; char comp; /* Some arbitrary data for our files */ memset (data1, '1', sizeof (data1)); memset (data2, '2', sizeof (data2)); memset (data3, '3', sizeof (data3)); /* Prepare data */ memset (pathname, 0, 80); /* Fill data array where sequential_data[i] == "%d" i % 10 */ for (i = 0; i < MAX_FILE_SIZE; i++) { sequential_data[i] = (char) (((int) '0') + i % 10); } #ifdef RAND_WRITE_AND_SEEK make_seqfile(); if ((retval = rd_open("/seqfile")) < 0) { fprintf (stderr, "rd_open: Error opening seqfile! status: %d\n", retval); exit(1); } fd = retval; /* Seek to random offsets in file, make sure the byte read is equal to the offset */ for (i = 0; i < 300; i++) { offset = rand() % (MAX_FILE_SIZE + 5); retval = rd_lseek(fd, offset); if (retval < 0 && offset < MAX_FILE_SIZE) { fprintf (stderr, "rd_lseek: Error seeking to valid offset %d! status: %d\n", offset, retval); exit(1); } else if (retval < 0 && offset > MAX_FILE_SIZE) continue; retval = rd_read(fd, read_buf, 1); if (retval < 1) { fprintf (stderr, "rd_read: Error reading valid offset %d! status: %d\n", offset, retval); exit(1); } comp = (char) (((int) '0') + offset % 10); if (read_buf[0] != comp) { fprintf (stderr, "rd_read: Expected to read %c at offset %d, but read %c! status: %d\n", comp, offset, read_buf[0], retval); exit(1); } } memset(read_buf, 0, MAX_FILE_SIZE); if ((retval = rd_close(fd)) < 0) { fprintf (stderr, "rd_close: Reportedly wrote too much data! status: %d\n", retval); exit(1); } retval = rd_unlink("/seqfile"); if (retval < 0) { fprintf(stderr, "rd_unlink: Error unlinking seqfile: status %d\n", retval); exit(1); } /* Ensure that the root directory is now empty */ retval = rd_open("/"); if (retval < 0) { fprintf(stderr, "rd_open: Error opening root file: status %d\n", retval); exit(1); } fd = retval; retval = rd_readdir(fd, read_buf); if (retval != 0 || strlen(read_buf) > 0) { fprintf(stderr, "rd_readdir: Expected empty root file, but got dir entry %s: status %d\n", read_buf, retval); exit(1); } if ((retval = rd_close(fd)) < 0) { fprintf (stderr, "rd_close: Reportedly wrote too much data! status: %d\n", retval); exit(1); } #endif #ifdef TEST6 //(mkdir) //if filename is longer than 14bytes retval = rd_mkdir("/123456789012345"); if (retval >= 0) { fprintf (stderr, "rd_mkdir: Filename longer than 14 bytes is created\n"); exit(1); } //if creating DIR nder REG file rd_creat("/test.txt"); retval = rd_mkdir("/test.txt/dir"); if (retval >= 0) { fprintf (stderr, "rd_mkdir: Directory created under regular file\n"); exit(1); } //if parent DIR doesn't exist retval = rd_mkdir("/nonexistdir/dir"); if (retval >= 0) { fprintf (stderr, "rd_mkdir: Directory created under non-existing parent\n"); exit(1); } //if creating maximum number of directories /* Generate MAXIMUM directory files */ for (i = 0; i < MAX_FILES + 1; i++) { // go beyond the limit sprintf (pathname, "/dir%d", i); retval = rd_mkdir(pathname); if (retval < 0) { fprintf (stderr, "rd_mkdir: File creation error! status: %d\n", retval); if (i != MAX_FILES) break; } memset (pathname, 0, 80); } /* Delete some of the directories created */ for (i = 0; i < 100; i++) { sprintf (pathname, "/dir%d", i); retval = rd_unlink (pathname); if (retval < 0) { fprintf (stderr, "rd_unlink: File deletion error! status: %d\n", retval); exit (1); } memset (pathname, 0, 80); } #endif #ifdef TEST7 //(open) //if filename doesn't exist retval = rd_open ("/nonexist"); /* Open directory file to read its entries */ if (retval >= 0) { fprintf (stderr, "rd_open: non-existing directory opened\n"); exit(1); } retval = rd_open ("/nonexist.txt"); /* Open regular file */ if (retval >= 0) { fprintf (stderr, "rd_open: non-existing file opened\n"); exit(1); } #endif #ifdef TEST8 //(close) retval = rd_close(1000); if (retval >= 0) { fprintf (stderr, "non-opened file closed\n"); exit(1); } #endif #ifdef TEST9 //(readdir) //if reading REG file rd_creat("/test.txt"); fd = rd_open("/test.txt"); memset (addr, 0, sizeof(addr)); /* Clear scratchpad memory */ retval = rd_readdir (fd, addr); /* 0 indicates end-of-file */ if (retval >= 0) { fprintf (stderr, "rd_readdir: Regular file read\n"); exit(1); } //if dir is empty rd_mkdir("/test9"); fd = rd_open("/test9"); //fprintf (stderr, "fd: %d\n", fd); memset (addr, 0, sizeof(addr)); /* Clear scratchpad memory */ retval = rd_readdir (fd, addr); /* 0 indicates end-of-file */ if (retval != 0) { fprintf (stderr, "rd_readdir: Didn't return 0 on empty directory\n"); exit(1); } #endif fprintf(stdout, "Passed all of our own tests\n"); return 0; }