fs/目录下的read_write.c
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
size_t, count)
{
struct file *file;
ssize_t ret = -EBADF;
int fput_needed;

file = fget_light(fd, &fput_needed);
if (file) {
loff_t pos = file_pos_read(file);
ret = vfs_write(file, buf, count, &pos);
file_pos_write(file, pos);
fput_light(file, fput_needed);
}

return ret;
}
 

fs/目录下的read_write.c
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;
  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->f_path.dentry);
   add_wchar(current, ret);
  }
  inc_syscw(current);
 }
 return ret;
}

ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
 struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
 struct kiocb kiocb;
 ssize_t ret;
 init_sync_kiocb(&kiocb, filp);
 kiocb.ki_pos = *ppos;
 kiocb.ki_left = len;
 for (;;) {
  ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
  if (ret != -EIOCBRETRY)
   break;
  wait_on_retry_sync_kiocb(&kiocb);
 }
 if (-EIOCBQUEUED == ret)
  ret = wait_on_sync_kiocb(&kiocb);
 *ppos = kiocb.ki_pos;
 return ret;
}

 


12-10 01:50