【问题标题】:Reading ext2 superblock into ext2_super_block struct questionsext2 superblock 结构题中的 ext2 superblock 阅读
【发布时间】:2016-09-04 03:48:28
【问题描述】:

我看到了一些关于阅读 ext2 分区的超级块的问题,但我有一些问题没有在这些问题中得到解答。
他们来了:
1. 使用 read() 从磁盘读取到 ext2_super_block struct 应该要求 struct 中的所有字段都按照它们在代码中出现的顺序进行编译,以及没有 struct padding 的必要性(或正确的结构填充)。怎么保证?
2. 当试图从非特权设备读取时,Linux 的行为如何?读取必须有一个初始偏移量(更准确地说,是一个映射,禁止访问前 N 个字节),因为我编写的程序仅在以 root 身份运行时才有效。无论如何,Linux 在这种情况下表现如何?
3. 我在哪里可以找到关于使用 ext2/ext3 的好文档?到目前为止,我一直在阅读 /usr/include/linux/ext2_fs.h 和互联网上的一些随机文档,但还没有找到完整的内容。

我还想听听对下面代码的建议/更正,到目前为止,它在我的机器上运行良好(包括为简洁起见省略,程序打印“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;
}

提前致谢。

【问题讨论】:

  • ext2fs 与 UFS 和 FFS 类似,因此您可以查阅这些文档(尽管 ext2 每个块总是有 1 个片段)。

标签: c linux filesystems


【解决方案1】:

结构中的所有字段都按照它们在代码中出现的顺序进行编译

我知道没有 C 编译器可以对结构中的字段进行重新排序。我不认为这是 C 标准所允许的。 对于 alingnemt 和填充,请查看结构的声明。涉及到一些宏。

当尝试从非特权设备读取时,Linux 的行为如何?

ls

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

您只能以 root 身份或在disk 组中阅读。

在哪里可以找到有关使用 ext2/ext3 的优秀文档?

使用来源,卢克。不要忘记,除了 linux 内核能够读取 ext2/3 之外,还有更多功能。

【讨论】:

  • 谢谢,检查 open() 的返回值并没有出错,我认为我从 FD 读取正确,甚至没有检查 /dev/sda1 的权限。至于重新排列struct, "man gcc", 寻找 -Wpadded,你会发现重新排列是可能的。如果我们能以某种方式查阅标准(我刚刚发现它不是免费的),那就太好了。此外,这也意味着字节序在阅读时很重要,对吧?你怎么看?
【解决方案2】:

我在寻求答案的过程中遇到了您的一些问题。

  1. ext2_super_block struct 已设置为按顺序排列/填充到规范中。您可以创建自己的或使用标准的。

  2. 如果出现错误,open() 函数将返回小于 0 的值,您可以调用 printf("Error: %s\n", strerror(errno)); 来打印错误。如果它返回类似“Permission denied”的信息,那么在 Ubuntu 终端中使用 sudo chmod 777 /dev/yourdevice 来授予它权限。

  3. 我自己找不到太多文档,如果有帮助,我可以将我的代码传递给您以打开设备。

【讨论】:

  • 我已经成功地从分区中读取,列出目录和读取文件以及做更多的事情。我仍然想知道具有不同字节字节序的两台机器如何读取相同的超级块,以及如何保证编译器不会重新排序结构中的字段。我查看了 /usr/src/linux/include/linux/ext2_fs.h 并没有找到任何告诉编译器这样做的东西。你能解释一下这个结构是如何按顺序/填充的吗?这是唯一让我无法接受您的回答的原因。
  • 超级块存储在小端,而不是系统端:nongnu.org/ext2-doc/ext2.html#DEF-SUPERBLOCKAll fields in the superblock (as in all other ext2 structures) are stored on the disc in little endian format, so a filesystem is portable between machines without having to know what machine it was created on.
  • 至于填充,这里是 GCC 的 -Wpadded 上的人:Warn if padding is included in a structure, either to align an element of the structure or to align the whole structure. Sometimes when this happens it is possible to rearrange the fields of the structure to reduce the padding and so make the structure smaller. 我相信它应该被理解为 它是可能的 对于程序员(不是编译器) 重新排列字段以减少填充。特别是因为这是一个警告而不是优化指令。
【解决方案3】:

试试这个;

#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);
}

【讨论】:

  • 抱歉,我的问题是没有从文件系统中读取信息。我实际上对 C 标准在结构内存布局上缺乏标准化会如何影响使用在不同编译器或不同体系结构中编译的代码读取分区感兴趣。
猜你喜欢
  • 2013-10-30
  • 2011-07-11
  • 2013-02-16
  • 2015-01-29
  • 2011-09-01
  • 2011-11-27
  • 2016-02-08
  • 2020-11-01
  • 2013-03-02
相关资源
最近更新 更多