The walkthrough is as follows:

  1. The "client info" is used by a lot of the called functions, so it's best to fetch it in one place. It tells us about the client, such as the client's node ID, process ID, group, etc.
  2. We discussed the connect_msg_to_attr() earlier.
  3. If the target doesn't exist, and we don't have the O_CREAT flag set, then we return an error of ENOENT.
  4. Otherwise, we do have the O_CREAT flag set, so we need to call the helper function iofunc_open(). The helper function performs a lot of checks for us (including, for example, the check against O_EXCL).
  5. We need to create a new attributes structure for the new entry. In c_open() we are only ever creating new files (directories are created in c_mknod() and symlinks are created in c_link()). The helper routine cfs_a_mkfile() initializes the attributes structure for us (the extended part, not the base part; that was done earlier by iofunc_open()).
  6. If the target exists, then we just call iofunc_open() (like step 4).
  7. Finally, we check the truncation flag, and truncate the file to zero bytes if required. We've come across the cfs_a_truncate() call before, when we used it to grow the file in ramdisk_io_write(), above. Here, however, it shrinks the size.
  8. The OCB and attributes structures are bound via the helper function iofunc_ocb_attach().