Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
C
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063/* SPDX-License-Identifier: GPL-2.0 *//* * fscrypt.h: declarations for per-file encryption * * Filesystems that implement per-file encryption must include this header * file. * * Copyright (C) 2015, Google, Inc. * * Written by Michael Halcrow, 2015. * Modified by Jaegeuk Kim, 2015. */#ifndef _LINUX_FSCRYPT_H#define _LINUX_FSCRYPT_H
#include <linux/fs.h>#include <linux/mm.h>#include <linux/slab.h>#include <uapi/linux/fscrypt.h>
/* * The lengths of all file contents blocks must be divisible by this value. * This is needed to ensure that all contents encryption modes will work, as * some of the supported modes don't support arbitrarily byte-aligned messages. * * Since the needed alignment is 16 bytes, most filesystems will meet this * requirement naturally, as typical block sizes are powers of 2. However, if a * filesystem can generate arbitrarily byte-aligned block lengths (e.g., via * compression), then it will need to pad to this alignment before encryption. */#define FSCRYPT_CONTENTS_ALIGNMENT 16
union fscrypt_policy;struct fscrypt_inode_info;struct fs_parameter;struct seq_file;
struct fscrypt_str { unsigned char *name; u32 len;};
struct fscrypt_name { const struct qstr *usr_fname; struct fscrypt_str disk_name; u32 hash; u32 minor_hash; struct fscrypt_str crypto_buf; bool is_nokey_name;};
#define FSTR_INIT(n, l) { .name = n, .len = l }#define FSTR_TO_QSTR(f) QSTR_INIT((f)->name, (f)->len)#define fname_name(p) ((p)->disk_name.name)#define fname_len(p) ((p)->disk_name.len)
/* Maximum value for the third parameter of fscrypt_operations.set_context(). */#define FSCRYPT_SET_CONTEXT_MAX_SIZE 40
/* Maximum supported number of block devices per filesystem */#define FSCRYPT_MAX_DEVICES 8
#ifdef CONFIG_FS_ENCRYPTION
/* Crypto operations for filesystems */struct fscrypt_operations { /* * The offset of the pointer to struct fscrypt_inode_info in the * filesystem-specific part of the inode, relative to the beginning of * the common part of the inode (the 'struct inode'). */ ptrdiff_t inode_info_offs;
/* * Set to 1 if the filesystem is block-based. This causes fs/crypto/ to * set up the key for regular files as a blk_crypto_key. The filesystem * then uses fscrypt_set_bio_crypt_ctx() and similar functions. */ unsigned int is_block_based : 1;
/* * Set to 1 if the filesystem uses fscrypt_encrypt_pagecache_blocks(). * This enables the allocation of the bounce page pool it requires. */ unsigned int needs_bounce_pages : 1;
/* * If set, then fs/crypto/ will allow the use of encryption settings * that assume inode numbers fit in 32 bits (i.e. * FSCRYPT_POLICY_FLAG_IV_INO_LBLK_{32,64}), provided that the other * prerequisites for these settings are also met. This is only useful * if the filesystem wants to support inline encryption hardware that is * limited to 32-bit or 64-bit data unit numbers and where programming * keyslots is very slow. */ unsigned int has_32bit_inodes : 1;
/* * If set, then fs/crypto/ will allow users to select a crypto data unit * size that is less than the filesystem block size. This is done via * the log2_data_unit_size field of the fscrypt policy. This flag is * not compatible with filesystems that encrypt variable-length blocks * (i.e. blocks that aren't all equal to filesystem's block size), for * example as a result of compression. It's also not compatible with * the fscrypt_encrypt_block_inplace() and * fscrypt_decrypt_block_inplace() functions. */ unsigned int supports_subblock_data_units : 1;
/* * This field exists only for backwards compatibility reasons and should * only be set by the filesystems that are setting it already. It * contains the filesystem-specific key description prefix that is * accepted for "logon" keys for v1 fscrypt policies. This * functionality is deprecated in favor of the generic prefix * "fscrypt:", which itself is deprecated in favor of the filesystem * keyring ioctls such as FS_IOC_ADD_ENCRYPTION_KEY. Filesystems that * are newly adding fscrypt support should not set this field. */ const char *legacy_key_prefix;
/* * Get the fscrypt context of the given inode. * * @inode: the inode whose context to get * @ctx: the buffer into which to get the context * @len: length of the @ctx buffer in bytes * * Return: On success, returns the length of the context in bytes; this * may be less than @len. On failure, returns -ENODATA if the * inode doesn't have a context, -ERANGE if the context is * longer than @len, or another -errno code. */ int (*get_context)(struct inode *inode, void *ctx, size_t len);
/* * Set an fscrypt context on the given inode. * * @inode: the inode whose context to set. The inode won't already have * an fscrypt context. * @ctx: the context to set * @len: length of @ctx in bytes (at most FSCRYPT_SET_CONTEXT_MAX_SIZE) * @fs_data: If called from fscrypt_set_context(), this will be the * value the filesystem passed to fscrypt_set_context(). * Otherwise (i.e. when called from * FS_IOC_SET_ENCRYPTION_POLICY) this will be NULL. * * i_rwsem will be held for write. * * Return: 0 on success, -errno on failure. */ int (*set_context)(struct inode *inode, const void *ctx, size_t len, void *fs_data);
/* * Get the dummy fscrypt policy in use on the filesystem (if any). * * Filesystems only need to implement this function if they support the * test_dummy_encryption mount option. * * Return: A pointer to the dummy fscrypt policy, if the filesystem is * mounted with test_dummy_encryption; otherwise NULL. */ const union fscrypt_policy *(*get_dummy_policy)(struct super_block *sb);
/* * Check whether a directory is empty. i_rwsem will be held for write. */ bool (*empty_dir)(struct inode *inode);
/* * Check whether the filesystem's inode numbers and UUID are stable, * meaning that they will never be changed even by offline operations * such as filesystem shrinking and therefore can be used in the * encryption without the possibility of files becoming unreadable. * * Filesystems only need to implement this function if they want to * support the FSCRYPT_POLICY_FLAG_IV_INO_LBLK_{32,64} flags. These * flags are designed to work around the limitations of UFS and eMMC * inline crypto hardware, and they shouldn't be used in scenarios where * such hardware isn't being used. * * Leaving this NULL is equivalent to always returning false. */ bool (*has_stable_inodes)(struct super_block *sb);
/* * Retrieve the list of block devices to which the filesystem may write * encrypted file contents. * * This writes the block_device pointers to @devs and returns the count * (between 1 and FSCRYPT_MAX_DEVICES inclusively). * * If the filesystem can use multiple block devices (other than block * devices that aren't used for encrypted file contents, such as * external journal devices), and wants to support inline encryption, * then it must implement this function. Otherwise it's not needed. */ unsigned int (*get_devices)( struct super_block *sb, struct block_device *devs[FSCRYPT_MAX_DEVICES]);};
int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name, struct dentry *dentry, unsigned int flags);
/* * Returns the address of the fscrypt info pointer within the * filesystem-specific part of the inode. (To save memory on filesystems that * don't support fscrypt, a field in 'struct inode' itself is no longer used.) */static inline struct fscrypt_inode_info **fscrypt_inode_info_addr(const struct inode *inode){ VFS_WARN_ON_ONCE(inode->i_sb->s_cop->inode_info_offs == 0); return (void *)inode + inode->i_sb->s_cop->inode_info_offs;}
/* * Load the inode's fscrypt info pointer, using a raw dereference. Since this * uses a raw dereference with no memory barrier, it is appropriate to use only * when the caller knows the inode's key setup already happened, resulting in * non-NULL fscrypt info. E.g., the file contents en/decryption functions use * this, since fscrypt_file_open() set up the key. */static inline struct fscrypt_inode_info *fscrypt_get_inode_info_raw(const struct inode *inode){ struct fscrypt_inode_info *ci = *fscrypt_inode_info_addr(inode);
VFS_WARN_ON_ONCE(ci == NULL); return ci;}
static inline struct fscrypt_inode_info *fscrypt_get_inode_info(const struct inode *inode){ /* * Pairs with the cmpxchg_release() in fscrypt_setup_encryption_info(). * I.e., another task may publish the fscrypt info concurrently, * executing a RELEASE barrier. Use smp_load_acquire() here to safely * ACQUIRE the memory the other task published. */ return smp_load_acquire(fscrypt_inode_info_addr(inode));}
/** * fscrypt_needs_contents_encryption() - check whether an inode needs * contents encryption * @inode: the inode to check * * Return: %true iff the inode is an encrypted regular file and the kernel was * built with fscrypt support. * * If you need to know whether the encrypt bit is set even when the kernel was * built without fscrypt support, you must use IS_ENCRYPTED() directly instead. */static inline bool fscrypt_needs_contents_encryption(const struct inode *inode){ return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);}
/* * When d_splice_alias() moves a directory's no-key alias to its * plaintext alias as a result of the encryption key being added, * DCACHE_NOKEY_NAME must be cleared and there might be an opportunity * to disable d_revalidate. Note that we don't have to support the * inverse operation because fscrypt doesn't allow no-key names to be * the source or target of a rename(). */static inline void fscrypt_handle_d_move(struct dentry *dentry){ /* * VFS calls fscrypt_handle_d_move even for non-fscrypt * filesystems. */ if (dentry->d_flags & DCACHE_NOKEY_NAME) { dentry->d_flags &= ~DCACHE_NOKEY_NAME;
/* * Other filesystem features might be handling dentry * revalidation, in which case it cannot be disabled. */ if (dentry->d_op->d_revalidate == fscrypt_d_revalidate) dentry->d_flags &= ~DCACHE_OP_REVALIDATE; }}
/** * fscrypt_is_nokey_name() - test whether a dentry is a no-key name * @dentry: the dentry to check * * This returns true if the dentry is a no-key dentry. A no-key dentry is a * dentry that was created in an encrypted directory that hasn't had its * encryption key added yet. Such dentries may be either positive or negative. * * When a filesystem is asked to create a new filename in an encrypted directory * and the new filename's dentry is a no-key dentry, it must fail the operation * with ENOKEY. This includes ->create(), ->mkdir(), ->mknod(), ->symlink(), * ->rename(), and ->link(). (However, ->rename() and ->link() are already * handled by fscrypt_prepare_rename() and fscrypt_prepare_link().) * * This is necessary because creating a filename requires the directory's * encryption key, but just checking for the key on the directory inode during * the final filesystem operation doesn't guarantee that the key was available * during the preceding dentry lookup. And the key must have already been * available during the dentry lookup in order for it to have been checked * whether the filename already exists in the directory and for the new file's * dentry not to be invalidated due to it incorrectly having the no-key flag. * * Return: %true if the dentry is a no-key name */static inline bool fscrypt_is_nokey_name(const struct dentry *dentry){ return dentry->d_flags & DCACHE_NOKEY_NAME;}
static inline void fscrypt_prepare_dentry(struct dentry *dentry, bool is_nokey_name){ /* * This code tries to only take ->d_lock when necessary to write * to ->d_flags. We shouldn't be peeking on d_flags for * DCACHE_OP_REVALIDATE unlocked, but in the unlikely case * there is a race, the worst it can happen is that we fail to * unset DCACHE_OP_REVALIDATE and pay the cost of an extra * d_revalidate. */ if (is_nokey_name) { spin_lock(&dentry->d_lock); dentry->d_flags |= DCACHE_NOKEY_NAME; spin_unlock(&dentry->d_lock); } else if (dentry->d_flags & DCACHE_OP_REVALIDATE && dentry->d_op->d_revalidate == fscrypt_d_revalidate) { /* * Unencrypted dentries and encrypted dentries where the * key is available are always valid from fscrypt * perspective. Avoid the cost of calling * fscrypt_d_revalidate unnecessarily. */ spin_lock(&dentry->d_lock); dentry->d_flags &= ~DCACHE_OP_REVALIDATE; spin_unlock(&dentry->d_lock); }}
/* crypto.c */
struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, size_t len, size_t offs, gfp_t gfp_flags);int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num);
int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num);
static inline bool fscrypt_is_bounce_page(struct page *page){ return page->mapping == NULL;}
static inline struct page *fscrypt_pagecache_page(struct page *bounce_page){ return (struct page *)page_private(bounce_page);}
static inline bool fscrypt_is_bounce_folio(const struct folio *folio){ return folio->mapping == NULL;}
static inlinestruct folio *fscrypt_pagecache_folio(const struct folio *bounce_folio){ return bounce_folio->private;}
void fscrypt_free_bounce_page(struct page *bounce_page);
/* policy.c */int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg);int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg);int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *arg);int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg);int fscrypt_has_permitted_context(struct inode *parent, struct inode *child);int fscrypt_context_for_new_inode(void *ctx, struct inode *inode);int fscrypt_set_context(struct inode *inode, void *fs_data);
struct fscrypt_dummy_policy { const union fscrypt_policy *policy;};
int fscrypt_parse_test_dummy_encryption(const struct fs_parameter *param, struct fscrypt_dummy_policy *dummy_policy);bool fscrypt_dummy_policies_equal(const struct fscrypt_dummy_policy *p1, const struct fscrypt_dummy_policy *p2);void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep, struct super_block *sb);static inline boolfscrypt_is_dummy_policy_set(const struct fscrypt_dummy_policy *dummy_policy){ return dummy_policy->policy != NULL;}static inline voidfscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy){ kfree(dummy_policy->policy); dummy_policy->policy = NULL;}
/* keyring.c */void fscrypt_destroy_keyring(struct super_block *sb);int fscrypt_ioctl_add_key(struct file *filp, void __user *arg);int fscrypt_ioctl_remove_key(struct file *filp, void __user *arg);int fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *arg);int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg);
/* keysetup.c */int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode, bool *encrypt_ret);void fscrypt_put_encryption_info(struct inode *inode);void fscrypt_free_inode(struct inode *inode);int fscrypt_drop_inode(struct inode *inode);
/* fname.c */int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, u8 *out, unsigned int olen);bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, u32 max_len, u32 *encrypted_len_ret);int fscrypt_setup_filename(struct inode *inode, const struct qstr *iname, int lookup, struct fscrypt_name *fname);
static inline void fscrypt_free_filename(struct fscrypt_name *fname){ kfree(fname->crypto_buf.name);}
int fscrypt_fname_alloc_buffer(u32 max_encrypted_len, struct fscrypt_str *crypto_str);void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str);int fscrypt_fname_disk_to_usr(const struct inode *inode, u32 hash, u32 minor_hash, const struct fscrypt_str *iname, struct fscrypt_str *oname);bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len);u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name);
/* hooks.c */int fscrypt_file_open(struct inode *inode, struct file *filp);int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, struct dentry *dentry);int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags);int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry, struct fscrypt_name *fname);int fscrypt_prepare_lookup_partial(struct inode *dir, struct dentry *dentry);int __fscrypt_prepare_readdir(struct inode *dir);int __fscrypt_prepare_setattr(struct dentry *dentry, struct iattr *attr);int fscrypt_prepare_setflags(struct inode *inode, unsigned int oldflags, unsigned int flags);int fscrypt_prepare_symlink(struct inode *dir, const char *target, unsigned int len, unsigned int max_len, struct fscrypt_str *disk_link);int __fscrypt_encrypt_symlink(struct inode *inode, const char *target, unsigned int len, struct fscrypt_str *disk_link);const char *fscrypt_get_symlink(struct inode *inode, const void *caddr, unsigned int max_size, struct delayed_call *done);int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat);static inline void fscrypt_set_ops(struct super_block *sb, const struct fscrypt_operations *s_cop){ sb->s_cop = s_cop;}#else /* !CONFIG_FS_ENCRYPTION */
static inline struct fscrypt_inode_info *fscrypt_get_inode_info(const struct inode *inode){ return NULL;}
static inline bool fscrypt_needs_contents_encryption(const struct inode *inode){ return false;}
static inline void fscrypt_handle_d_move(struct dentry *dentry){}
static inline bool fscrypt_is_nokey_name(const struct dentry *dentry){ return false;}
static inline void fscrypt_prepare_dentry(struct dentry *dentry, bool is_nokey_name){}
/* crypto.c */
static inline struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, size_t len, size_t offs, gfp_t gfp_flags){ return ERR_PTR(-EOPNOTSUPP);}
static inline int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num){ return -EOPNOTSUPP;}
static inline int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num){ return -EOPNOTSUPP;}
static inline bool fscrypt_is_bounce_page(struct page *page){ return false;}
static inline struct page *fscrypt_pagecache_page(struct page *bounce_page){ WARN_ON_ONCE(1); return ERR_PTR(-EINVAL);}
static inline bool fscrypt_is_bounce_folio(const struct folio *folio){ return false;}
static inlinestruct folio *fscrypt_pagecache_folio(const struct folio *bounce_folio){ WARN_ON_ONCE(1); return ERR_PTR(-EINVAL);}
static inline void fscrypt_free_bounce_page(struct page *bounce_page){}
/* policy.c */static inline int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg){ return -EOPNOTSUPP;}
static inline int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg){ return -EOPNOTSUPP;}
static inline int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *arg){ return -EOPNOTSUPP;}
static inline int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg){ return -EOPNOTSUPP;}
static inline int fscrypt_has_permitted_context(struct inode *parent, struct inode *child){ return 0;}
static inline int fscrypt_set_context(struct inode *inode, void *fs_data){ return -EOPNOTSUPP;}
struct fscrypt_dummy_policy {};
static inline intfscrypt_parse_test_dummy_encryption(const struct fs_parameter *param, struct fscrypt_dummy_policy *dummy_policy){ return -EINVAL;}
static inline boolfscrypt_dummy_policies_equal(const struct fscrypt_dummy_policy *p1, const struct fscrypt_dummy_policy *p2){ return true;}
static inline void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep, struct super_block *sb){}
static inline boolfscrypt_is_dummy_policy_set(const struct fscrypt_dummy_policy *dummy_policy){ return false;}
static inline voidfscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy){}
/* keyring.c */static inline void fscrypt_destroy_keyring(struct super_block *sb){}
static inline int fscrypt_ioctl_add_key(struct file *filp, void __user *arg){ return -EOPNOTSUPP;}
static inline int fscrypt_ioctl_remove_key(struct file *filp, void __user *arg){ return -EOPNOTSUPP;}
static inline int fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *arg){ return -EOPNOTSUPP;}
static inline int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg){ return -EOPNOTSUPP;}
/* keysetup.c */
static inline int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode, bool *encrypt_ret){ if (IS_ENCRYPTED(dir)) return -EOPNOTSUPP; return 0;}
static inline void fscrypt_put_encryption_info(struct inode *inode){ return;}
static inline void fscrypt_free_inode(struct inode *inode){}
static inline int fscrypt_drop_inode(struct inode *inode){ return 0;}
/* fname.c */static inline int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, int lookup, struct fscrypt_name *fname){ if (IS_ENCRYPTED(dir)) return -EOPNOTSUPP;
memset(fname, 0, sizeof(*fname)); fname->usr_fname = iname; fname->disk_name.name = (unsigned char *)iname->name; fname->disk_name.len = iname->len; return 0;}
static inline void fscrypt_free_filename(struct fscrypt_name *fname){ return;}
static inline int fscrypt_fname_alloc_buffer(u32 max_encrypted_len, struct fscrypt_str *crypto_str){ return -EOPNOTSUPP;}
static inline void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str){ return;}
static inline int fscrypt_fname_disk_to_usr(const struct inode *inode, u32 hash, u32 minor_hash, const struct fscrypt_str *iname, struct fscrypt_str *oname){ return -EOPNOTSUPP;}
static inline bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len){ /* Encryption support disabled; use standard comparison */ if (de_name_len != fname->disk_name.len) return false; return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);}
static inline u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name){ WARN_ON_ONCE(1); return 0;}
static inline int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name, struct dentry *dentry, unsigned int flags){ return 1;}
/* hooks.c */
static inline int fscrypt_file_open(struct inode *inode, struct file *filp){ if (IS_ENCRYPTED(inode)) return -EOPNOTSUPP; return 0;}
static inline int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, struct dentry *dentry){ return -EOPNOTSUPP;}
static inline int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags){ return -EOPNOTSUPP;}
static inline int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry, struct fscrypt_name *fname){ return -EOPNOTSUPP;}
static inline int fscrypt_prepare_lookup_partial(struct inode *dir, struct dentry *dentry){ return -EOPNOTSUPP;}
static inline int __fscrypt_prepare_readdir(struct inode *dir){ return -EOPNOTSUPP;}
static inline int __fscrypt_prepare_setattr(struct dentry *dentry, struct iattr *attr){ return -EOPNOTSUPP;}
static inline int fscrypt_prepare_setflags(struct inode *inode, unsigned int oldflags, unsigned int flags){ return 0;}
static inline int fscrypt_prepare_symlink(struct inode *dir, const char *target, unsigned int len, unsigned int max_len, struct fscrypt_str *disk_link){ if (IS_ENCRYPTED(dir)) return -EOPNOTSUPP; disk_link->name = (unsigned char *)target; disk_link->len = len + 1; if (disk_link->len > max_len) return -ENAMETOOLONG; return 0;}
static inline int __fscrypt_encrypt_symlink(struct inode *inode, const char *target, unsigned int len, struct fscrypt_str *disk_link){ return -EOPNOTSUPP;}
static inline const char *fscrypt_get_symlink(struct inode *inode, const void *caddr, unsigned int max_size, struct delayed_call *done){ return ERR_PTR(-EOPNOTSUPP);}
static inline int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat){ return -EOPNOTSUPP;}
static inline void fscrypt_set_ops(struct super_block *sb, const struct fscrypt_operations *s_cop){}
#endif /* !CONFIG_FS_ENCRYPTION */
/* block.c */#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, loff_t pos, gfp_t gfp_mask);
bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, loff_t pos);
u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks);int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, sector_t sector, u64 len);
#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
static inline void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, loff_t pos, gfp_t gfp_mask) { }
static inline bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, loff_t pos){ return true;}
static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks){ return nr_blocks;}
static inline int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, sector_t sector, u64 len){ return -EOPNOTSUPP;}#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
/** * fscrypt_has_encryption_key() - check whether an inode has had its key set up * @inode: the inode to check * * Return: %true if the inode has had its encryption key set up, else %false. * * Usually this should be preceded by fscrypt_get_encryption_info() to try to * set up the key first. */static inline bool fscrypt_has_encryption_key(const struct inode *inode){ return fscrypt_get_inode_info(inode) != NULL;}
/** * fscrypt_prepare_link() - prepare to link an inode into a possibly-encrypted * directory * @old_dentry: an existing dentry for the inode being linked * @dir: the target directory * @dentry: negative dentry for the target filename * * A new link can only be added to an encrypted directory if the directory's * encryption key is available --- since otherwise we'd have no way to encrypt * the filename. * * We also verify that the link will not violate the constraint that all files * in an encrypted directory tree use the same encryption policy. * * Return: 0 on success, -ENOKEY if the directory's encryption key is missing, * -EXDEV if the link would result in an inconsistent encryption policy, or * another -errno code. */static inline int fscrypt_prepare_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry){ if (IS_ENCRYPTED(dir)) return __fscrypt_prepare_link(d_inode(old_dentry), dir, dentry); return 0;}
/** * fscrypt_prepare_rename() - prepare for a rename between possibly-encrypted * directories * @old_dir: source directory * @old_dentry: dentry for source file * @new_dir: target directory * @new_dentry: dentry for target location (may be negative unless exchanging) * @flags: rename flags (we care at least about %RENAME_EXCHANGE) * * Prepare for ->rename() where the source and/or target directories may be * encrypted. A new link can only be added to an encrypted directory if the * directory's encryption key is available --- since otherwise we'd have no way * to encrypt the filename. A rename to an existing name, on the other hand, * *is* cryptographically possible without the key. However, we take the more * conservative approach and just forbid all no-key renames. * * We also verify that the rename will not violate the constraint that all files * in an encrypted directory tree use the same encryption policy. * * Return: 0 on success, -ENOKEY if an encryption key is missing, -EXDEV if the * rename would cause inconsistent encryption policies, or another -errno code. */static inline int fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags){ if (IS_ENCRYPTED(old_dir) || IS_ENCRYPTED(new_dir)) return __fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry, flags); return 0;}
/** * fscrypt_prepare_lookup() - prepare to lookup a name in a possibly-encrypted * directory * @dir: directory being searched * @dentry: filename being looked up * @fname: (output) the name to use to search the on-disk directory * * Prepare for ->lookup() in a directory which may be encrypted by determining * the name that will actually be used to search the directory on-disk. If the * directory's encryption policy is supported by this kernel and its encryption * key is available, then the lookup is assumed to be by plaintext name; * otherwise, it is assumed to be by no-key name. * * This will set DCACHE_NOKEY_NAME on the dentry if the lookup is by no-key * name. In this case the filesystem must assign the dentry a dentry_operations * which contains fscrypt_d_revalidate (or contains a d_revalidate method that * calls fscrypt_d_revalidate), so that the dentry will be invalidated if the * directory's encryption key is later added. * * Return: 0 on success; -ENOENT if the directory's key is unavailable but the * filename isn't a valid no-key name, so a negative dentry should be created; * or another -errno code. */static inline int fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry, struct fscrypt_name *fname){ if (IS_ENCRYPTED(dir)) return __fscrypt_prepare_lookup(dir, dentry, fname);
memset(fname, 0, sizeof(*fname)); fname->usr_fname = &dentry->d_name; fname->disk_name.name = (unsigned char *)dentry->d_name.name; fname->disk_name.len = dentry->d_name.len;
fscrypt_prepare_dentry(dentry, false);
return 0;}
/** * fscrypt_prepare_readdir() - prepare to read a possibly-encrypted directory * @dir: the directory inode * * If the directory is encrypted and it doesn't already have its encryption key * set up, try to set it up so that the filenames will be listed in plaintext * form rather than in no-key form. * * Return: 0 on success; -errno on error. Note that the encryption key being * unavailable is not considered an error. It is also not an error if * the encryption policy is unsupported by this kernel; that is treated * like the key being unavailable, so that files can still be deleted. */static inline int fscrypt_prepare_readdir(struct inode *dir){ if (IS_ENCRYPTED(dir)) return __fscrypt_prepare_readdir(dir); return 0;}
/** * fscrypt_prepare_setattr() - prepare to change a possibly-encrypted inode's * attributes * @dentry: dentry through which the inode is being changed * @attr: attributes to change * * Prepare for ->setattr() on a possibly-encrypted inode. On an encrypted file, * most attribute changes are allowed even without the encryption key. However, * without the encryption key we do have to forbid truncates. This is needed * because the size being truncated to may not be a multiple of the filesystem * block size, and in that case we'd have to decrypt the final block, zero the * portion past i_size, and re-encrypt it. (We *could* allow truncating to a * filesystem block boundary, but it's simpler to just forbid all truncates --- * and we already forbid all other contents modifications without the key.) * * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code * if a problem occurred while setting up the encryption key. */static inline int fscrypt_prepare_setattr(struct dentry *dentry, struct iattr *attr){ if (IS_ENCRYPTED(d_inode(dentry))) return __fscrypt_prepare_setattr(dentry, attr); return 0;}
/** * fscrypt_encrypt_symlink() - encrypt the symlink target if needed * @inode: symlink inode * @target: plaintext symlink target * @len: length of @target excluding null terminator * @disk_link: (in/out) the on-disk symlink target being prepared * * If the symlink target needs to be encrypted, then this function encrypts it * into @disk_link->name. fscrypt_prepare_symlink() must have been called * previously to compute @disk_link->len. If the filesystem did not allocate a * buffer for @disk_link->name after calling fscrypt_prepare_link(), then one * will be kmalloc()'ed and the filesystem will be responsible for freeing it. * * Return: 0 on success, -errno on failure */static inline int fscrypt_encrypt_symlink(struct inode *inode, const char *target, unsigned int len, struct fscrypt_str *disk_link){ if (IS_ENCRYPTED(inode)) return __fscrypt_encrypt_symlink(inode, target, len, disk_link); return 0;}
#endif /* _LINUX_FSCRYPT_H */