3
votes

I've seen some questions on reading the superblock of an ext2 partition, but I have some questions that weren't answered in these.
Here they go:
1. using read() to read from disk into a ext2_super_block struct should require that all the fields in the struct are compiled in the order they are presented in the code, as well as the necessity of there being no struct padding (or the correct struct padding). How is that guaranteed?
2. How does Linux behave when trying to read from a device when unprivileged? There must be an initial offset for the reads (a mapping, to be more precise, forbidding access to the first N bytes), because the program I wrote only works when running as root. Anyways, how does Linux behave in that situation?
3. Where can I find good documentation on working with ext2/ext3? So far I've been reading /usr/include/linux/ext2_fs.h and some random documents on the internet, but have found nothing complete yet.

I would also like to hear suggestions/corrections on the code below, which so far works fine on my machine (includes omitted for brevity, the program prints "ef53"):

int main() {
  int fd;
  char boot[1024];
  struct ext2_super_block super_block;

  fd = open("/dev/sda1", O_RDONLY);

  /* Reads the boot section and the superblock */
  read(fd, boot, 1024);
  read(fd, &super_block, sizeof(struct ext2_super_block));

  /* Prints the Magic Number */
  printf("%x\n", super_block.s_magic);

  close(fd);

  return 0;
}

Thanks in advance.

3
ext2fs is similar to UFS and FFS, so you can consult docs on those (though ext2 always has 1 fragment per block).ninjalj

3 Answers

0
votes

all the fields in the struct are compiled in the order they are presented in the code

I know no C compiler which reorders fields in structures. I don't think this is allowed by C standard. For alingnemt and padding look at the declaration of the structure. There are some macros involved.

How does Linux behave when trying to read from a device when unprivileged?

Lets ask ls:

j@linux:~> ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 15. Mai 17:51 /dev/sda

You can only read as root or if you are in disk group.

Where can I find good documentation on working with ext2/ext3?

Use the source, luke. Don't forget that there is more than the linux kernel being able to read ext2/3.

0
votes

I ran into some of your questions in my quest for answers.

  1. The ext2_super_block struct is already setup to be in order/padded to spec. You can create your own or use the standard one.

  2. The open() function will return less than 0 if there was an error and you can call printf("Error: %s\n", strerror(errno)); to print the error. If it returns something like "Permission denied" then use sudo chmod 777 /dev/yourdevice if in a Ubuntu terminal to grant permission to it.

  3. I can't find too much documentation myself, I can pass you my code to open a device if that helps.

0
votes

TRY THIS;

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <./linux/ext2_fs.h> 
int main(int argc, char *argv[])
{
struct ext2_super_block es;
int f;
char but[1024];

  f = open("/dev/sda1", O_RDONLY);
  read(f, but, 1024);  
  read(f, &es, sizeof(struct ext2_super_block));
  printf("El tamano de int es %d byts\n", sizeof(int));
  printf("El tamano de char es %d byts\n", sizeof(char));
  printf("Número de inodos: %d \n", es.s_inodes_count);
  printf("Número de bloques: %d \n", es.s_blocks_count); 
  printf("Número de bloques libres: %d \n", es.s_free_blocks_count); 
  printf("Número de inodos libres: %d \n", es.s_free_inodes_count);
  printf("Tamano del bloque: %d \n", es.s_log_block_size);
  printf("Bloques en un grupo: %d \n", es.s_blocks_per_group);
  printf("Fragmentos en un grupo: %d \n", es.s_frags_per_group);
  printf("NM: %x\n", es.s_magic);

return (0);
}