2012-04-27 3 views
1

У меня есть диск с некоторой файловой системой, известной ядром Linux. Мне нужно получить номера физических блоков для всех блоков, которые в настоящее время свободны в этой файловой системе. Как я могу это сделать?Linux: получите номера физического блока свободного места (битмарт свободного пространства)

+2

Вы хотите знать _how many_ блоков есть свободные или _where блоки are_? – bdonlan

+0

Я хочу знать, где находятся блоки - физические числа каждого свободного блока на диске. – Karatheodory

+0

@ Karatheodory, мне очень любопытно, почему вы хотите это узнать? :-) – FooF

ответ

2

Получение счет свободных блоков:

В ядре метод:

Посмотрите на .statfs суперблока крюком, который Файловые системы реализации. Они возвращают объект kstatfs, который имеет параметр f_bfree, количество свободных блоков. Вы должны иметь возможность позвонить в это.

С пользовательское приложение:?

Команда df является самым простым (что, конечно, вызывает ядро ​​вызвать statfs - где еще он получит информацию :)

Edit: передал Ваш первоначальный вопрос получая только количество свободных блоков.

Получение местоположения блоков:

Получение расположение каждого свободного блока, а не только общее число невозможно в файловой системе независимым образом с текущей структурой ядра (и это, вероятно, останется таким образом,). VFS не накладывает никакой общей структуры на то, как файловая система поддерживает ее растровое изображение; растровые изображения отслеживаются в зависимой от файловой системы части суперблока.

Итак, если вы хотите решение, которое работает во всех файловых системах, вам не повезло. Если вы знаете, что может быть файловой системой и ее небольшим числом, вы можете посмотреть код пользователя fsck для каждого из них и добавить функции для записи растрового изображения в ожидаемом формате или вы можете изменить крючки .statfs, чтобы выписать битовая карта.

Ваш метод выделения большого файла, который выделяет все оставшиеся свободные блоки, совсем не похож на очень хорошую идею, особенно если есть журналы. Он также не будет работать для активной файловой системы с файлами, которые будут записаны и удалены, когда вы это сделаете.

+0

Это не вопрос для меня, из ядра или пользовательского пространства. Я думаю, что если есть какая-то функция, которая дает мне номера физических блоков, она должна быть расположена в ядре, но это только мое предложение :) – Karatheodory

+0

Спасибо за ответ! Кажется, мне нужно перейти на более низкий уровень ... :) – Karatheodory

-1

Вы можете пойти в старый стиль C, fork, а затем запустить программу под названием stat в unix. Вы можете передать этот вывод в файл, а затем использовать некоторый stringstream для его интерпретации и найти количество свободных блоков. .. (Это предполагает, принимая число полных блоков ввода-вывода и вычитания числа используемых блоков ввода-вывода

Я не уверен, если есть более простой способ, то это Вот некоторые псевдо-код:

main() { 
    fork() 
    if child{ 
     execl(stat/%B >> output.txt) 
    } 
    if parent { 
     wait until output.txt is populated 
     read in data with stringstream 
     calculate number of free blocks 
    } 
} 

надежда .., что помогает

+0

альтернативно вы можете использовать команду df. –

-1

Capturing stdout from a system() command optimally

системный вызов может быть то, что вы ищете, просто убедитесь, что POPEN является стандартным Linux первым я забыл упомянуть, что вы должны сделать что-то вроде:

FILE* test = popen("df","r"); 

Поскольку df сообщает вам количество свободных блоков в системе.

1

Afraid statfs-подобные функции могут дать мне только кол-во бесплатных блоков fs, но не их позиции.

Самый простой способ я нашел, чтобы получить позиции свободных блоков, чтобы создать файл, который заполняет (или запасы только с fallocate() вызова) все доступное пространство, получить карту с помощью блока FIBMAP IOCTL и удалите файл. Но делать это не совсем то, что я хочу по некоторым причинам.

Другой способ - войти в нижний уровень конкретной файловой системы и получить растровое изображение свободного пространства от его драйвера. Это хороший способ для меня, но он должен быть реализован для каждой файловой системы зависимым образом, и это не хорошо :)

Возможно, есть какая-то функция vfs, которую я не могу найти для этого или некоторого fs ioctl, который может помочь в таком случае?

Спасибо всем за ваши ответы в любом случае!

+0

Не изменяя файловую систему, вы можете использовать 'FIBEMAP' /' FIBMAP' 'ioctl()', чтобы получить информацию о каждом отдельном файле, собирать все зарезервированные блоки (диапазоны блоков). Свободные блоки будут дополнять этот набор блоков. Это, по-видимому, тяжелое дело, если в вашей файловой системе много файлов. Также вам нужно будет найти способ сделать это в пространстве ядра. – FooF

+2

@Foof, этот подход будет неправильно сообщать блоки, используемые для внутренних структур FS (например, журнал), как свободные. – bdonlan

2

Это зависит от файловой системы - единого интерфейса нет, и некоторые файловые системы, такие как JFFS, на самом деле не имеют понятия свободного блока. Более того, если файловая система смонтирована, любая информация, которую вы получаете, может быть устаревшей. Ожидайте, что вам придется читать плохо документированный внутренний код файловой системы. Однако вы не обязательно должны делать это в ядре. Если вы заинтересованы в получении растровых изображений ext [234], например, посмотрите на функции растрового изображения в libext2fs. В общем случае, если есть файловая система fsck, вы, вероятно, можете использовать ее код, чтобы получить нужную вам информацию.

Для чего это необходимо, так или иначе?

+0

Мне нужно записать некоторые данные в файловую систему, не повреждая их и не изменяя. Во всяком случае, кажется, что это возможно только при использовании низкоуровневых драйверов. Спасибо за ваш ответ! – Karatheodory

Смежные вопросы