mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
* google/upstream-f2fs-stable-linux-4.14.y: f2fs: fix to do sanity check on .cp_pack_total_block_count f2fs: make gc_urgent and gc_segment_mode sysfs node readable f2fs: use aggressive GC policy during f2fs_disable_checkpoint() f2fs: fix compressed file start atomic write may cause data corruption f2fs: initialize sbi->gc_mode explicitly f2fs: introduce gc_urgent_mid mode f2fs: compress: fix to print raw data size in error path of lz4 decompression f2fs: remove redundant parameter judgment f2fs: use spin_lock to avoid hang f2fs: don't get FREEZE lock in f2fs_evict_inode in frozen fs f2fs: remove unnecessary read for F2FS_FITS_IN_INODE f2fs: fix to do sanity check on curseg->alloc_type f2fs: fix to avoid potential deadlock f2fs: quota: fix loop condition at f2fs_quota_sync() f2fs: Restore rwsem lockdep support f2fs: fix missing free nid in f2fs_handle_failed_inode f2fs: add a way to limit roll forward recovery time f2fs: introduce F2FS_IPU_HONOR_OPU_WRITE ipu policy f2fs: adjust readahead block number during recovery f2fs: fix to unlock page correctly in error path of is_alive() f2fs: expose discard related parameters in sysfs f2fs: move discard parameters into discard_cmd_control f2fs: fix to enable ATGC correctly via gc_idle sysfs interface f2fs: move f2fs to use reader-unfair rwsems f2fs: do not allow partial truncation on pinned file f2fs: remove redunant invalidate compress pages f2fs: Simplify bool conversion f2fs: don't drop compressed page cache in .{invalidate,release}page f2fs: fix to reserve space for IO align feature f2fs: fix to check available space of CP area correctly in update_ckpt_flags() f2fs: support fault injection to f2fs_trylock_op() f2fs: clean up __find_inline_xattr() with __find_xattr() f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr() f2fs: do not bother checkpoint by f2fs_get_node_info f2fs: avoid down_write on nat_tree_lock during checkpoint f2fs: compress: fix potential deadlock of compress file f2fs: avoid EINVAL by SBI_NEED_FSCK when pinning a file f2fs: add gc_urgent_high_remaining sysfs node f2fs: fix to do sanity check in is_alive() f2fs: fix to avoid panic in is_alive() if metadata is inconsistent f2fs: fix to do sanity check on inode type during garbage collection f2fs: avoid duplicate call of mark_inode_dirty f2fs: fix remove page failed in invalidate compress pages f2fs: fix the f2fs_file_write_iter tracepoint f2fs: do not expose unwritten blocks to user by DIO f2fs: reduce indentation in f2fs_file_write_iter() f2fs: rework write preallocations f2fs: compress: reduce one page array alloc and free when write compressed page f2fs: show number of pending discard commands f2fs: check nr_pages for readahead f2fs: fix UAF in f2fs_available_free_memory f2fs: invalidate META_MAPPING before IPU/DIO write f2fs: support fault injection for dquot_initialize() f2fs: fix incorrect return value in f2fs_sanity_check_ckpt() f2fs: compress: disallow disabling compress on non-empty compressed file f2fs: compress: fix overwrite may reduce compress ratio unproperly f2fs: multidevice: support direct IO f2fs: introduce fragment allocation mode mount option f2fs: include non-compressed blocks in compr_written_block f2fs: fix wrong condition to trigger background checkpoint correctly f2fs: fix to use WHINT_MODE f2fs: fix up f2fs_lookup tracepoints f2fs: set SBI_NEED_FSCK flag when inconsistent node block found f2fs: introduce excess_dirty_threshold() f2fs: avoid attaching SB_ACTIVE flag during mount f2fs: quota: fix potential deadlock f2fs: should use GFP_NOFS for directory inodes f2fs: should put a page beyond EOF when preparing a write f2fs: deallocate compressed pages when error happens f2fs: enable realtime discard iff device supports discard f2fs: guarantee to write dirty data when enabling checkpoint back f2fs: fix to unmap pages from userspace process in punch_hole() f2fs: fix unexpected ENOENT comes from f2fs_map_blocks() f2fs: fix to account missing .skipped_gc_rwsem f2fs: adjust unlock order for cleanup f2fs: Don't create discard thread when device doesn't support realtime discard f2fs: rebuild nat_bits during umount f2fs: introduce periodic iostat io latency traces f2fs: separate out iostat feature f2fs: compress: do sanity check on cluster f2fs: fix description about main_blkaddr node f2fs: convert S_IRUGO to 0444 f2fs: fix to keep compatibility of fault injection interface f2fs: support fault injection for f2fs_kmem_cache_alloc() f2fs: compress: allow write compress released file after truncate to zero f2fs: correct comment in segment.h f2fs: improve sbi status info in debugfs/f2fs/status f2fs: compress: avoid duplicate counting of valid blocks when read compressed file f2fs: fix to do sanity check for sb/cp fields correctly f2fs: avoid unneeded memory allocation in __add_ino_entry() f2fs: extent cache: support unaligned extent f2fs: Kconfig: clean up config options about compression f2fs: reduce the scope of setting fsck tag when de->name_len is zero f2fs: fix to stop filesystem update once CP failed f2fs: introduce discard_unit mount option f2fs: fix min_seq_blocks can not make sense in some scenes. f2fs: fix to force keeping write barrier for strict fsync mode f2fs: fix wrong checkpoint_changed value in f2fs_remount() f2fs: show sbi status in debugfs/f2fs/status f2fs: turn back remapped address in compressed page endio f2fs: change fiemap way in printing compression chunk f2fs: do not submit NEW_ADDR to read node block f2fs: compress: remove unneeded read when rewrite whole cluster f2fs: don't sleep while grabing nat_tree_lock f2fs: remove allow_outplace_dio() f2fs: make f2fs_write_failed() take struct inode f2fs: quota: fix potential deadlock f2fs: let's keep writing IOs on SBI_NEED_FSCK f2fs: Revert "f2fs: Fix indefinite loop in f2fs_gc() v1" f2fs: avoid to create an empty string as the extension_list f2fs: compress: fix to set zstd compress level correctly f2fs: add sysfs nodes to get GC info for each GC mode f2fs: drop dirty node pages when cp is in error status f2fs: initialize page->private when using for our internal use f2fs: compress: add nocompress extensions support Revert "f2fs: avoid attaching SB_ACTIVE flag during mount/remount" f2fs: remove false alarm on iget failure during GC f2fs: enable extent cache for compression files in read-only f2fs: fix to avoid adding tab before doc section f2fs: introduce f2fs_casefolded_name slab cache f2fs: swap: support migrating swapfile in aligned write mode f2fs: swap: remove dead codes f2fs: compress: add compress_inode to cache compressed blocks f2fs: clean up /sys/fs/f2fs/<disk>/features f2fs: add pin_file in feature list f2fs: Advertise encrypted casefolding in sysfs f2fs: Show casefolding support only when supported f2fs: support RO feature f2fs: logging neatening f2fs: restructure f2fs page.private layout f2fs: introduce FI_COMPRESS_RELEASED instead of using IMMUTABLE bit f2fs: compress: remove unneeded preallocation f2fs: avoid attaching SB_ACTIVE flag during mount/remount f2fs: atgc: export entries for better tunability via sysfs f2fs: compress: fix to disallow temp extension f2fs: let's allow compression for mmap files f2fs: add MODULE_SOFTDEP to ensure crc32 is included in the initramfs f2fs: return success if there is no work to do f2fs: compress: clean up parameter of __f2fs_cluster_blocks() f2fs: compress: remove unneeded f2fs_put_dnode() f2fs: atgc: fix to set default age threshold f2fs: Prevent swap file in LFS mode f2fs: fix to avoid racing on fsync_entry_slab by multi filesystem instances f2fs: add cp_error check in f2fs_write_compressed_pages f2fs: compress: rename __cluster_may_compress f2fs: return EINVAL for hole cases in swap file f2fs: avoid swapon failure by giving a warning first f2fs: compress: fix to assign cc.cluster_idx correctly f2fs: compress: fix race condition of overwrite vs truncate f2fs: compress: fix to free compress page correctly f2fs: support iflag change given the mask f2fs: avoid null pointer access when handling IPU error f2fs: drop inplace IO if fs status is abnormal f2fs: compress: remove unneed check condition f2fs: clean up left deprecated IO trace codes f2fs: avoid using native allocate_segment_by_default() f2fs: remove unnecessary struct declaration f2fs: fix to avoid NULL pointer dereference f2fs: avoid duplicated codes for cleanup f2fs: document: add description about compressed space handling f2fs: clean up build warnings f2fs: fix the periodic wakeups of discard thread f2fs: fix to avoid accessing invalid fio in f2fs_allocate_data_block() f2fs: fix to avoid GC/mmap race with f2fs_truncate() f2fs: set checkpoint_merge by default f2fs: Fix a hungtask problem in atomic write f2fs: fix to restrict mount condition on readonly block device f2fs: introduce gc_merge mount option f2fs: fix to cover __allocate_new_section() with curseg_lock f2fs: fix wrong alloc_type in f2fs_do_replace_block f2fs: delete empty compress.h f2fs: fix a typo in inode.c f2fs: allow to change discard policy based on cached discard cmds f2fs: fix to avoid touching checkpointed data in get_victim() f2fs: fix to update last i_size if fallocate partially succeeds f2fs: fix error path of f2fs_remount() f2fs: fix wrong comment of nat_tree_lock f2fs: fix to avoid out-of-bounds memory access f2fs: don't start checkpoint thread in readonly mountpoint f2fs: do not use AT_SSR mode in FG_GC & high urgent BG_GC f2fs: add sysfs nodes to get runtime compression stat f2fs: fix to use per-inode maxbytes in f2fs_fiemap f2fs: fix to align to section for fallocate() on pinned file f2fs: expose # of overprivision segments f2fs: fix error handling in f2fs_end_enable_verity() f2fs: fix a redundant call to f2fs_balance_fs if an error occurs f2fs: remove unused file_clear_encrypt() f2fs: check if swapfile is section-alligned f2fs: fix last_lblock check in check_swap_activate_fast f2fs: remove unnecessary IS_SWAPFILE check f2fs: Replace one-element array with flexible-array member f2fs: compress: Allow modular (de)compression algorithms f2fs: check discard command number before traversing discard pending list f2fs: update comments for explicit memory barrier f2fs: remove unused FORCE_FG_GC macro f2fs: avoid unused f2fs_show_compress_options() f2fs: fix panic during f2fs_resize_fs() f2fs: fix to allow migrating fully valid segment f2fs: fix a spelling error f2fs: fix a spacing coding style fs: Enable bmap() function to properly return errors f2fs: remove obsolete f2fs.txt fs-verity: support reading signature with ioctl fs-verity: support reading descriptor with ioctl fs-verity: support reading Merkle tree with ioctl fs-verity: add FS_IOC_READ_VERITY_METADATA ioctl fs-verity: don't pass whole descriptor to fsverity_verify_signature() fs-verity: factor out fsverity_get_descriptor() fs-verity: move structs needed for file signing to UAPI header fs-verity: rename "file measurement" to "file digest" fs-verity: rename fsverity_signed_digest to fsverity_formatted_digest fs-verity: remove filenames from file comments fs-verity: use smp_load_acquire() for ->i_verity_info f2fs: remove FAULT_ALLOC_BIO f2fs: use blkdev_issue_flush in __submit_flush_wait f2fs: remove a few bd_part checks quota: Cleanup list iteration in dqcache_shrink_scan() quota: reclaim least recently used dquots fs: quota: Replace GFP_ATOMIC with GFP_KERNEL in dquot_init quota: Check for register_shrinker() failure. quota: propagate error from __dquot_initialize quota: be aware of error from dquot_initialize Documentation: f2fs: fix typo s/automaic/automatic f2fs: give a warning only for readonly partition f2fs: don't grab superblock freeze for flush/ckpt thread f2fs: add ckpt_thread_ioprio sysfs node f2fs: introduce checkpoint_merge mount option f2fs: relocate inline conversion from mmap() to mkwrite() f2fs: fix a wrong condition in __submit_bio f2fs: remove unnecessary initialization in xattr.c f2fs: fix to avoid inconsistent quota data f2fs: flush data when enabling checkpoint back f2fs: deprecate f2fs_trace_io f2fs: remove unused stat_{inc, dec}_atomic_write f2fs: introduce sb_status sysfs node f2fs: fix to use per-inode maxbytes f2fs: compress: fix potential deadlock libfs: unexport generic_ci_d_compare() and generic_ci_d_hash() f2fs: fix to set/clear I_LINKABLE under i_lock f2fs: fix null page reference in redirty_blocks f2fs: clean up post-read processing f2fs: trival cleanup in move_data_block() f2fs: fix out-of-repair __setattr_copy() f2fs: fix to tag FIEMAP_EXTENT_MERGED in f2fs_fiemap() f2fs: introduce a new per-sb directory in sysfs f2fs: compress: support compress level f2fs: compress: deny setting unsupported compress algorithm f2fs: relocate f2fs_precache_extents() f2fs: enforce the immutable flag on open files f2fs: enhance to update i_mode and acl atomically in f2fs_setattr() f2fs: fix to set inode->i_mode correctly for posix_acl_update_mode f2fs: Replace expression with offsetof() f2fs: handle unallocated section and zone on pinned/atgc f2fs: compress: fix compression chksum f2fs: fix shift-out-of-bounds in sanity_check_raw_super() f2fs: fix race of pending_pages in decompression f2fs: fix to account inline xattr correctly during recovery f2fs: inline: fix wrong inline inode stat f2fs: inline: correct comment in f2fs_recover_inline_data f2fs: don't check PAGE_SIZE again in sanity_check_raw_super() f2fs: convert to F2FS_*_INO macro f2fs: introduce max_io_bytes, a sysfs entry, to limit bio size f2fs: don't allow any writes on readonly mount f2fs: avoid race condition for shrinker count f2fs: add F2FS_IOC_DECOMPRESS_FILE and F2FS_IOC_COMPRESS_FILE f2fs: add compress_mode mount option f2fs: Remove unnecessary unlikely() f2fs: init dirty_secmap incorrectly f2fs: remove buffer_head which has 32bits limit f2fs: fix wrong block count instead of bytes f2fs: use new conversion functions between blks and bytes f2fs: rename logical_to_blk and blk_to_logical f2fs: fix kbytes written stat for multi-device case f2fs: compress: support chksum f2fs: fix to avoid REQ_TIME and CP_TIME collision f2fs: change to use rwsem for cp_mutex f2fs: Handle casefolding with Encryption fscrypt: Have filesystems handle their d_ops libfs: Add generic function for setting dentry_ops f2fs: Remove the redundancy initialization f2fs: remove writeback_inodes_sb in f2fs_remount f2fs: fix double free of unicode map f2fs: fix compat F2FS_IOC_{MOVE,GARBAGE_COLLECT}_RANGE f2fs: avoid unneeded data copy in f2fs_ioc_move_range() f2fs: add F2FS_IOC_SET_COMPRESS_OPTION ioctl f2fs: add F2FS_IOC_GET_COMPRESS_OPTION ioctl f2fs: move ioctl interface definitions to separated file f2fs: fix to seek incorrect data offset in inline data file f2fs: check fiemap parameters f2fs: call f2fs_get_meta_page_retry for nat page fscrypt: rename DCACHE_ENCRYPTED_NAME to DCACHE_NOKEY_NAME fscrypt: don't call no-key names "ciphertext names" fscrypt: export fscrypt_d_revalidate() f2fs: code cleanup by removing unnecessary check f2fs: wait for sysfs kobject removal before freeing f2fs_sb_info f2fs: fix writecount false positive in releasing compress blocks f2fs: introduce check_swap_activate_fast() f2fs: don't issue flush in f2fs_flush_device_cache() for nobarrier case f2fs: handle errors of f2fs_get_meta_page_nofail f2fs: fix to set SBI_NEED_FSCK flag for inconsistent inode f2fs: reject CASEFOLD inode flag without casefold feature f2fs: fix memory alignment to support 32bit f2fs: fix slab leak of rpages pointer f2fs: compress: fix to disallow enabling compress on non-empty file f2fs: compress: introduce cic/dic slab cache f2fs: compress: introduce page array slab cache f2fs: fix to do sanity check on segment/section count f2fs: fix to check segment boundary during SIT page readahead f2fs: fix uninit-value in f2fs_lookup fs/buffer.c: record blockdev write errors in super_block that it backs vfs: track per-sb writeback errors and report them to syncfs f2fs: remove unneeded parameter in find_in_block() f2fs: fix wrong total_sections check and fsmeta check f2fs: remove duplicated code in sanity_check_area_boundary f2fs: remove unused check on version_bitmap f2fs: relocate blkzoned feature check f2fs: do sanity check on zoned block device path f2fs: add trace exit in exception path f2fs: change return value of reserved_segments to unsigned int f2fs: clean up kvfree f2fs: change virtual mapping way for compression pages f2fs: change return value of f2fs_disable_compressed_file to bool f2fs: change i_compr_blocks of inode to atomic value f2fs: ignore compress mount option on image w/o compression feature f2fs: allocate proper size memory for zstd decompress f2fs: change compr_blocks of superblock info to 64bit f2fs: add block address limit check to compressed file f2fs: check position in move range ioctl f2fs: correct statistic of APP_DIRECT_IO/APP_DIRECT_READ_IO f2fs: support age threshold based garbage collection f2fs: Use generic casefolding support fs: Add standard casefolding support unicode: Add utf8_casefold_hash f2fs: compress: use more readable atomic_t type for {cic,dic}.ref f2fs: fix compile warning f2fs: support 64-bits key in f2fs rb-tree node entry f2fs: inherit mtime of original block during GC f2fs: record average update time of segment f2fs: introduce inmem curseg f2fs: compress: remove unneeded code f2fs: remove duplicated type casting f2fs: support zone capacity less than zone size f2fs: update changes in upstream on GC_URGENT_HIGH f2fs: Return EOF on unaligned end of file DIO read f2fs: fix indefinite loop scanning for free nid f2fs: Fix type of section block count variables f2fs: prepare a waiter before entering io_schedule f2fs: update_sit_entry: Make the judgment condition of f2fs_bug_on more intuitive f2fs: replace test_and_set/clear_bit() with set/clear_bit() f2fs: make file immutable even if releasing zero compression block f2fs: compress: disable compression mount option if compression is off f2fs: compress: add sanity check during compressed cluster read f2fs: use macro instead of f2fs verity version f2fs: fix deadlock between quota writes and checkpoint f2fs: correct comment of f2fs_exist_written_data f2fs: compress: delay temp page allocation f2fs: compress: fix to update isize when overwriting compressed file f2fs: space related cleanup f2fs: fix use-after-free issue f2fs: Change the type of f2fs_flush_inline_data() to void f2fs: add F2FS_IOC_SEC_TRIM_FILE ioctl f2fs: segment.h: delete a duplicated word f2fs: compress: fix to avoid memory leak on cc->cpages f2fs: use generic names for generic ioctls f2fs: don't keep meta inode pages used for compressed block migration f2fs: fix error path in do_recover_data() f2fs: fix to wait GCed compressed page writeback f2fs: remove write attribute of main_blkaddr sysfs node f2fs: add GC_URGENT_LOW mode in gc_urgent f2fs: avoid readahead race condition f2fs: fix return value of move_data_block() f2fs: add parameter op_flag in f2fs_submit_page_read() f2fs: split f2fs_allocate_new_segments() f2fs: lost matching-pair of trace in f2fs_truncate_inode_blocks f2fs: fix an oops in f2fs_is_compressed_page f2fs: make trace enter and end in pairs for unlink f2fs: fix to check page dirty status before writeback f2fs: remove the unused compr parameter f2fs: support to trace f2fs_fiemap() f2fs: support to trace f2fs_bmap() f2fs: fix wrong return value of f2fs_bmap_compress() f2fs: remove useless parameter of __insert_free_nid() f2fs: fix typo in comment of f2fs_do_add_link f2fs: fix to wait page writeback before update f2fs: show more debug info for per-temperature log f2fs: add f2fs_gc exception handle in f2fs_ioc_gc_range f2fs: clean up parameter of f2fs_allocate_data_block() f2fs: shrink node_write lock coverage f2fs: add prefix for exported symbols f2fs: use kfree() to free variables allocated by match_strdup() f2fs: get the right gc victim section when section has several segments f2fs: fix a race condition between f2fs_write_end_io and f2fs_del_fsync_node_entry f2fs: remove useless truncate in f2fs_collapse_range() f2fs: use kfree() instead of kvfree() to free superblock data f2fs: avoid checkpatch error f2fs: should avoid inode eviction in synchronous path
869 lines
26 KiB
C
869 lines
26 KiB
C
/* 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/parser.h>
|
|
#include <linux/slab.h>
|
|
#include <uapi/linux/fscrypt.h>
|
|
|
|
#define FS_CRYPTO_BLOCK_SIZE 16
|
|
|
|
union fscrypt_context;
|
|
struct fscrypt_info;
|
|
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
|
|
|
|
#ifdef CONFIG_FS_ENCRYPTION
|
|
/*
|
|
* fscrypt superblock flags
|
|
*/
|
|
#define FS_CFLG_OWN_PAGES (1U << 1)
|
|
|
|
/*
|
|
* crypto operations for filesystems
|
|
*/
|
|
struct fscrypt_operations {
|
|
unsigned int flags;
|
|
const char *key_prefix;
|
|
int (*get_context)(struct inode *inode, void *ctx, size_t len);
|
|
int (*set_context)(struct inode *inode, const void *ctx, size_t len,
|
|
void *fs_data);
|
|
const union fscrypt_context *(*get_dummy_context)(
|
|
struct super_block *sb);
|
|
bool (*empty_dir)(struct inode *inode);
|
|
unsigned int max_namelen;
|
|
bool (*is_encrypted)(struct inode *);
|
|
bool (*has_stable_inodes)(struct super_block *sb);
|
|
void (*get_ino_and_lblk_bits)(struct super_block *sb,
|
|
int *ino_bits_ret, int *lblk_bits_ret);
|
|
bool (*inline_crypt_enabled)(struct super_block *sb);
|
|
int (*get_num_devices)(struct super_block *sb);
|
|
void (*get_devices)(struct super_block *sb,
|
|
struct request_queue **devs);
|
|
};
|
|
|
|
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
|
{
|
|
/* pairs with cmpxchg_release() in fscrypt_get_encryption_info() */
|
|
return READ_ONCE(inode->i_crypt_info) != NULL;
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
static inline const union fscrypt_context *
|
|
fscrypt_get_dummy_context(struct super_block *sb)
|
|
{
|
|
if (!sb->s_cop->get_dummy_context)
|
|
return NULL;
|
|
return sb->s_cop->get_dummy_context(sb);
|
|
}
|
|
|
|
/*
|
|
* 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. Note that we don't have to support arbitrary moves of this flag
|
|
* 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)
|
|
{
|
|
dentry->d_flags &= ~DCACHE_NOKEY_NAME;
|
|
}
|
|
|
|
/* crypto.c */
|
|
void fscrypt_enqueue_decrypt_work(struct work_struct *);
|
|
|
|
struct page *fscrypt_encrypt_pagecache_blocks(struct page *page,
|
|
unsigned int len,
|
|
unsigned int 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, gfp_t gfp_flags);
|
|
|
|
int fscrypt_decrypt_pagecache_blocks(struct page *page, unsigned int len,
|
|
unsigned int offs);
|
|
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);
|
|
}
|
|
|
|
void fscrypt_free_bounce_page(struct page *bounce_page);
|
|
int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags);
|
|
|
|
/* 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_inherit_context(struct inode *parent, struct inode *child,
|
|
void *fs_data, bool preload);
|
|
|
|
struct fscrypt_dummy_context {
|
|
const union fscrypt_context *ctx;
|
|
};
|
|
|
|
int fscrypt_set_test_dummy_encryption(struct super_block *sb,
|
|
const substring_t *arg,
|
|
struct fscrypt_dummy_context *dummy_ctx);
|
|
void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep,
|
|
struct super_block *sb);
|
|
static inline void
|
|
fscrypt_free_dummy_context(struct fscrypt_dummy_context *dummy_ctx)
|
|
{
|
|
kfree(dummy_ctx->ctx);
|
|
dummy_ctx->ctx = NULL;
|
|
}
|
|
|
|
/* keyring.c */
|
|
void fscrypt_sb_free(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);
|
|
int fscrypt_register_key_removal_notifier(struct notifier_block *nb);
|
|
int fscrypt_unregister_key_removal_notifier(struct notifier_block *nb);
|
|
|
|
/* keysetup.c */
|
|
int fscrypt_get_encryption_info(struct inode *inode);
|
|
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_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(const struct inode *inode, 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);
|
|
int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags);
|
|
|
|
/* bio.c */
|
|
void fscrypt_decrypt_bio(struct bio *bio);
|
|
int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
|
|
sector_t pblk, unsigned int len);
|
|
|
|
/* 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_setflags(struct inode *inode,
|
|
unsigned int oldflags, unsigned int flags);
|
|
int __fscrypt_prepare_symlink(struct inode *dir, 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);
|
|
#else /* !CONFIG_FS_ENCRYPTION */
|
|
|
|
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline bool fscrypt_needs_contents_encryption(const struct inode *inode)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline const union fscrypt_context *
|
|
fscrypt_get_dummy_context(struct super_block *sb)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void fscrypt_handle_d_move(struct dentry *dentry)
|
|
{
|
|
}
|
|
|
|
/* crypto.c */
|
|
static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
|
|
{
|
|
}
|
|
|
|
static inline struct page *fscrypt_encrypt_pagecache_blocks(struct page *page,
|
|
unsigned int len,
|
|
unsigned int 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,
|
|
gfp_t gfp_flags)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int fscrypt_decrypt_pagecache_blocks(struct page *page,
|
|
unsigned int len,
|
|
unsigned int offs)
|
|
{
|
|
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 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_inherit_context(struct inode *parent,
|
|
struct inode *child,
|
|
void *fs_data, bool preload)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
struct fscrypt_dummy_context {
|
|
};
|
|
|
|
static inline void fscrypt_show_test_dummy_encryption(struct seq_file *seq,
|
|
char sep,
|
|
struct super_block *sb)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
fscrypt_free_dummy_context(struct fscrypt_dummy_context *dummy_ctx)
|
|
{
|
|
}
|
|
|
|
/* keyring.c */
|
|
static inline void fscrypt_sb_free(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;
|
|
}
|
|
|
|
static inline int fscrypt_register_key_removal_notifier(
|
|
struct notifier_block *nb)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int fscrypt_unregister_key_removal_notifier(
|
|
struct notifier_block *nb)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* keysetup.c */
|
|
static inline int fscrypt_get_encryption_info(struct inode *inode)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
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(const struct inode *inode,
|
|
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 dentry *dentry,
|
|
unsigned int flags)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/* bio.c */
|
|
static inline void fscrypt_decrypt_bio(struct bio *bio)
|
|
{
|
|
}
|
|
|
|
static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
|
|
sector_t pblk, unsigned int len)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
/* 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_setflags(struct inode *inode,
|
|
unsigned int oldflags,
|
|
unsigned int flags)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int __fscrypt_prepare_symlink(struct inode *dir,
|
|
unsigned int len,
|
|
unsigned int max_len,
|
|
struct fscrypt_str *disk_link)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
#endif /* !CONFIG_FS_ENCRYPTION */
|
|
|
|
/* inline_crypt.c */
|
|
#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
|
|
extern bool fscrypt_inode_uses_inline_crypto(const struct inode *inode);
|
|
|
|
extern bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode);
|
|
|
|
extern void fscrypt_set_bio_crypt_ctx(struct bio *bio,
|
|
const struct inode *inode,
|
|
u64 first_lblk, gfp_t gfp_mask);
|
|
|
|
extern void fscrypt_set_bio_crypt_ctx_bh(struct bio *bio,
|
|
const struct buffer_head *first_bh,
|
|
gfp_t gfp_mask);
|
|
|
|
extern bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,
|
|
u64 next_lblk);
|
|
|
|
extern bool fscrypt_mergeable_bio_bh(struct bio *bio,
|
|
const struct buffer_head *next_bh);
|
|
|
|
bool fscrypt_dio_supported(struct kiocb *iocb, struct iov_iter *iter);
|
|
|
|
int fscrypt_limit_dio_pages(const struct inode *inode, loff_t pos,
|
|
int nr_pages);
|
|
|
|
#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
|
|
static inline bool fscrypt_inode_uses_inline_crypto(const struct inode *inode)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode)
|
|
{
|
|
return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
|
|
}
|
|
|
|
static inline void fscrypt_set_bio_crypt_ctx(struct bio *bio,
|
|
const struct inode *inode,
|
|
u64 first_lblk, gfp_t gfp_mask) { }
|
|
|
|
static inline void fscrypt_set_bio_crypt_ctx_bh(
|
|
struct bio *bio,
|
|
const struct buffer_head *first_bh,
|
|
gfp_t gfp_mask) { }
|
|
|
|
static inline bool fscrypt_mergeable_bio(struct bio *bio,
|
|
const struct inode *inode,
|
|
u64 next_lblk)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static inline bool fscrypt_mergeable_bio_bh(struct bio *bio,
|
|
const struct buffer_head *next_bh)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static inline bool fscrypt_dio_supported(struct kiocb *iocb,
|
|
struct iov_iter *iter)
|
|
{
|
|
const struct inode *inode = file_inode(iocb->ki_filp);
|
|
|
|
return !fscrypt_needs_contents_encryption(inode);
|
|
}
|
|
|
|
static inline int fscrypt_limit_dio_pages(const struct inode *inode, loff_t pos,
|
|
int nr_pages)
|
|
{
|
|
return nr_pages;
|
|
}
|
|
#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
|
|
|
|
#if IS_ENABLED(CONFIG_FS_ENCRYPTION) && IS_ENABLED(CONFIG_DM_DEFAULT_KEY)
|
|
static inline bool
|
|
fscrypt_inode_should_skip_dm_default_key(const struct inode *inode)
|
|
{
|
|
return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
|
|
}
|
|
#else
|
|
static inline bool
|
|
fscrypt_inode_should_skip_dm_default_key(const struct inode *inode)
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* fscrypt_require_key() - require an inode's encryption key
|
|
* @inode: the inode we need the key for
|
|
*
|
|
* If the inode is encrypted, set up its encryption key if not already done.
|
|
* Then require that the key be present and return -ENOKEY otherwise.
|
|
*
|
|
* No locks are needed, and the key will live as long as the struct inode --- so
|
|
* it won't go away from under you.
|
|
*
|
|
* 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_require_key(struct inode *inode)
|
|
{
|
|
if (IS_ENCRYPTED(inode)) {
|
|
int err = fscrypt_get_encryption_info(inode);
|
|
|
|
if (err)
|
|
return err;
|
|
if (!fscrypt_has_encryption_key(inode))
|
|
return -ENOKEY;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* 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. Therefore, we first set up the directory's encryption key (if
|
|
* not already done) and return an error if it's unavailable.
|
|
*
|
|
* 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 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;
|
|
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 (attr->ia_valid & ATTR_SIZE)
|
|
return fscrypt_require_key(d_inode(dentry));
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* fscrypt_prepare_symlink() - prepare to create a possibly-encrypted symlink
|
|
* @dir: directory in which the symlink is being created
|
|
* @target: plaintext symlink target
|
|
* @len: length of @target excluding null terminator
|
|
* @max_len: space the filesystem has available to store the symlink target
|
|
* @disk_link: (out) the on-disk symlink target being prepared
|
|
*
|
|
* This function computes the size the symlink target will require on-disk,
|
|
* stores it in @disk_link->len, and validates it against @max_len. An
|
|
* encrypted symlink may be longer than the original.
|
|
*
|
|
* Additionally, @disk_link->name is set to @target if the symlink will be
|
|
* unencrypted, but left NULL if the symlink will be encrypted. For encrypted
|
|
* symlinks, the filesystem must call fscrypt_encrypt_symlink() to create the
|
|
* on-disk target later. (The reason for the two-step process is that some
|
|
* filesystems need to know the size of the symlink target before creating the
|
|
* inode, e.g. to determine whether it will be a "fast" or "slow" symlink.)
|
|
*
|
|
* Return: 0 on success, -ENAMETOOLONG if the symlink target is too long,
|
|
* -ENOKEY if the encryption key is missing, or another -errno code if a problem
|
|
* occurred while setting up the encryption key.
|
|
*/
|
|
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) || fscrypt_get_dummy_context(dir->i_sb) != NULL)
|
|
return __fscrypt_prepare_symlink(dir, len, max_len, disk_link);
|
|
|
|
disk_link->name = (unsigned char *)target;
|
|
disk_link->len = len + 1;
|
|
if (disk_link->len > max_len)
|
|
return -ENAMETOOLONG;
|
|
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;
|
|
}
|
|
|
|
/* If *pagep is a bounce page, free it and set *pagep to the pagecache page */
|
|
static inline void fscrypt_finalize_bounce_page(struct page **pagep)
|
|
{
|
|
struct page *page = *pagep;
|
|
|
|
if (fscrypt_is_bounce_page(page)) {
|
|
*pagep = fscrypt_pagecache_page(page);
|
|
fscrypt_free_bounce_page(page);
|
|
}
|
|
}
|
|
|
|
#endif /* _LINUX_FSCRYPT_H */
|