私の問題は、スパースファイルの読み取りに対処し、ファイルのエクステントがどこにあるのかを理解し、その周りで何らかのロジックを実行することです。
これらを把握するための直接の API 呼び出しがないため、ioctl api を使用してこれを行うことにしました。私は cp コマンドがスパース ファイルのコピーの問題をコードを調べて処理する方法からアイデアを得て、最終的にこれを確認しました。
そのため、ユーザー空間で実行しているサンプル プログラムで同じことを実行しようとすると、「引数が無効です」というエラーが発生します。何が欠けているのか、またはこれがユーザー空間から可能かどうかはわかりません。ext4 ファイル システムの ubuntu 14.04 で実行しています。これは、これらの要求モードをサポートするデバイス ドライバーの問題でしょうか?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include "fiemap.h" //This is from https://github.com/coreutils/coreutils/blob/df88fce71651afb2c3456967a142db0ae4bf9906/src/fiemap.h
int main(int argc, char* argv[]) {
int input_fd;
if(argc != 2){
printf ("Usage: ioctl file1");
return 1;
}
/* Create input file descriptor */
input_fd = open (argv [1], O_RDWR);
if (input_fd < 0) {
perror ("open");
return 2;
}
union { struct fiemap f; char c[4096]; } fiemap_buf;
struct fiemap *fiemap = &fiemap_buf.f;
int s = ioctl(input_fd, FS_IOC_FIEMAP, fiemap);
if (s == 0) {
printf("ioctl success\n");
} else {
printf("ioctl failure\n");
char * errmsg = strerror(errno);
printf("error: %d %s\n", errno, errmsg);
}
/* Close file descriptors */
close (input_fd);
return s;
}