title: Why do write() syscall fails with ENOSPC?
body: <p>As per my understanding, write() syscall write data from uspace buffer to kspace buffer, not to the disk (or disk driver), provided O_SYNC, O_DIRECT flags are not used in open(). To test it I have created one 100MB ext4 File System, fill it to 100% using below dd command:</p>
  <pre><code># mount -t ext4
  /mnt1 type ext4 (rw,relatime,seclabel)
  
  # dd if=/dev/urandom of=/mnt1/dd_infinite.txt bs=1k
  dd: error writing '/mnt1/dd_infinite.txt': No space left on device
  91455+0 records in
  91454+0 records out
  93648896 bytes (94 MB, 89 MiB) copied, 0.871788 s, 107 MB/s
  
  # df -h
  Size  Used Avail Use% Mounted on
  93M   91M     0 100% /mnt1
  </code></pre>
  <p>Then I used below code to create one file and write some data into it. I was expecting fsync() to give me ENOSPC, but no it was the write() syscall which was giving me ENOSPC. My question is why? How does write() know that there is no space left on device when its task is just to copy data from uspace to kspace?</p>
  <p>Does linux kernel by default allocate data blocks during write() but flush data into it later? Or there is something which I am missing.</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;string.h&gt;
  
  int
  main(
          int             argc,
          char            *argv[])
  {
          int             fd, rv;
          char            buf[80] = { 0 };
          memset(buf, 'A', 80);
          fd = open(&quot;/mnt1/hello.txt&quot;, O_CREAT | O_RDWR, 0666);
          if (fd == -1) {
                  perror(&quot;open&quot;);
                  exit(EXIT_FAILURE);
          }
          rv = write(fd, buf, 80);
          if (rv == -1) {
                  perror(&quot;write&quot;);
                  exit(EXIT_FAILURE);
          }
          rv = fsync(fd);
          if (rv == -1) {
                  perror(&quot;fsync&quot;);
                  exit(EXIT_FAILURE);
          }
          rv = close(fd);
          if (rv == -1) {
                  perror(&quot;close&quot;);
                  exit(EXIT_FAILURE);
          }
          exit(EXIT_SUCCESS);
  }
  </code></pre>
  <p>Output:</p>
  <pre><code># gcc enospc_file_create.c -Wall -pedantic -std=c99
  # ./a.out
  write: No space left on device
  #
  </code></pre>
  <p>OS details:</p>
  <pre><code>(RHEL 8.4) Linux 4.18.0-305.el8.x86_64
  </code></pre>