The c_mount() function

The first function called is the c_mount() function, which is responsible for accepting the name of a .tar file to operate on, and where to manifest its contents. There's a "mount helper" utility (the file m_main.c) that we'll look at later.

The beginning part of c_mount() is the same as the RAM disk, so we'll just point out the tail-end section that's different:

...

    // 1) allocate an attributes structure
    if (!(cfs_attr = malloc (sizeof (*cfs_attr)))) {
        return ENOMEM;
    }

    // 2) initialize it
    iofunc_attr_init (&cfs_attr -> attr,
                      S_IFDIR | 0555, NULL, NULL);
    cfs_attr_init (cfs_attr);
    cfs_attr -> attr.inode = (int) cfs_attr;
    cfs_a_mknod (cfs_attr, ".", S_IFDIR | 0555, NULL);
    cfs_a_mknod (cfs_attr, "..", S_IFDIR | 0555, NULL);

    // 3) load the tar file
    if (ret = analyze_tar_file (cfs_attr, spec_name)) {
        return (ret);
    }

    // 4) Attach the new pathname with the new value
    ret = resmgr_attach (dpp, &resmgr_attr, mnt_point,
                         _FTYPE_ANY, _RESMGR_FLAG_DIR,
                         &connect_func, &io_func,
                         &cfs_attr -> attr);
    if (ret == -1) {
        free (cfs_attr);
        return (errno);
    }
    return (EOK);
}

The code walkthrough is as follows:

  1. Just like in the RAM disk, we initialize our attributes structure. (This is for synchronization with the RAM-disk source; after this point we diverge.)
  2. The initialization is almost the same as the RAM disk, except we use mode 0555 because we are a read-only filesystem. We could lie and show 0777 if we wanted to, but we'd just run into grief later on (see below).
  3. All of the tar-specific work is done in analyze_tar_file(), which we'll look at next. The function can return a non-zero value if it detects something it doesn't like—if that's the case, we just return it to the resource-manager framework.
  4. Finally, we attach the mount point using resmgr_attr() as per normal (same as the RAM disk).

Part of the grief mentioned in step 2 above actually turns out to have a useful side-effect. If you were to reinstate the RAM-disk portion of the extended attributes structure—even though it's not implemented in the current filesystem manager—you could implement a somewhat "modifiable" .tar filesystem. If you ever went to write to a file, the resource manager would copy the data from the .tar version of the file, and then use the fileblocks member rather than the vfile member for subsequent operations. This might be a fairly simple way of making a few small modifications to an existing tar file, without the need to uncompress and untar the file. You'd then need to re-tar the entire directory structure to include your new changes. Try it and see!