Удаление файла в процессе ввода-вывода: это файловая система и / или функция ОС? - PullRequest
0 голосов
/ 08 мая 2018

Я пишу сценарий оболочки, который будет работать в Linux, но может работать с файлами, расположенными на смонтированном разделе,

  1. , которая может иметь или не иметь файловую систему ext *. Это может быть, например, NTFS, FAT32 или любая система, основанная на инодах или не инодах;

  2. , которые могут быть дополнительно перемонтированы на других компьютерах с ОС, отличных от Linux, таких как Windows или Mac.

Кроме того, мой сценарий должен иметь возможность удалять файл на этом общем разделе произвольно отформатированного раздела (даже во время чтения или записи файла) с помощью удаленного процесса, работающего на компьютерах с Linux, Windows или Mac

Вопросы:

  1. Возможность удаления файла при использовании функции,

    а. только файловая система?

    б. или только ОС?

    с. или сочетание обоих?

  2. (расширение Q1) Имеет ли значение, если процесс, выполняющий ввод-вывод файла, и процесс, удаляющий файл, являются локальными или удаленными?

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Имеет ли значение, если процессы, выполняющие ввод-вывод файла, и процесс удаления файла являются локальными или удаленными?

интересно - как удаленная система может получить доступ к файлу (открыть, чтение-запись данных, удаление) на windows direct ?на самом деле это невозможно.нам нужен некоторый агент (сервер LANMan), работающий в локальной системе, который будет удаленными командами (отправлять, скажем, Network Redirector ) для выполнения локальных операций над файлом.так из представления файловой системы - все операции всегда локальные .

Способность удалять файлы при использовании функции

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

в Windows у нас есть следующие правила для удаления файлов:

Обычно файл помечен дляудаление фактически не удаляется до тех пор, пока все открытые дескрипторы файла не будут закрыты, а количество ссылок для файла равно нулю.При маркировке файла для удаления с использованием FILE_DISPOSITION_POSIX_SEMANTICS ссылка удаляется из видимого пространства имен, как только закрывается дескриптор удаления POSIX, но потоки данных файла остаются доступными для других существующих дескрипторов до тех пор, пока последний дескриптор не будетбыл закрыт.

, поэтому в общем случае файл не будет удален, пока не будет закрыт последний дескриптор к нему.файл стал недоступен после того, как мы попытались удалить его - больше не можем его открыть (мы получаем ошибку Запрошена операция без закрытия для файлового объекта с отложенным удалением. если попытаться сделать это, после того, как файл помечен какудалять).но если файл уже был открыт - мы все еще можем работать с ним этим дескриптором.Также файл не может быть удален, если в файле существует раздел - будет ошибка Была предпринята попытка удалить файл или каталог, которые невозможно удалить.

начните с win10 redstone1 build build FILE_DISPOSITION_POSIX_SEMANTICS флаг, позволяющий удалить имя файла из видимого пространства имен, когда дескриптор удаления закрыт, но потоки данных файла остаются доступными для других существующих дескрипторов, пока не будет закрыт последний дескриптор

демонстрация теста кода Windows: (FILE_DISPOSITION_POSIX_SEMANTICS, поддерживаемый ntfs, начинается только с _WIN32_WINNT_WIN10_RS1. FileDispositionInfoEx Информационный класс, также поддерживаемый, начинается только с _WIN32_WINNT_WIN10_RS1. В предыдущей сборке мы просто получили не реализованную ошибку )

void print_error(PCSTR name)
{
    PWSTR sz;
    NTSTATUS status = RtlGetLastNtStatus();
    if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE, 
        GetModuleHandle(L"ntdll"), status, 0, (PWSTR)&sz, 0, 0))
    {
        DbgPrint("%s=%x\n%S\n", name, status, sz);
        LocalFree(sz);
    }
}

HANDLE OpenFile(PCWSTR lpFileName, DWORD dwDesiredAccess)
{
    HANDLE hFile = CreateFileW(lpFileName, dwDesiredAccess, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        print_error("OpenFile");
        return 0;
    }

    return hFile;
}

void ReadTest(HANDLE hFile)
{
    if (hFile)
    {
        ULONG dwBytes;
        if (ReadFile(hFile, &dwBytes, sizeof(dwBytes), &dwBytes, 0))
        {
            DbgPrint("ReadFile=OK\n");
        }
        else
        {
            print_error("ReadFile");
        }
    }
}

void DeleteTest(PCWSTR lpFileName)
{
    HANDLE hFile1, hFile2, hFile3;

    if (hFile1 = OpenFile(lpFileName, DELETE))
    {
        hFile2 = OpenFile(lpFileName, FILE_GENERIC_READ);

        FILE_DISPOSITION_INFO_EX fdi = { FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS };
        if (!SetFileInformationByHandle(hFile1, FileDispositionInfoEx, &fdi, sizeof(fdi)))
        {
            print_error("SetFileInformationByHandle");
        }

        // file already not accessible here (open must fail) but visible
        if (hFile3 = OpenFile(lpFileName, FILE_GENERIC_READ))
        {
            CloseHandle(hFile3);
        }

        ReadTest(hFile2);

        // win10 rs1: file removed from the visible namespace here
        CloseHandle(hFile1);

        // are file still visible ?
        if (hFile3 = OpenFile(lpFileName, FILE_GENERIC_READ))
        {
            CloseHandle(hFile3);
        }

        // are possible create new file with this name &
        hFile3 = CreateFileW(lpFileName, DELETE, 
            FILE_SHARE_VALID_FLAGS, 0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);
        if (hFile3 == INVALID_HANDLE_VALUE)
        {
            print_error("CreateFile");
        }
        else
        {
            CloseHandle(hFile3);
            DbgPrint("CreateFile OK\n");
        }

        ReadTest(hFile2);

        if (hFile2)
        {
            CloseHandle(hFile2);
        }
    }
}

и вывод

OpenFile=c0000056
A non close operation has been requested of a file object with a delete pending.

ReadFile=OK
OpenFile=c0000034
Object Name not found.

CreateFile OK
ReadFile=OK
0 голосов
/ 08 мая 2018

это зависит от того, как вы определяете файловую систему и ОС. Обычно под файловой системой я понимаю способ организации хранения данных на устройстве. ОС отвечает за ввод / вывод данных и файлов. В частности, если ваш скрипт хочет удалить файл, он вызывает какую-то утилиту, такую ​​как rm, и предоставляет имя файла. Эта утилита представляет собой программу, которая выполняет соответствующий системный вызов. Этот системный вызов является частью операционной системы, которая выполняется в привилегированном режиме. Он понимает, что и как делать (например, какие драйверы следует использовать, чтобы пометить блоки жесткого диска как свободные на конкретном диске, или, возможно, следует вызвать некоторую удаленную процедуру или задействовать сервер samba и т. Д.) Итак, чтобы дать ответ на ваш вопрос 1, я бы склонялся к ответу б.

...