Я делаю некоторые расширения для модуля ядра nandsim , и у меня возникают проблемы с поиском правильного способа проверить, существует ли файл перед его открытием. Я прочитал этот вопрос , который описывает, как основные операции c открытия / чтения / записи go, но у меня возникают проблемы с выяснением того, применяются ли обычные флаги open (2) и как здесь.
Я хорошо знаю, что чтение и запись файлов в модулях ядра - плохая практика; этот код уже существует в ядре и уже читает и записывает файлы. Я просто пытаюсь внести некоторые коррективы в то, что уже на месте. В настоящее время, когда модуль загружается и получает указание использовать файл кэша (указанный как строковый путь при вызове modprobe), он использует filp_open (), чтобы открыть файл или создать его, если он не существует:
/* in nandsim.c */
...
module_param(cache_file, charp, 0400);
...
MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of memory");
...
struct file *cfile;
cfile = filp_open(cache_file, O_CREAT | O_RDWR | O_LARGEFILE, 0600);
Вы можете спросить: "Что вы на самом деле хотите здесь сделать?" Я хочу включить заголовок для файла кэша, чтобы его можно было использовать повторно, если необходимо перезагрузить систему. Включая информацию о геометрии nand-страницы и количестве страниц в начале этого файла, я могу с большей легкостью смоделировать ряд состояний ошибки, которые в противном случае были бы невозможны в среде nandsim. Если я смогу отключить модуль nandsim во время файловых операций или изменить файл поддержки для моделирования реального режима отказа, я смогу воссоздать эффект net этих условий ошибки. Это позволило бы мне вернуть имитированное устройство в оперативный режим с помощью nandsim и оценить, насколько хорошо отказоустойчивая файловая система выполняет свою работу.
Мой мыслительный процесс заключался в том, чтобы изменить его следующим образом, чтобы оно не сработало пытаюсь принудительно создать файл, который уже существует:
struct file *cfile;
cfile = filp_open(cache_file, O_CREAT | O_EXCL | O_RDWR | O_LARGEFILE, 0600);
if(IS_ERR(cfile)){
printk(KERN_INFO "File didn't exist: %ld", PTR_ERR(cfile));
/* Do header setup for first-time run of NAND simulation */
}
else{
/* Read header and validate against system parameters. Recover operations */
}
Я вижу ошибку, но это не та ошибка, которую я ожидал. Он сообщает errno 14, EFAULT (неверный адрес) вместо errno 17 EEXIST (файл существует). Я не хочу работать с этим, потому что я хотел бы, чтобы это было как идиоматизм c и как можно более правильным.
Есть ли какой-то другой способ, которым я должен делать это?
Мне нужно как-то указать, что путь к файлу находится в адресном пространстве пользователя? Если так, то почему это не так в коде, как это было?
РЕДАКТИРОВАТЬ: я смог получить надежную ошибку, пытаясь открыть только с O_RDWR
и O_LARGEFILE
, что привело к ENOENT
. До сих пор не ясно, почему мой первоначальный подход был неверным, и каков наилучший способ достижения sh моей цели. Тем не менее, если кто-то более опытный может прокомментировать это, я могу добавить это в качестве решения.