• 请不要在回答技术问题时复制粘贴 AI 生成的内容
jdz
V2EX  ›  程序员

当 Linux 内核正在把 A 文件写入磁盘,这时另一个进程调用 write 写 A 文件,该进程会挂起么

  •  
  •   jdz · Feb 23, 2022 · 2474 views
    This topic created in 1541 days ago, the information mentioned may be changed or developed.

    如果不会,内核怎么处理这种竞争呢。

    9 replies    2022-02-27 07:48:00 +08:00
    soulzz
        1
    soulzz  
       Feb 23, 2022   ❤️ 1
    另一个进程 write 写 A 失败
    msg7086
        2
    msg7086  
       Feb 23, 2022
    问题看得有点迷。内核把 A 刷入磁盘,然后进程又让内核写 A ?
    wellsc
        3
    wellsc  
       Feb 23, 2022
    了解下 io 调度算法
    cheng6563
        4
    cheng6563  
       Feb 23, 2022
    不说同文件了,如果写的超过缓冲区了同硬盘都会挂起
    jdz
        5
    jdz  
    OP
       Feb 23, 2022
    @msg7086 比如进程 M 调用了 flush(A), 然后内核就会刷新 A 到磁盘,在内核刷新到磁盘的同时,进程 N 调用 write(A),这时会发生什么呢
    msg7086
        6
    msg7086  
       Feb 23, 2022
    @jdz 会放进内存里等内核下一次 flush ?
    tomychen
        7
    tomychen  
       Feb 23, 2022
    ```C
    static inline void file_start_write(struct file *file)
    {
    if (!S_ISREG(file_inode(file)->i_mode))
    return;
    __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true);
    }

    static inline bool file_start_write_trylock(struct file *file)
    {
    if (!S_ISREG(file_inode(file)->i_mode))
    return true;
    return __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, false);
    }

    static inline void file_end_write(struct file *file)
    {
    if (!S_ISREG(file_inode(file)->i_mode))
    return;
    __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE);
    }

    ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
    {
    ssize_t ret;

    if (!(file->f_mode & FMODE_WRITE))
    return -EBADF;
    if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
    return -EINVAL;
    if (unlikely(!access_ok(VERIFY_READ, buf, count)))
    return -EFAULT;

    ret = rw_verify_area(WRITE, file, pos, count);
    if (ret >= 0) {
    count = ret;
    file_start_write(file);
    if (file->f_op->write)
    ret = file->f_op->write(file, buf, count, pos);
    else
    ret = do_sync_write(file, buf, count, pos);
    if (ret > 0) {
    fsnotify_modify(file);
    add_wchar(current, ret);
    }
    inc_syscw(current);
    file_end_write(file);
    }

    return ret;
    }
    ```
    whileFalse
        8
    whileFalse  
       Feb 23, 2022 via iPhone
    你确定另一个进程能以写方式 open 该文件?
    mayli
        9
    mayli  
       Feb 27, 2022 via Android
    不处理 写入会被序列化 后面的会覆盖之前的写入
    内核相当于写同一个文件同一个 Offset 两次
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5464 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 08:49 · PVG 16:49 · LAX 01:49 · JFK 04:49
    ♥ Do have faith in what you're doing.