系统相关
首页 > 系统相关> > linux-正在进行I / O删除文件:它是文件系统和/或OS功能吗?

linux-正在进行I / O删除文件:它是文件系统和/或OS功能吗?

作者:互联网

我正在写一个可以在Linux上运行但可以对已安装分区上的文件进行操作的shell脚本,

>可能有或没有ext *文件系统.例如,它可以是NTFS,FAT32或任何基于inode或基于非inode的系统;
>可能会进一步在运行非Linux操作系统(例如Windows或Mac)的其他机器上重新安装.

此外,我的脚本需要能够通过Linux,Windows或Mac机器上运行的远程进程删除此共享的,任意格式的分区上的文件(即使正在读取或写入文件时)

问题:

>能够删除正在使用的文件的功能,

一种.仅文件系统?

b.还是只有操作系统?

C.还是两者的结合?
>(问题1的扩展名)对文件执行I / O和删除文件的进程是本地的还是远程的,这有关系吗?

解决方法:

Does it matter if the processes doing I/O on the file and the one
deleting the file are both local or remote?

有趣的是-远程系统如何直接在Windows上访问文件(打开,读写数据,删除)?真的,这不可能.我们需要在本地系统中运行的某些代理(LANMan服务器),该代理将通过远程命令(发送Network Redirector)对文件进行本地操作.因此从文件系统视图-所有操作始终是本地的.

Is the ability to be able to delete a file in use a feature of

这当然是由文件系统驱动程序实现的,但是此驱动程序是为具体的OS编写的,并基于该规则.磁盘上的文件系统数据具有通用格式(结果驱动器在一个OS中格式化(和写入的文件),可以从另一个OS读取)-文件系统驱动程序如何处理请求,打开,读取,写入,删除文件的方式-这是特定于操作系统.针对不同的操作系统而有所不同.根据它的规则.因此磁盘上的数据格式很常见,并且仅取决于文件系统.但是如何读取/写入/删除此数据-已经特定于操作系统.

在Windows中,我们有next rules用于删除文件:

Normally a file marked for deletion is not actually deleted until all
open handles for the file have been closed and the link count for the
file is zero. When marking a file for deletion using
FILE_DISPOSITION_POSIX_SEMANTICS, the link gets removed from the
visible namespace as soon as the POSIX delete handle has been closed,
but the file’s data streams remain accessible by other existing
handles until the last handle has been closed.

因此一般来说,文件不会被删除,直到关闭文件的最后一个句柄.尝试删除文件后无法访问该文件-无法再将其打开(我们收到错误消息,请求对具有待处理删除操作的文件对象执行非关闭操作.如果尝试这样做,请在标记为删除的文件之后进行).但是如果文件已经打开-我们仍然可以通过此句柄使用它.如果文件上存在节,则文件也无法删除-将是错误的.试图删除无法删除的文件或目录.

从win10开始redstone1构建存在FILE_DISPOSITION_POSIX_SEMANTICS标志,当关闭删除句柄时,该文件名允许从可见的命名空间中删除文件名,但是文件的数据流仍可被其他现有句柄访问,直到关闭最后一个句柄为止

Windows代码测试演示:(ntfs支持的FILE_DISPOSITION_POSIX_SEMANTICS仅从_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

标签:operating-system,io,filesystems,linux,windows
来源: https://codeday.me/bug/20191025/1926719.html