0

I'm working on a directory-level snapshot feature based on a file system, where a snapshot of a directory is recorded by an inode, and I want to implement how the snapshot sharing mount should be implemented. Specifically, you can locate the specified directory and version to the inode, and then mount the specified snapshot to another directory read-only while mounting the entire file system.

I learned that mount -bind can be used to mount subdirectories of the file system, and look at its source code, but I found that its processing function is do_loopback It is a general binding and mounting logic at the VFS layer, which only handles path mappings and does not involve specific file systems.

like code below

int f2fs_mount_snapshot(struct inode *inode, const int version, char *target_path)
{
    struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
    struct path mountpoint_path;
    struct inode *snapshot_inode = NULL;
    struct dentry *snapshot_dentry = NULL;
    int ret;

    pr_debug("F2FS: Entering f2fs_mount_snapshot(inode=%p, version=%d, target_path=%s)\n",
             inode, version, target_path);

    // Step 1: Retrieve the snapshot inode
    ret = f2fs_get_snapshot_inode(sbi, inode, version, &snapshot_inode);
    if (ret) {
        f2fs_err(sbi, "Failed to get snapshot inode");
        return ret;
    }

    // Step 2: Create dentry (to represent the mount point)
    snapshot_dentry = d_obtain_alias(snapshot_inode);
    if (IS_ERR(snapshot_dentry)) {
        ret = PTR_ERR(snapshot_dentry);
        f2fs_err(sbi, "Failed to obtain dentry for snapshot inode");
        goto out_iput;
    }

    // Step 3: Resolve the target mount path
    ret = kern_path(target_path, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &mountpoint_path);
    if (ret) {
        f2fs_err(sbi, "Failed to lookup mount point %s", target_path);
        goto out_dput;
    }

    // Step 4: Perform loopback mount (bind mount)
    down_write(&mountpoint_path.dentry->d_inode->i_rwsem);
    ret = do_loopback(mountpoint_path.dentry, snapshot_dentry, 0, 0);
    up_write(&mountpoint_path.dentry->d_inode->i_rwsem);

    if (ret) {
        f2fs_err(sbi, "Failed to loopback mount snapshot");
        goto out_path_put;
    }

    // Step 5: Set mount as read-only (optional)
    {
        struct vfsmount *mnt = lookup_mnt(&mountpoint_path);
        if (mnt) {
            mnt->mnt_flags |= MNT_READONLY;
            mntput(mnt);
        }
    }

    pr_info("F2FS: Mounted snapshot version %d at %s\n", version, target_path);

out_path_put:
    path_put(&mountpoint_path);
out_dput:
    dput(snapshot_dentry);
out_iput:
    iput(snapshot_inode);

    return ret;
}
1
  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Commented Jun 16 at 16:32

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.