linux/fs/overlayfs/util.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2011 Novell Inc.
 * Copyright (C) 2016 Red Hat, Inc.
 */

#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/slab.h>
#include <linux/cred.h>
#include <linux/xattr.h>
#include <linux/exportfs.h>
#include <linux/file.h>
#include <linux/fileattr.h>
#include <linux/uuid.h>
#include <linux/namei.h>
#include <linux/ratelimit.h>
#include "overlayfs.h"

/* Get write access to upper mnt - may fail if upper sb was remounted ro */
int ovl_get_write_access(struct dentry *dentry)
{}

/* Get write access to upper sb - may block if upper sb is frozen */
void ovl_start_write(struct dentry *dentry)
{}

int ovl_want_write(struct dentry *dentry)
{}

void ovl_put_write_access(struct dentry *dentry)
{}

void ovl_end_write(struct dentry *dentry)
{}

void ovl_drop_write(struct dentry *dentry)
{}

struct dentry *ovl_workdir(struct dentry *dentry)
{}

const struct cred *ovl_override_creds(struct super_block *sb)
{}

/*
 * Check if underlying fs supports file handles and try to determine encoding
 * type, in order to deduce maximum inode number used by fs.
 *
 * Return 0 if file handles are not supported.
 * Return 1 (FILEID_INO32_GEN) if fs uses the default 32bit inode encoding.
 * Return -1 if fs uses a non default encoding with unknown inode size.
 */
int ovl_can_decode_fh(struct super_block *sb)
{}

struct dentry *ovl_indexdir(struct super_block *sb)
{}

/* Index all files on copy up. For now only enabled for NFS export */
bool ovl_index_all(struct super_block *sb)
{}

/* Verify lower origin on lookup. For now only enabled for NFS export */
bool ovl_verify_lower(struct super_block *sb)
{}

struct ovl_path *ovl_stack_alloc(unsigned int n)
{}

void ovl_stack_cpy(struct ovl_path *dst, struct ovl_path *src, unsigned int n)
{}

void ovl_stack_put(struct ovl_path *stack, unsigned int n)
{}

void ovl_stack_free(struct ovl_path *stack, unsigned int n)
{}

struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
{}

void ovl_free_entry(struct ovl_entry *oe)
{}

#define OVL_D_REVALIDATE

bool ovl_dentry_remote(struct dentry *dentry)
{}

void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry)
{}

void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry,
			   struct ovl_entry *oe)
{}

void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
			   struct ovl_entry *oe, unsigned int mask)
{}

bool ovl_dentry_weird(struct dentry *dentry)
{}

enum ovl_path_type ovl_path_type(struct dentry *dentry)
{}

void ovl_path_upper(struct dentry *dentry, struct path *path)
{}

void ovl_path_lower(struct dentry *dentry, struct path *path)
{}

void ovl_path_lowerdata(struct dentry *dentry, struct path *path)
{}

enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path)
{}

enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path)
{}

struct dentry *ovl_dentry_upper(struct dentry *dentry)
{}

struct dentry *ovl_dentry_lower(struct dentry *dentry)
{}

const struct ovl_layer *ovl_layer_lower(struct dentry *dentry)
{}

/*
 * ovl_dentry_lower() could return either a data dentry or metacopy dentry
 * depending on what is stored in lowerstack[0]. At times we need to find
 * lower dentry which has data (and not metacopy dentry). This helper
 * returns the lower data dentry.
 */
struct dentry *ovl_dentry_lowerdata(struct dentry *dentry)
{}

int ovl_dentry_set_lowerdata(struct dentry *dentry, struct ovl_path *datapath)
{}

struct dentry *ovl_dentry_real(struct dentry *dentry)
{}

struct dentry *ovl_i_dentry_upper(struct inode *inode)
{}

struct inode *ovl_i_path_real(struct inode *inode, struct path *path)
{}

struct inode *ovl_inode_upper(struct inode *inode)
{}

struct inode *ovl_inode_lower(struct inode *inode)
{}

struct inode *ovl_inode_real(struct inode *inode)
{}

/* Return inode which contains lower data. Do not return metacopy */
struct inode *ovl_inode_lowerdata(struct inode *inode)
{}

/* Return real inode which contains data. Does not return metacopy inode */
struct inode *ovl_inode_realdata(struct inode *inode)
{}

const char *ovl_lowerdata_redirect(struct inode *inode)
{}

struct ovl_dir_cache *ovl_dir_cache(struct inode *inode)
{}

void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache)
{}

void ovl_dentry_set_flag(unsigned long flag, struct dentry *dentry)
{}

void ovl_dentry_clear_flag(unsigned long flag, struct dentry *dentry)
{}

bool ovl_dentry_test_flag(unsigned long flag, struct dentry *dentry)
{}

bool ovl_dentry_is_opaque(struct dentry *dentry)
{}

bool ovl_dentry_is_whiteout(struct dentry *dentry)
{}

void ovl_dentry_set_opaque(struct dentry *dentry)
{}

bool ovl_dentry_has_xwhiteouts(struct dentry *dentry)
{}

void ovl_dentry_set_xwhiteouts(struct dentry *dentry)
{}

/*
 * ovl_layer_set_xwhiteouts() is called before adding the overlay dir
 * dentry to dcache, while readdir of that same directory happens after
 * the overlay dir dentry is in dcache, so if some cpu observes that
 * ovl_dentry_is_xwhiteouts(), it will also observe layer->has_xwhiteouts
 * for the layers where xwhiteouts marker was found in that merge dir.
 */
void ovl_layer_set_xwhiteouts(struct ovl_fs *ofs,
			      const struct ovl_layer *layer)
{}

/*
 * For hard links and decoded file handles, it's possible for ovl_dentry_upper()
 * to return positive, while there's no actual upper alias for the inode.
 * Copy up code needs to know about the existence of the upper alias, so it
 * can't use ovl_dentry_upper().
 */
bool ovl_dentry_has_upper_alias(struct dentry *dentry)
{}

void ovl_dentry_set_upper_alias(struct dentry *dentry)
{}

static bool ovl_should_check_upperdata(struct inode *inode)
{}

bool ovl_has_upperdata(struct inode *inode)
{}

void ovl_set_upperdata(struct inode *inode)
{}

/* Caller should hold ovl_inode->lock */
bool ovl_dentry_needs_data_copy_up_locked(struct dentry *dentry, int flags)
{}

bool ovl_dentry_needs_data_copy_up(struct dentry *dentry, int flags)
{}

const char *ovl_dentry_get_redirect(struct dentry *dentry)
{}

void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect)
{}

void ovl_inode_update(struct inode *inode, struct dentry *upperdentry)
{}

static void ovl_dir_version_inc(struct dentry *dentry, bool impurity)
{}

void ovl_dir_modified(struct dentry *dentry, bool impurity)
{}

u64 ovl_inode_version_get(struct inode *inode)
{}

bool ovl_is_whiteout(struct dentry *dentry)
{}

/*
 * Use this over ovl_is_whiteout for upper and lower files, as it also
 * handles overlay.whiteout xattr whiteout files.
 */
bool ovl_path_is_whiteout(struct ovl_fs *ofs, const struct path *path)
{}

struct file *ovl_path_open(const struct path *path, int flags)
{}

/* Caller should hold ovl_inode->lock */
static bool ovl_already_copied_up_locked(struct dentry *dentry, int flags)
{}

bool ovl_already_copied_up(struct dentry *dentry, int flags)
{}

/*
 * The copy up "transaction" keeps an elevated mnt write count on upper mnt,
 * but leaves taking freeze protection on upper sb to lower level helpers.
 */
int ovl_copy_up_start(struct dentry *dentry, int flags)
{}

void ovl_copy_up_end(struct dentry *dentry)
{}

bool ovl_path_check_origin_xattr(struct ovl_fs *ofs, const struct path *path)
{}

bool ovl_path_check_xwhiteout_xattr(struct ovl_fs *ofs, const struct path *path)
{}

/*
 * Load persistent uuid from xattr into s_uuid if found, or store a new
 * random generated value in s_uuid and in xattr.
 */
bool ovl_init_uuid_xattr(struct super_block *sb, struct ovl_fs *ofs,
			 const struct path *upperpath)
{}

char ovl_get_dir_xattr_val(struct ovl_fs *ofs, const struct path *path,
			   enum ovl_xattr ox)
{}

#define OVL_XATTR_OPAQUE_POSTFIX
#define OVL_XATTR_REDIRECT_POSTFIX
#define OVL_XATTR_ORIGIN_POSTFIX
#define OVL_XATTR_IMPURE_POSTFIX
#define OVL_XATTR_NLINK_POSTFIX
#define OVL_XATTR_UPPER_POSTFIX
#define OVL_XATTR_UUID_POSTFIX
#define OVL_XATTR_METACOPY_POSTFIX
#define OVL_XATTR_PROTATTR_POSTFIX
#define OVL_XATTR_XWHITEOUT_POSTFIX

#define OVL_XATTR_TAB_ENTRY(x)

const char *const ovl_xattr_table[][2] =;

int ovl_check_setxattr(struct ovl_fs *ofs, struct dentry *upperdentry,
		       enum ovl_xattr ox, const void *value, size_t size,
		       int xerr)
{}

int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry)
{}


#define OVL_PROTATTR_MAX

void ovl_check_protattr(struct inode *inode, struct dentry *upper)
{}

int ovl_set_protattr(struct inode *inode, struct dentry *upper,
		      struct fileattr *fa)
{}

/*
 * Caller must hold a reference to inode to prevent it from being freed while
 * it is marked inuse.
 */
bool ovl_inuse_trylock(struct dentry *dentry)
{}

void ovl_inuse_unlock(struct dentry *dentry)
{}

bool ovl_is_inuse(struct dentry *dentry)
{}

/*
 * Does this overlay dentry need to be indexed on copy up?
 */
bool ovl_need_index(struct dentry *dentry)
{}

/* Caller must hold OVL_I(inode)->lock */
static void ovl_cleanup_index(struct dentry *dentry)
{}

/*
 * Operations that change overlay inode and upper inode nlink need to be
 * synchronized with copy up for persistent nlink accounting.
 */
int ovl_nlink_start(struct dentry *dentry)
{}

void ovl_nlink_end(struct dentry *dentry)
{}

int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
{}

/*
 * err < 0, 0 if no metacopy xattr, metacopy data size if xattr found.
 * an empty xattr returns OVL_METACOPY_MIN_SIZE to distinguish from no xattr value.
 */
int ovl_check_metacopy_xattr(struct ovl_fs *ofs, const struct path *path,
			     struct ovl_metacopy *data)
{}

int ovl_set_metacopy_xattr(struct ovl_fs *ofs, struct dentry *d, struct ovl_metacopy *metacopy)
{}

bool ovl_is_metacopy_dentry(struct dentry *dentry)
{}

char *ovl_get_redirect_xattr(struct ovl_fs *ofs, const struct path *path, int padding)
{}

/* Call with mounter creds as it may open the file */
int ovl_ensure_verity_loaded(struct path *datapath)
{}

int ovl_validate_verity(struct ovl_fs *ofs,
			struct path *metapath,
			struct path *datapath)
{}

int ovl_get_verity_digest(struct ovl_fs *ofs, struct path *src,
			  struct ovl_metacopy *metacopy)
{}

/*
 * ovl_sync_status() - Check fs sync status for volatile mounts
 *
 * Returns 1 if this is not a volatile mount and a real sync is required.
 *
 * Returns 0 if syncing can be skipped because mount is volatile, and no errors
 * have occurred on the upperdir since the mount.
 *
 * Returns -errno if it is a volatile mount, and the error that occurred since
 * the last mount. If the error code changes, it'll return the latest error
 * code.
 */

int ovl_sync_status(struct ovl_fs *ofs)
{}

/*
 * ovl_copyattr() - copy inode attributes from layer to ovl inode
 *
 * When overlay copies inode information from an upper or lower layer to the
 * relevant overlay inode it will apply the idmapping of the upper or lower
 * layer when doing so ensuring that the ovl inode ownership will correctly
 * reflect the ownership of the idmapped upper or lower layer. For example, an
 * idmapped upper or lower layer mapping id 1001 to id 1000 will take care to
 * map any lower or upper inode owned by id 1001 to id 1000. These mapping
 * helpers are nops when the relevant layer isn't idmapped.
 */
void ovl_copyattr(struct inode *inode)
{}