• David Howells's avatar
    vfs: syscall: Add fsconfig() for configuring and managing a context · ecdab150
    David Howells authored
    Add a syscall for configuring a filesystem creation context and triggering
    actions upon it, to be used in conjunction with fsopen, fspick and fsmount.
    
        long fsconfig(int fs_fd, unsigned int cmd, const char *key,
    		  const void *value, int aux);
    
    Where fs_fd indicates the context, cmd indicates the action to take, key
    indicates the parameter name for parameter-setting actions and, if needed,
    value points to a buffer containing the value and aux can give more
    information for the value.
    
    The following command IDs are proposed:
    
     (*) FSCONFIG_SET_FLAG: No value is specified.  The parameter must be
         boolean in nature.  The key may be prefixed with "no" to invert the
         setting. value must be NULL and aux must be 0.
    
     (*) FSCONFIG_SET_STRING: A string value is specified.  The parameter can
         be expecting boolean, integer, string or take a path.  A conversion to
         an appropriate type will be attempted (which may include looking up as
         a path).  value points to a NUL-terminated string and aux must be 0.
    
     (*) FSCONFIG_SET_BINARY: A binary blob is specified.  value points to
         the blob and aux indicates its size.  The parameter must be expecting
         a blob.
    
     (*) FSCONFIG_SET_PATH: A non-empty path is specified.  The parameter must
         be expecting a path object.  value points to a NUL-terminated string
         that is the path and aux is a file descriptor at which to start a
         relative lookup or AT_FDCWD.
    
     (*) FSCONFIG_SET_PATH_EMPTY: As fsconfig_set_path, but with AT_EMPTY_PATH
         implied.
    
     (*) FSCONFIG_SET_FD: An open file descriptor is specified.  value must
         be NULL and aux indicates the file descriptor.
    
     (*) FSCONFIG_CMD_CREATE: Trigger superblock creation.
    
     (*) FSCONFIG_CMD_RECONFIGURE: Trigger superblock reconfiguration.
    
    For the "set" command IDs, the idea is that the file_system_type will point
    to a list of parameters and the types of value that those parameters expect
    to take.  The core code can then do the parse and argument conversion and
    then give the LSM and FS a cooked option or array of options to use.
    
    Source specification is also done the same way same way, using special keys
    "source", "source1", "source2", etc..
    
    [!] Note that, for the moment, the key and value are just glued back
    together and handed to the filesystem.  Every filesystem that uses options
    uses match_token() and co. to do this, and this will need to be changed -
    but not all at once.
    
    Example usage:
    
        fd = fsopen("ext4", FSOPEN_CLOEXEC);
        fsconfig(fd, fsconfig_set_path, "source", "/dev/sda1", AT_FDCWD);
        fsconfig(fd, fsconfig_set_path_empty, "journal_path", "", journal_fd);
        fsconfig(fd, fsconfig_set_fd, "journal_fd", "", journal_fd);
        fsconfig(fd, fsconfig_set_flag, "user_xattr", NULL, 0);
        fsconfig(fd, fsconfig_set_flag, "noacl", NULL, 0);
        fsconfig(fd, fsconfig_set_string, "sb", "1", 0);
        fsconfig(fd, fsconfig_set_string, "errors", "continue", 0);
        fsconfig(fd, fsconfig_set_string, "data", "journal", 0);
        fsconfig(fd, fsconfig_set_string, "context", "unconfined_u:...", 0);
        fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
        mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);
    
    or:
    
        fd = fsopen("ext4", FSOPEN_CLOEXEC);
        fsconfig(fd, fsconfig_set_string, "source", "/dev/sda1", 0);
        fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
        mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);
    
    or:
    
        fd = fsopen("afs", FSOPEN_CLOEXEC);
        fsconfig(fd, fsconfig_set_string, "source", "#grand.central.org:root.cell", 0);
        fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
        mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);
    
    or:
    
        fd = fsopen("jffs2", FSOPEN_CLOEXEC);
        fsconfig(fd, fsconfig_set_string, "source", "mtd0", 0);
        fsconfig(fd, fsconfig_cmd_create, NULL, NULL, 0);
        mfd = fsmount(fd, FSMOUNT_CLOEXEC, MS_NOEXEC);
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    cc: linux-api@vger.kernel.org
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    ecdab150
fs_context.c 18.7 KB