Merge android-4.14.118 (db39369) into msm-4.14
* refs/heads/tmp-db39369: Linux 4.14.118 arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP locking/futex: Allow low-level atomic operations to return -EAGAIN ASoC: Intel: avoid Oops if DMA setup fails UAS: fix alignment of scatter/gather segments Bluetooth: Align minimum encryption key size for LE and BR/EDR connections Bluetooth: hidp: fix buffer overflow scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines intel_th: pci: Add Comet Lake support usb-storage: Set virt_boundary_mask to avoid SG overflows USB: cdc-acm: fix unthrottle races USB: serial: f81232: fix interrupt worker not stop usb: dwc3: Fix default lpm_nyet_threshold value genirq: Prevent use-after-free and work list corruption iommu/amd: Set exclusion range correctly platform/x86: pmc_atom: Drop __initconst on dmi table virtio-blk: limit number of hw queues by nr_cpu_ids ASoC: Intel: kbl: fix wrong number of channels drm/mediatek: fix possible object reference leak scsi: csiostor: fix missing data copy in csio_scsi_err_handler() RDMA/vmw_pvrdma: Fix memory leak on pvrdma_pci_remove virtio_pci: fix a NULL pointer reference in vp_del_vqs slab: fix a crash by reading /proc/slab_allocators ASoC: rockchip: pdm: fix regmap_ops hang issue linux/kernel.h: Use parentheses around argument in u64_to_user_ptr() perf/x86/intel: Initialize TFA MSR perf/x86/intel: Fix handling of wakeup_events for multi-entry PEBS drm/mediatek: Fix an error code in mtk_hdmi_dt_parse_pdata() ASoC: tlv320aic32x4: Fix Common Pins MIPS: KGDB: fix kgdb support for SMP platforms. IB/hfi1: Eliminate opcode tests on mr deref ASoC: cs4270: Set auto-increment bit for register writes ASoC: wm_adsp: Add locking to wm_adsp2_bus_error ASoC: samsung: odroid: Fix clock configuration for 44100 sample rate ASoC: nau8810: fix the issue of widget with prefixed name ASoC: nau8824: fix the issue of the widget with prefix name ASoC:soc-pcm:fix a codec fixup issue in TDM case ASoC: hdmi-codec: fix S/PDIF DAI staging: greybus: power_supply: fix prop-descriptor request size ubsan: Fix nasty -Wbuiltin-declaration-mismatch GCC-9 warnings Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup() scsi: libsas: fix a race condition when smp task timeout ANDROID: block/cfq-iosched: make group_idle per io cgroup tunable ANDROID: cuttlefish_defconfig: Enable CONFIG_CPUSETS and CONFIG_CGROUP_SCHEDTUNE fscrypt: remove filesystem specific build config option f2fs: use IS_ENCRYPTED() to check encryption status ext4: use IS_ENCRYPTED() to check encryption status fscrypt: return -EXDEV for incompatible rename or link into encrypted dir fscrypt: remove CRYPTO_CTR dependency fscrypt: add Adiantum support / removed speck ext4: switch to fscrypt_prepare_setattr() ext4: switch to fscrypt_prepare_rename() ext4: switch to fscrypt_prepare_link() ext4: switch to fscrypt_file_open() ext4, dax: set ext4_dax_aops for dax files Conflicts: fs/crypto/fscrypt_private.h fs/ext4/inode.c fs/ext4/move_extent.c include/linux/fscrypt_supp.h kernel/irq/manage.c Change-Id: I71237103050ab644a1e4a14eeb64a5b6e992629c Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
This commit is contained in:
@@ -343,9 +343,9 @@ FS_IOC_SET_ENCRYPTION_POLICY can fail with the following errors:
|
||||
- ``ENOTEMPTY``: the file is unencrypted and is a nonempty directory
|
||||
- ``ENOTTY``: this type of filesystem does not implement encryption
|
||||
- ``EOPNOTSUPP``: the kernel was not configured with encryption
|
||||
support for this filesystem, or the filesystem superblock has not
|
||||
support for filesystems, or the filesystem superblock has not
|
||||
had encryption enabled on it. (For example, to use encryption on an
|
||||
ext4 filesystem, CONFIG_EXT4_ENCRYPTION must be enabled in the
|
||||
ext4 filesystem, CONFIG_FS_ENCRYPTION must be enabled in the
|
||||
kernel config, and the superblock must have had the "encrypt"
|
||||
feature flag enabled using ``tune2fs -O encrypt`` or ``mkfs.ext4 -O
|
||||
encrypt``.)
|
||||
@@ -451,10 +451,18 @@ astute users may notice some differences in behavior:
|
||||
- Unencrypted files, or files encrypted with a different encryption
|
||||
policy (i.e. different key, modes, or flags), cannot be renamed or
|
||||
linked into an encrypted directory; see `Encryption policy
|
||||
enforcement`_. Attempts to do so will fail with EPERM. However,
|
||||
enforcement`_. Attempts to do so will fail with EXDEV. However,
|
||||
encrypted files can be renamed within an encrypted directory, or
|
||||
into an unencrypted directory.
|
||||
|
||||
Note: "moving" an unencrypted file into an encrypted directory, e.g.
|
||||
with the `mv` program, is implemented in userspace by a copy
|
||||
followed by a delete. Be aware that the original unencrypted data
|
||||
may remain recoverable from free space on the disk; prefer to keep
|
||||
all files encrypted from the very beginning. The `shred` program
|
||||
may be used to overwrite the source files but isn't guaranteed to be
|
||||
effective on all filesystems and storage devices.
|
||||
|
||||
- Direct I/O is not supported on encrypted files. Attempts to use
|
||||
direct I/O on such files will fall back to buffered I/O.
|
||||
|
||||
@@ -541,7 +549,7 @@ not be encrypted.
|
||||
Except for those special files, it is forbidden to have unencrypted
|
||||
files, or files encrypted with a different encryption policy, in an
|
||||
encrypted directory tree. Attempts to link or rename such a file into
|
||||
an encrypted directory will fail with EPERM. This is also enforced
|
||||
an encrypted directory will fail with EXDEV. This is also enforced
|
||||
during ->lookup() to provide limited protection against offline
|
||||
attacks that try to disable or downgrade encryption in known locations
|
||||
where applications may later write sensitive data. It is recommended
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 117
|
||||
SUBLEVEL = 118
|
||||
EXTRAVERSION =
|
||||
NAME = Petit Gorille
|
||||
|
||||
|
||||
@@ -23,26 +23,34 @@
|
||||
|
||||
#include <asm/errno.h>
|
||||
|
||||
#define FUTEX_MAX_LOOPS 128 /* What's the largest number you can think of? */
|
||||
|
||||
#define __futex_atomic_op(insn, ret, oldval, uaddr, tmp, oparg) \
|
||||
do { \
|
||||
unsigned int loops = FUTEX_MAX_LOOPS; \
|
||||
\
|
||||
uaccess_enable(); \
|
||||
asm volatile( \
|
||||
" prfm pstl1strm, %2\n" \
|
||||
"1: ldxr %w1, %2\n" \
|
||||
insn "\n" \
|
||||
"2: stlxr %w0, %w3, %2\n" \
|
||||
" cbnz %w0, 1b\n" \
|
||||
" dmb ish\n" \
|
||||
" cbz %w0, 3f\n" \
|
||||
" sub %w4, %w4, %w0\n" \
|
||||
" cbnz %w4, 1b\n" \
|
||||
" mov %w0, %w7\n" \
|
||||
"3:\n" \
|
||||
" dmb ish\n" \
|
||||
" .pushsection .fixup,\"ax\"\n" \
|
||||
" .align 2\n" \
|
||||
"4: mov %w0, %w5\n" \
|
||||
"4: mov %w0, %w6\n" \
|
||||
" b 3b\n" \
|
||||
" .popsection\n" \
|
||||
_ASM_EXTABLE(1b, 4b) \
|
||||
_ASM_EXTABLE(2b, 4b) \
|
||||
: "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \
|
||||
: "r" (oparg), "Ir" (-EFAULT) \
|
||||
: "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp), \
|
||||
"+r" (loops) \
|
||||
: "r" (oparg), "Ir" (-EFAULT), "Ir" (-EAGAIN) \
|
||||
: "memory"); \
|
||||
uaccess_disable(); \
|
||||
} while (0)
|
||||
@@ -57,23 +65,23 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *_uaddr)
|
||||
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
__futex_atomic_op("mov %w3, %w4",
|
||||
__futex_atomic_op("mov %w3, %w5",
|
||||
ret, oldval, uaddr, tmp, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ADD:
|
||||
__futex_atomic_op("add %w3, %w1, %w4",
|
||||
__futex_atomic_op("add %w3, %w1, %w5",
|
||||
ret, oldval, uaddr, tmp, oparg);
|
||||
break;
|
||||
case FUTEX_OP_OR:
|
||||
__futex_atomic_op("orr %w3, %w1, %w4",
|
||||
__futex_atomic_op("orr %w3, %w1, %w5",
|
||||
ret, oldval, uaddr, tmp, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_atomic_op("and %w3, %w1, %w4",
|
||||
__futex_atomic_op("and %w3, %w1, %w5",
|
||||
ret, oldval, uaddr, tmp, ~oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_atomic_op("eor %w3, %w1, %w4",
|
||||
__futex_atomic_op("eor %w3, %w1, %w5",
|
||||
ret, oldval, uaddr, tmp, oparg);
|
||||
break;
|
||||
default:
|
||||
@@ -93,6 +101,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *_uaddr,
|
||||
u32 oldval, u32 newval)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int loops = FUTEX_MAX_LOOPS;
|
||||
u32 val, tmp;
|
||||
u32 __user *uaddr;
|
||||
|
||||
@@ -104,20 +113,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *_uaddr,
|
||||
asm volatile("// futex_atomic_cmpxchg_inatomic\n"
|
||||
" prfm pstl1strm, %2\n"
|
||||
"1: ldxr %w1, %2\n"
|
||||
" sub %w3, %w1, %w4\n"
|
||||
" cbnz %w3, 3f\n"
|
||||
"2: stlxr %w3, %w5, %2\n"
|
||||
" cbnz %w3, 1b\n"
|
||||
" dmb ish\n"
|
||||
" sub %w3, %w1, %w5\n"
|
||||
" cbnz %w3, 4f\n"
|
||||
"2: stlxr %w3, %w6, %2\n"
|
||||
" cbz %w3, 3f\n"
|
||||
" sub %w4, %w4, %w3\n"
|
||||
" cbnz %w4, 1b\n"
|
||||
" mov %w0, %w8\n"
|
||||
"3:\n"
|
||||
" dmb ish\n"
|
||||
"4:\n"
|
||||
" .pushsection .fixup,\"ax\"\n"
|
||||
"4: mov %w0, %w6\n"
|
||||
" b 3b\n"
|
||||
"5: mov %w0, %w7\n"
|
||||
" b 4b\n"
|
||||
" .popsection\n"
|
||||
_ASM_EXTABLE(1b, 4b)
|
||||
_ASM_EXTABLE(2b, 4b)
|
||||
: "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp)
|
||||
: "r" (oldval), "r" (newval), "Ir" (-EFAULT)
|
||||
_ASM_EXTABLE(1b, 5b)
|
||||
_ASM_EXTABLE(2b, 5b)
|
||||
: "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp), "+r" (loops)
|
||||
: "r" (oldval), "r" (newval), "Ir" (-EFAULT), "Ir" (-EAGAIN)
|
||||
: "memory");
|
||||
uaccess_disable();
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ CONFIG_HID_MONTEREY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_EXT4_ENCRYPTION=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/sigcontext.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/irq_regs.h>
|
||||
|
||||
static struct hard_trap_info {
|
||||
unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */
|
||||
@@ -214,7 +215,7 @@ static void kgdb_call_nmi_hook(void *ignored)
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
|
||||
kgdb_nmicallback(raw_smp_processor_id(), NULL);
|
||||
kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
|
||||
|
||||
set_fs(old_fs);
|
||||
}
|
||||
|
||||
@@ -481,7 +481,6 @@ CONFIG_VIRTIO_BALLOON=m
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_EXT4_ENCRYPTION=y
|
||||
CONFIG_JBD2_DEBUG=y
|
||||
CONFIG_JFS_FS=m
|
||||
CONFIG_JFS_POSIX_ACL=y
|
||||
@@ -499,6 +498,7 @@ CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_NILFS2_FS=m
|
||||
CONFIG_FS_DAX=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
|
||||
@@ -18,9 +18,11 @@ CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_BPF=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_SCHED_TUNE=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_LZ4 is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
|
||||
@@ -3051,7 +3051,7 @@ static int intel_pmu_hw_config(struct perf_event *event)
|
||||
return ret;
|
||||
|
||||
if (event->attr.precise_ip) {
|
||||
if (!event->attr.freq) {
|
||||
if (!(event->attr.freq || event->attr.wakeup_events)) {
|
||||
event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
|
||||
if (!(event->attr.sample_type &
|
||||
~intel_pmu_free_running_flags(event)))
|
||||
@@ -3427,6 +3427,12 @@ static void intel_pmu_cpu_starting(int cpu)
|
||||
|
||||
cpuc->lbr_sel = NULL;
|
||||
|
||||
if (x86_pmu.flags & PMU_FL_TFA) {
|
||||
WARN_ON_ONCE(cpuc->tfa_shadow);
|
||||
cpuc->tfa_shadow = ~0ULL;
|
||||
intel_set_tfa(cpuc, false);
|
||||
}
|
||||
|
||||
if (x86_pmu.version > 1)
|
||||
flip_smm_bit(&x86_pmu.attr_freeze_on_smi);
|
||||
|
||||
|
||||
@@ -225,6 +225,7 @@ struct cfq_group_data {
|
||||
|
||||
unsigned int weight;
|
||||
unsigned int leaf_weight;
|
||||
u64 group_idle;
|
||||
};
|
||||
|
||||
/* This is per cgroup per device grouping structure */
|
||||
@@ -310,6 +311,7 @@ struct cfq_group {
|
||||
struct cfq_queue *async_cfqq[2][IOPRIO_BE_NR];
|
||||
struct cfq_queue *async_idle_cfqq;
|
||||
|
||||
u64 group_idle;
|
||||
};
|
||||
|
||||
struct cfq_io_cq {
|
||||
@@ -802,6 +804,17 @@ static inline void cfqg_stats_update_completion(struct cfq_group *cfqg,
|
||||
|
||||
#endif /* CONFIG_CFQ_GROUP_IOSCHED */
|
||||
|
||||
static inline u64 get_group_idle(struct cfq_data *cfqd)
|
||||
{
|
||||
#ifdef CONFIG_CFQ_GROUP_IOSCHED
|
||||
struct cfq_queue *cfqq = cfqd->active_queue;
|
||||
|
||||
if (cfqq && cfqq->cfqg)
|
||||
return cfqq->cfqg->group_idle;
|
||||
#endif
|
||||
return cfqd->cfq_group_idle;
|
||||
}
|
||||
|
||||
#define cfq_log(cfqd, fmt, args...) \
|
||||
blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args)
|
||||
|
||||
@@ -822,7 +835,7 @@ static inline bool cfq_io_thinktime_big(struct cfq_data *cfqd,
|
||||
if (!sample_valid(ttime->ttime_samples))
|
||||
return false;
|
||||
if (group_idle)
|
||||
slice = cfqd->cfq_group_idle;
|
||||
slice = get_group_idle(cfqd);
|
||||
else
|
||||
slice = cfqd->cfq_slice_idle;
|
||||
return ttime->ttime_mean > slice;
|
||||
@@ -1589,6 +1602,7 @@ static void cfq_cpd_init(struct blkcg_policy_data *cpd)
|
||||
|
||||
cgd->weight = weight;
|
||||
cgd->leaf_weight = weight;
|
||||
cgd->group_idle = cfq_group_idle;
|
||||
}
|
||||
|
||||
static void cfq_cpd_free(struct blkcg_policy_data *cpd)
|
||||
@@ -1633,6 +1647,7 @@ static void cfq_pd_init(struct blkg_policy_data *pd)
|
||||
|
||||
cfqg->weight = cgd->weight;
|
||||
cfqg->leaf_weight = cgd->leaf_weight;
|
||||
cfqg->group_idle = cgd->group_idle;
|
||||
}
|
||||
|
||||
static void cfq_pd_offline(struct blkg_policy_data *pd)
|
||||
@@ -1754,6 +1769,19 @@ static int cfq_print_leaf_weight(struct seq_file *sf, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cfq_print_group_idle(struct seq_file *sf, void *v)
|
||||
{
|
||||
struct blkcg *blkcg = css_to_blkcg(seq_css(sf));
|
||||
struct cfq_group_data *cgd = blkcg_to_cfqgd(blkcg);
|
||||
u64 val = 0;
|
||||
|
||||
if (cgd)
|
||||
val = cgd->group_idle;
|
||||
|
||||
seq_printf(sf, "%llu\n", div_u64(val, NSEC_PER_USEC));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
|
||||
char *buf, size_t nbytes, loff_t off,
|
||||
bool on_dfl, bool is_leaf_weight)
|
||||
@@ -1875,6 +1903,37 @@ static int cfq_set_leaf_weight(struct cgroup_subsys_state *css,
|
||||
return __cfq_set_weight(css, val, false, false, true);
|
||||
}
|
||||
|
||||
static int cfq_set_group_idle(struct cgroup_subsys_state *css,
|
||||
struct cftype *cft, u64 val)
|
||||
{
|
||||
struct blkcg *blkcg = css_to_blkcg(css);
|
||||
struct cfq_group_data *cfqgd;
|
||||
struct blkcg_gq *blkg;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irq(&blkcg->lock);
|
||||
cfqgd = blkcg_to_cfqgd(blkcg);
|
||||
if (!cfqgd) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cfqgd->group_idle = val * NSEC_PER_USEC;
|
||||
|
||||
hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
|
||||
struct cfq_group *cfqg = blkg_to_cfqg(blkg);
|
||||
|
||||
if (!cfqg)
|
||||
continue;
|
||||
|
||||
cfqg->group_idle = cfqgd->group_idle;
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_irq(&blkcg->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cfqg_print_stat(struct seq_file *sf, void *v)
|
||||
{
|
||||
blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_stat,
|
||||
@@ -2020,6 +2079,11 @@ static struct cftype cfq_blkcg_legacy_files[] = {
|
||||
.seq_show = cfq_print_leaf_weight,
|
||||
.write_u64 = cfq_set_leaf_weight,
|
||||
},
|
||||
{
|
||||
.name = "group_idle",
|
||||
.seq_show = cfq_print_group_idle,
|
||||
.write_u64 = cfq_set_group_idle,
|
||||
},
|
||||
|
||||
/* statistics, covers only the tasks in the cfqg */
|
||||
{
|
||||
@@ -2914,7 +2978,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
|
||||
* with sync vs async workloads.
|
||||
*/
|
||||
if (blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag &&
|
||||
!cfqd->cfq_group_idle)
|
||||
!get_group_idle(cfqd))
|
||||
return;
|
||||
|
||||
WARN_ON(!RB_EMPTY_ROOT(&cfqq->sort_list));
|
||||
@@ -2925,9 +2989,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
|
||||
*/
|
||||
if (!cfq_should_idle(cfqd, cfqq)) {
|
||||
/* no queue idling. Check for group idling */
|
||||
if (cfqd->cfq_group_idle)
|
||||
group_idle = cfqd->cfq_group_idle;
|
||||
else
|
||||
group_idle = get_group_idle(cfqd);
|
||||
if (!group_idle)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2968,7 +3031,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
|
||||
cfq_mark_cfqq_wait_request(cfqq);
|
||||
|
||||
if (group_idle)
|
||||
sl = cfqd->cfq_group_idle;
|
||||
sl = group_idle;
|
||||
else
|
||||
sl = cfqd->cfq_slice_idle;
|
||||
|
||||
@@ -3317,7 +3380,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
|
||||
* this group, wait for requests to complete.
|
||||
*/
|
||||
check_group_idle:
|
||||
if (cfqd->cfq_group_idle && cfqq->cfqg->nr_cfqq == 1 &&
|
||||
if (get_group_idle(cfqd) && cfqq->cfqg->nr_cfqq == 1 &&
|
||||
cfqq->cfqg->dispatched &&
|
||||
!cfq_io_thinktime_big(cfqd, &cfqq->cfqg->ttime, true)) {
|
||||
cfqq = NULL;
|
||||
@@ -3880,7 +3943,7 @@ cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
|
||||
cfqd->cfq_slice_idle);
|
||||
}
|
||||
#ifdef CONFIG_CFQ_GROUP_IOSCHED
|
||||
__cfq_update_io_thinktime(&cfqq->cfqg->ttime, cfqd->cfq_group_idle);
|
||||
__cfq_update_io_thinktime(&cfqq->cfqg->ttime, get_group_idle(cfqd));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4278,7 +4341,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
|
||||
if (cfq_should_wait_busy(cfqd, cfqq)) {
|
||||
u64 extend_sl = cfqd->cfq_slice_idle;
|
||||
if (!cfqd->cfq_slice_idle)
|
||||
extend_sl = cfqd->cfq_group_idle;
|
||||
extend_sl = get_group_idle(cfqd);
|
||||
cfqq->slice_end = now + extend_sl;
|
||||
cfq_mark_cfqq_wait_busy(cfqq);
|
||||
cfq_log_cfqq(cfqd, cfqq, "will busy wait");
|
||||
|
||||
@@ -437,6 +437,8 @@ static int init_vq(struct virtio_blk *vblk)
|
||||
if (err)
|
||||
num_vqs = 1;
|
||||
|
||||
num_vqs = min_t(unsigned int, nr_cpu_ids, num_vqs);
|
||||
|
||||
vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL);
|
||||
if (!vblk->vqs)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1473,7 +1473,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
||||
if (IS_ERR(regmap))
|
||||
ret = PTR_ERR(regmap);
|
||||
if (ret) {
|
||||
ret = PTR_ERR(regmap);
|
||||
dev_err(dev,
|
||||
"Failed to get system configuration registers: %d\n",
|
||||
ret);
|
||||
@@ -1509,6 +1508,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
||||
of_node_put(remote);
|
||||
|
||||
hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
|
||||
of_node_put(i2c_np);
|
||||
if (!hdmi->ddc_adpt) {
|
||||
dev_err(dev, "Failed to get ddc i2c adapter by node\n");
|
||||
return -EINVAL;
|
||||
|
||||
@@ -356,7 +356,6 @@ int hv_synic_cleanup(unsigned int cpu)
|
||||
|
||||
clockevents_unbind_device(hv_cpu->clk_evt, cpu);
|
||||
hv_ce_shutdown(hv_cpu->clk_evt);
|
||||
put_cpu_ptr(hv_cpu);
|
||||
}
|
||||
|
||||
hv_get_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,
|
||||
|
||||
@@ -173,6 +173,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{
|
||||
/* Comet Lake */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6),
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
|
||||
@@ -2309,7 +2309,7 @@ send_last:
|
||||
update_ack_queue(qp, next);
|
||||
}
|
||||
e = &qp->s_ack_queue[qp->r_head_ack_queue];
|
||||
if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) {
|
||||
if (e->rdma_sge.mr) {
|
||||
rvt_put_mr(e->rdma_sge.mr);
|
||||
e->rdma_sge.mr = NULL;
|
||||
}
|
||||
@@ -2383,7 +2383,7 @@ send_last:
|
||||
update_ack_queue(qp, next);
|
||||
}
|
||||
e = &qp->s_ack_queue[qp->r_head_ack_queue];
|
||||
if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) {
|
||||
if (e->rdma_sge.mr) {
|
||||
rvt_put_mr(e->rdma_sge.mr);
|
||||
e->rdma_sge.mr = NULL;
|
||||
}
|
||||
|
||||
@@ -1055,6 +1055,8 @@ static void pvrdma_pci_remove(struct pci_dev *pdev)
|
||||
pvrdma_page_dir_cleanup(dev, &dev->cq_pdir);
|
||||
pvrdma_page_dir_cleanup(dev, &dev->async_pdir);
|
||||
pvrdma_free_slots(dev);
|
||||
dma_free_coherent(&pdev->dev, sizeof(*dev->dsr), dev->dsr,
|
||||
dev->dsrbase);
|
||||
|
||||
iounmap(dev->regs);
|
||||
kfree(dev->sgid_tbl);
|
||||
|
||||
@@ -355,7 +355,7 @@ static void iommu_write_l2(struct amd_iommu *iommu, u8 address, u32 val)
|
||||
static void iommu_set_exclusion_range(struct amd_iommu *iommu)
|
||||
{
|
||||
u64 start = iommu->exclusion_start & PAGE_MASK;
|
||||
u64 limit = (start + iommu->exclusion_length) & PAGE_MASK;
|
||||
u64 limit = (start + iommu->exclusion_length - 1) & PAGE_MASK;
|
||||
u64 entry;
|
||||
|
||||
if (!iommu->exclusion_start)
|
||||
|
||||
@@ -426,7 +426,7 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
|
||||
* Some systems need one or more of their pmc_plt_clks to be
|
||||
* marked as critical.
|
||||
*/
|
||||
static const struct dmi_system_id critclk_systems[] __initconst = {
|
||||
static const struct dmi_system_id critclk_systems[] = {
|
||||
{
|
||||
.ident = "MPL CEC1x",
|
||||
.matches = {
|
||||
|
||||
@@ -1713,8 +1713,11 @@ csio_scsi_err_handler(struct csio_hw *hw, struct csio_ioreq *req)
|
||||
}
|
||||
|
||||
out:
|
||||
if (req->nsge > 0)
|
||||
if (req->nsge > 0) {
|
||||
scsi_dma_unmap(cmnd);
|
||||
if (req->dcopy && (host_status == DID_OK))
|
||||
host_status = csio_scsi_copy_to_sgl(hw, req);
|
||||
}
|
||||
|
||||
cmnd->result = (((host_status) << 16) | scsi_status);
|
||||
cmnd->scsi_done(cmnd);
|
||||
|
||||
@@ -47,17 +47,16 @@ static void smp_task_timedout(unsigned long _task)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&task->task_state_lock, flags);
|
||||
if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
|
||||
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
|
||||
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
|
||||
complete(&task->slow_task->completion);
|
||||
}
|
||||
spin_unlock_irqrestore(&task->task_state_lock, flags);
|
||||
|
||||
complete(&task->slow_task->completion);
|
||||
}
|
||||
|
||||
static void smp_task_done(struct sas_task *task)
|
||||
{
|
||||
if (!del_timer(&task->slow_task->timer))
|
||||
return;
|
||||
del_timer(&task->slow_task->timer);
|
||||
complete(&task->slow_task->completion);
|
||||
}
|
||||
|
||||
|
||||
@@ -345,7 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
|
||||
}
|
||||
|
||||
ha->optrom_region_start = start;
|
||||
ha->optrom_region_size = start + size;
|
||||
ha->optrom_region_size = size;
|
||||
|
||||
ha->optrom_state = QLA_SREADING;
|
||||
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
|
||||
@@ -418,7 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
|
||||
}
|
||||
|
||||
ha->optrom_region_start = start;
|
||||
ha->optrom_region_size = start + size;
|
||||
ha->optrom_region_size = size;
|
||||
|
||||
ha->optrom_state = QLA_SWRITING;
|
||||
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
|
||||
|
||||
@@ -521,7 +521,7 @@ static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy)
|
||||
|
||||
op = gb_operation_create(connection,
|
||||
GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS,
|
||||
sizeof(req), sizeof(*resp) + props_count *
|
||||
sizeof(*req), sizeof(*resp) + props_count *
|
||||
sizeof(struct gb_power_supply_props_desc),
|
||||
GFP_KERNEL);
|
||||
if (!op)
|
||||
|
||||
@@ -482,12 +482,12 @@ static void acm_read_bulk_callback(struct urb *urb)
|
||||
struct acm *acm = rb->instance;
|
||||
unsigned long flags;
|
||||
int status = urb->status;
|
||||
bool stopped = false;
|
||||
bool stalled = false;
|
||||
|
||||
dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n",
|
||||
rb->index, urb->actual_length, status);
|
||||
|
||||
set_bit(rb->index, &acm->read_urbs_free);
|
||||
|
||||
if (!acm->dev) {
|
||||
dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
|
||||
return;
|
||||
@@ -500,15 +500,16 @@ static void acm_read_bulk_callback(struct urb *urb)
|
||||
break;
|
||||
case -EPIPE:
|
||||
set_bit(EVENT_RX_STALL, &acm->flags);
|
||||
schedule_work(&acm->work);
|
||||
return;
|
||||
stalled = true;
|
||||
break;
|
||||
case -ENOENT:
|
||||
case -ECONNRESET:
|
||||
case -ESHUTDOWN:
|
||||
dev_dbg(&acm->data->dev,
|
||||
"%s - urb shutting down with status: %d\n",
|
||||
__func__, status);
|
||||
return;
|
||||
stopped = true;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&acm->data->dev,
|
||||
"%s - nonzero urb status received: %d\n",
|
||||
@@ -517,10 +518,24 @@ static void acm_read_bulk_callback(struct urb *urb)
|
||||
}
|
||||
|
||||
/*
|
||||
* Unthrottle may run on another CPU which needs to see events
|
||||
* in the same order. Submission has an implict barrier
|
||||
* Make sure URB processing is done before marking as free to avoid
|
||||
* racing with unthrottle() on another CPU. Matches the barriers
|
||||
* implied by the test_and_clear_bit() in acm_submit_read_urb().
|
||||
*/
|
||||
smp_mb__before_atomic();
|
||||
set_bit(rb->index, &acm->read_urbs_free);
|
||||
/*
|
||||
* Make sure URB is marked as free before checking the throttled flag
|
||||
* to avoid racing with unthrottle() on another CPU. Matches the
|
||||
* smp_mb() in unthrottle().
|
||||
*/
|
||||
smp_mb__after_atomic();
|
||||
|
||||
if (stopped || stalled) {
|
||||
if (stalled)
|
||||
schedule_work(&acm->work);
|
||||
return;
|
||||
}
|
||||
|
||||
/* throttle device if requested by tty */
|
||||
spin_lock_irqsave(&acm->read_lock, flags);
|
||||
@@ -854,6 +869,9 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
|
||||
acm->throttle_req = 0;
|
||||
spin_unlock_irq(&acm->read_lock);
|
||||
|
||||
/* Matches the smp_mb__after_atomic() in acm_read_bulk_callback(). */
|
||||
smp_mb();
|
||||
|
||||
if (was_throttled)
|
||||
acm_submit_read_urbs(acm, GFP_KERNEL);
|
||||
}
|
||||
|
||||
@@ -1079,7 +1079,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
|
||||
u8 hird_threshold;
|
||||
|
||||
/* default to highest possible threshold */
|
||||
lpm_nyet_threshold = 0xff;
|
||||
lpm_nyet_threshold = 0xf;
|
||||
|
||||
/* default to -3.5dB de-emphasis */
|
||||
tx_de_emphasis = 1;
|
||||
|
||||
@@ -560,9 +560,12 @@ static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
|
||||
static void f81232_close(struct usb_serial_port *port)
|
||||
{
|
||||
struct f81232_private *port_priv = usb_get_serial_port_data(port);
|
||||
|
||||
f81232_port_disable(port);
|
||||
usb_serial_generic_close(port);
|
||||
usb_kill_urb(port->interrupt_in_urb);
|
||||
flush_work(&port_priv->interrupt_work);
|
||||
}
|
||||
|
||||
static void f81232_dtr_rts(struct usb_serial_port *port, int on)
|
||||
@@ -656,6 +659,40 @@ static int f81232_port_remove(struct usb_serial_port *port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f81232_suspend(struct usb_serial *serial, pm_message_t message)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct f81232_private *port_priv = usb_get_serial_port_data(port);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
|
||||
usb_kill_urb(port->read_urbs[i]);
|
||||
|
||||
usb_kill_urb(port->interrupt_in_urb);
|
||||
|
||||
if (port_priv)
|
||||
flush_work(&port_priv->interrupt_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f81232_resume(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
int result;
|
||||
|
||||
if (tty_port_initialized(&port->port)) {
|
||||
result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
|
||||
if (result) {
|
||||
dev_err(&port->dev, "submit interrupt urb failed: %d\n",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return usb_serial_generic_resume(serial);
|
||||
}
|
||||
|
||||
static struct usb_serial_driver f81232_device = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -679,6 +716,8 @@ static struct usb_serial_driver f81232_device = {
|
||||
.read_int_callback = f81232_read_int_callback,
|
||||
.port_probe = f81232_port_probe,
|
||||
.port_remove = f81232_port_remove,
|
||||
.suspend = f81232_suspend,
|
||||
.resume = f81232_resume,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
||||
@@ -81,6 +81,7 @@ static const char* host_info(struct Scsi_Host *host)
|
||||
static int slave_alloc (struct scsi_device *sdev)
|
||||
{
|
||||
struct us_data *us = host_to_us(sdev->host);
|
||||
int maxp;
|
||||
|
||||
/*
|
||||
* Set the INQUIRY transfer length to 36. We don't use any of
|
||||
@@ -90,20 +91,17 @@ static int slave_alloc (struct scsi_device *sdev)
|
||||
sdev->inquiry_len = 36;
|
||||
|
||||
/*
|
||||
* USB has unusual DMA-alignment requirements: Although the
|
||||
* starting address of each scatter-gather element doesn't matter,
|
||||
* the length of each element except the last must be divisible
|
||||
* by the Bulk maxpacket value. There's currently no way to
|
||||
* express this by block-layer constraints, so we'll cop out
|
||||
* and simply require addresses to be aligned at 512-byte
|
||||
* boundaries. This is okay since most block I/O involves
|
||||
* hardware sectors that are multiples of 512 bytes in length,
|
||||
* and since host controllers up through USB 2.0 have maxpacket
|
||||
* values no larger than 512.
|
||||
*
|
||||
* But it doesn't suffice for Wireless USB, where Bulk maxpacket
|
||||
* values can be as large as 2048. To make that work properly
|
||||
* will require changes to the block layer.
|
||||
* USB has unusual scatter-gather requirements: the length of each
|
||||
* scatterlist element except the last must be divisible by the
|
||||
* Bulk maxpacket value. Fortunately this value is always a
|
||||
* power of 2. Inform the block layer about this requirement.
|
||||
*/
|
||||
maxp = usb_maxpacket(us->pusb_dev, us->recv_bulk_pipe, 0);
|
||||
blk_queue_virt_boundary(sdev->request_queue, maxp - 1);
|
||||
|
||||
/*
|
||||
* Some host controllers may have alignment requirements.
|
||||
* We'll play it safe by requiring 512-byte alignment always.
|
||||
*/
|
||||
blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
|
||||
|
||||
|
||||
@@ -796,24 +796,33 @@ static int uas_slave_alloc(struct scsi_device *sdev)
|
||||
{
|
||||
struct uas_dev_info *devinfo =
|
||||
(struct uas_dev_info *)sdev->host->hostdata;
|
||||
int maxp;
|
||||
|
||||
sdev->hostdata = devinfo;
|
||||
|
||||
/*
|
||||
* USB has unusual DMA-alignment requirements: Although the
|
||||
* starting address of each scatter-gather element doesn't matter,
|
||||
* the length of each element except the last must be divisible
|
||||
* by the Bulk maxpacket value. There's currently no way to
|
||||
* express this by block-layer constraints, so we'll cop out
|
||||
* and simply require addresses to be aligned at 512-byte
|
||||
* boundaries. This is okay since most block I/O involves
|
||||
* hardware sectors that are multiples of 512 bytes in length,
|
||||
* and since host controllers up through USB 2.0 have maxpacket
|
||||
* values no larger than 512.
|
||||
* We have two requirements here. We must satisfy the requirements
|
||||
* of the physical HC and the demands of the protocol, as we
|
||||
* definitely want no additional memory allocation in this path
|
||||
* ruling out using bounce buffers.
|
||||
*
|
||||
* But it doesn't suffice for Wireless USB, where Bulk maxpacket
|
||||
* values can be as large as 2048. To make that work properly
|
||||
* will require changes to the block layer.
|
||||
* For a transmission on USB to continue we must never send
|
||||
* a package that is smaller than maxpacket. Hence the length of each
|
||||
* scatterlist element except the last must be divisible by the
|
||||
* Bulk maxpacket value.
|
||||
* If the HC does not ensure that through SG,
|
||||
* the upper layer must do that. We must assume nothing
|
||||
* about the capabilities off the HC, so we use the most
|
||||
* pessimistic requirement.
|
||||
*/
|
||||
|
||||
maxp = usb_maxpacket(devinfo->udev, devinfo->data_in_pipe, 0);
|
||||
blk_queue_virt_boundary(sdev->request_queue, maxp - 1);
|
||||
|
||||
/*
|
||||
* The protocol has no requirements on alignment in the strict sense.
|
||||
* Controllers may or may not have alignment restrictions.
|
||||
* As this is not exported, we use an extremely conservative guess.
|
||||
*/
|
||||
blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
|
||||
|
||||
|
||||
@@ -254,9 +254,11 @@ void vp_del_vqs(struct virtio_device *vdev)
|
||||
for (i = 0; i < vp_dev->msix_used_vectors; ++i)
|
||||
free_irq(pci_irq_vector(vp_dev->pci_dev, i), vp_dev);
|
||||
|
||||
for (i = 0; i < vp_dev->msix_vectors; i++)
|
||||
if (vp_dev->msix_affinity_masks[i])
|
||||
free_cpumask_var(vp_dev->msix_affinity_masks[i]);
|
||||
if (vp_dev->msix_affinity_masks) {
|
||||
for (i = 0; i < vp_dev->msix_vectors; i++)
|
||||
if (vp_dev->msix_affinity_masks[i])
|
||||
free_cpumask_var(vp_dev->msix_affinity_masks[i]);
|
||||
}
|
||||
|
||||
if (vp_dev->msix_enabled) {
|
||||
/* Disable the vector used for configuration */
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
config FS_ENCRYPTION
|
||||
tristate "FS Encryption (Per-file encryption)"
|
||||
bool "FS Encryption (Per-file encryption)"
|
||||
select CRYPTO
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_CBC
|
||||
select CRYPTO_ECB
|
||||
select CRYPTO_XTS
|
||||
select CRYPTO_CTS
|
||||
select CRYPTO_CTR
|
||||
select CRYPTO_SHA256
|
||||
select KEYS
|
||||
help
|
||||
Enable encryption of files and directories. This
|
||||
feature is similar to ecryptfs, but it is more memory
|
||||
efficient since it avoids caching the encrypted and
|
||||
decrypted pages in the page cache.
|
||||
decrypted pages in the page cache. Currently Ext4,
|
||||
F2FS and UBIFS make use of this feature.
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
#ifndef _FSCRYPT_PRIVATE_H
|
||||
#define _FSCRYPT_PRIVATE_H
|
||||
|
||||
#ifndef __FS_HAS_ENCRYPTION
|
||||
#define __FS_HAS_ENCRYPTION 1
|
||||
#endif
|
||||
#include <linux/fscrypt.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <linux/pfk.h>
|
||||
|
||||
@@ -58,7 +58,7 @@ int __fscrypt_prepare_link(struct inode *inode, struct inode *dir)
|
||||
return err;
|
||||
|
||||
if (!fscrypt_has_permitted_context(dir, inode))
|
||||
return -EPERM;
|
||||
return -EXDEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -82,13 +82,13 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
if (IS_ENCRYPTED(new_dir) &&
|
||||
!fscrypt_has_permitted_context(new_dir,
|
||||
d_inode(old_dentry)))
|
||||
return -EPERM;
|
||||
return -EXDEV;
|
||||
|
||||
if ((flags & RENAME_EXCHANGE) &&
|
||||
IS_ENCRYPTED(old_dir) &&
|
||||
!fscrypt_has_permitted_context(old_dir,
|
||||
d_inode(new_dentry)))
|
||||
return -EPERM;
|
||||
return -EXDEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -151,8 +151,7 @@ EXPORT_SYMBOL(fscrypt_ioctl_get_policy);
|
||||
* malicious offline violations of this constraint, while the link and rename
|
||||
* checks are needed to prevent online violations of this constraint.
|
||||
*
|
||||
* Return: 1 if permitted, 0 if forbidden. If forbidden, the caller must fail
|
||||
* the filesystem operation with EPERM.
|
||||
* Return: 1 if permitted, 0 if forbidden.
|
||||
*/
|
||||
int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
|
||||
{
|
||||
|
||||
@@ -103,10 +103,9 @@ config EXT4_ENCRYPTION
|
||||
depends on EXT4_FS
|
||||
select FS_ENCRYPTION
|
||||
help
|
||||
Enable encryption of ext4 files and directories. This
|
||||
feature is similar to ecryptfs, but it is more memory
|
||||
efficient since it avoids caching the encrypted and
|
||||
decrypted pages in the page cache.
|
||||
This kconfig symbol is deprecated; now it just selects
|
||||
FS_ENCRYPTION. Use CONFIG_FS_ENCRYPTION=y in new config
|
||||
files
|
||||
|
||||
config EXT4_FS_ENCRYPTION
|
||||
bool "Ext4 FS Encryption"
|
||||
|
||||
@@ -110,7 +110,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
||||
int dir_has_error = 0;
|
||||
struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
|
||||
|
||||
if (ext4_encrypted_inode(inode)) {
|
||||
if (IS_ENCRYPTED(inode)) {
|
||||
err = fscrypt_get_encryption_info(inode);
|
||||
if (err && err != -ENOKEY)
|
||||
return err;
|
||||
@@ -137,7 +137,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (ext4_encrypted_inode(inode)) {
|
||||
if (IS_ENCRYPTED(inode)) {
|
||||
err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@@ -244,7 +244,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
||||
offset += ext4_rec_len_from_disk(de->rec_len,
|
||||
sb->s_blocksize);
|
||||
if (le32_to_cpu(de->inode)) {
|
||||
if (!ext4_encrypted_inode(inode)) {
|
||||
if (!IS_ENCRYPTED(inode)) {
|
||||
if (!dir_emit(ctx, de->name,
|
||||
de->name_len,
|
||||
le32_to_cpu(de->inode),
|
||||
@@ -282,9 +282,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
||||
done:
|
||||
err = 0;
|
||||
errout:
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
fscrypt_fname_free_buffer(&fstr);
|
||||
#endif
|
||||
brelse(bh);
|
||||
return err;
|
||||
}
|
||||
@@ -610,7 +608,7 @@ finished:
|
||||
|
||||
static int ext4_dir_open(struct inode * inode, struct file * filp)
|
||||
{
|
||||
if (ext4_encrypted_inode(inode))
|
||||
if (IS_ENCRYPTED(inode))
|
||||
return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <linux/compat.h>
|
||||
#endif
|
||||
|
||||
#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_EXT4_FS_ENCRYPTION)
|
||||
#include <linux/fscrypt.h>
|
||||
|
||||
/*
|
||||
@@ -1353,7 +1352,7 @@ struct ext4_super_block {
|
||||
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
|
||||
#define EXT4_MF_TEST_DUMMY_ENCRYPTION 0x0004
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
#define DUMMY_ENCRYPTION_ENABLED(sbi) (unlikely((sbi)->s_mount_flags & \
|
||||
EXT4_MF_TEST_DUMMY_ENCRYPTION))
|
||||
#else
|
||||
@@ -2084,7 +2083,7 @@ struct ext4_filename {
|
||||
const struct qstr *usr_fname;
|
||||
struct fscrypt_str disk_name;
|
||||
struct dx_hash_info hinfo;
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
struct fscrypt_str crypto_buf;
|
||||
#endif
|
||||
};
|
||||
@@ -2312,12 +2311,7 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
|
||||
struct ext4_group_desc *gdp);
|
||||
ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
|
||||
|
||||
static inline bool ext4_encrypted_inode(struct inode *inode)
|
||||
{
|
||||
return ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
static inline int ext4_fname_setup_filename(struct inode *dir,
|
||||
const struct qstr *iname,
|
||||
int lookup, struct ext4_filename *fname)
|
||||
|
||||
@@ -414,7 +414,7 @@ static inline int ext4_inode_journal_mode(struct inode *inode)
|
||||
(ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
|
||||
!test_opt(inode->i_sb, DELALLOC))) {
|
||||
/* We do not support data journalling for encrypted data */
|
||||
if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode))
|
||||
if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
|
||||
return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
|
||||
return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */
|
||||
}
|
||||
|
||||
@@ -3581,7 +3581,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
|
||||
max_zeroout = sbi->s_extent_max_zeroout_kb >>
|
||||
(inode->i_sb->s_blocksize_bits - 10);
|
||||
|
||||
if (ext4_encrypted_inode(inode))
|
||||
if (IS_ENCRYPTED(inode))
|
||||
max_zeroout = 0;
|
||||
|
||||
/*
|
||||
@@ -4927,7 +4927,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
|
||||
* leave it disabled for encrypted inodes for now. This is a
|
||||
* bug we should fix....
|
||||
*/
|
||||
if (ext4_encrypted_inode(inode) &&
|
||||
if (IS_ENCRYPTED(inode) &&
|
||||
(mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE |
|
||||
FALLOC_FL_ZERO_RANGE)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -365,7 +365,6 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||
struct vfsmount *mnt = filp->f_path.mnt;
|
||||
struct dentry *dir;
|
||||
struct path path;
|
||||
char buf[64], *cp;
|
||||
int ret;
|
||||
@@ -405,25 +404,11 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
|
||||
ext4_journal_stop(handle);
|
||||
}
|
||||
}
|
||||
if (ext4_encrypted_inode(inode)) {
|
||||
ret = fscrypt_get_encryption_info(inode);
|
||||
if (ret)
|
||||
return -EACCES;
|
||||
if (!fscrypt_has_encryption_key(inode))
|
||||
return -ENOKEY;
|
||||
}
|
||||
|
||||
dir = dget_parent(file_dentry(filp));
|
||||
if (ext4_encrypted_inode(d_inode(dir)) &&
|
||||
!fscrypt_has_permitted_context(d_inode(dir), inode)) {
|
||||
ext4_warning(inode->i_sb,
|
||||
"Inconsistent encryption contexts: %lu/%lu",
|
||||
(unsigned long) d_inode(dir)->i_ino,
|
||||
(unsigned long) inode->i_ino);
|
||||
dput(dir);
|
||||
return -EPERM;
|
||||
}
|
||||
dput(dir);
|
||||
ret = fscrypt_file_open(inode, filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Set up the jbd2_inode if we are opening the inode for
|
||||
* writing and the journal is present
|
||||
|
||||
@@ -779,7 +779,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
|
||||
if (unlikely(ext4_forced_shutdown(sbi)))
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
if ((ext4_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
|
||||
if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
|
||||
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
|
||||
!(i_flags & EXT4_EA_INODE_FL)) {
|
||||
err = fscrypt_get_encryption_info(dir);
|
||||
|
||||
@@ -415,7 +415,7 @@ int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ext4_encrypted_inode(inode))
|
||||
if (IS_ENCRYPTED(inode))
|
||||
return fscrypt_zeroout_range(inode, lblk, pblk, len);
|
||||
|
||||
ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
|
||||
@@ -1150,7 +1150,7 @@ int do_journal_get_write_access(handle_t *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
|
||||
get_block_t *get_block)
|
||||
{
|
||||
@@ -1215,7 +1215,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
|
||||
if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
|
||||
!buffer_unwritten(bh) &&
|
||||
(block_start < from || block_end > to)) {
|
||||
decrypt = ext4_encrypted_inode(inode) &&
|
||||
decrypt = IS_ENCRYPTED(inode) &&
|
||||
S_ISREG(inode->i_mode) &&
|
||||
!fscrypt_using_hardware_encryption(inode);
|
||||
ll_rw_block(REQ_OP_READ, (decrypt ? REQ_NOENCRYPT : 0),
|
||||
@@ -1315,7 +1315,7 @@ retry_journal:
|
||||
/* In case writeback began while the page was unlocked */
|
||||
wait_for_stable_page(page);
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
if (ext4_should_dioread_nolock(inode))
|
||||
ret = ext4_block_write_begin(page, pos, len,
|
||||
ext4_get_block_unwritten);
|
||||
@@ -3097,7 +3097,7 @@ retry_journal:
|
||||
/* In case writeback began while the page was unlocked */
|
||||
wait_for_stable_page(page);
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
ret = ext4_block_write_begin(page, pos, len,
|
||||
ext4_da_get_block_prep);
|
||||
#else
|
||||
@@ -3711,7 +3711,7 @@ static ssize_t ext4_direct_IO_write(struct kiocb *iocb, struct iov_iter *iter)
|
||||
dio_flags = DIO_LOCKING;
|
||||
}
|
||||
#if defined(CONFIG_EXT4_FS_ENCRYPTION)
|
||||
WARN_ON(ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)
|
||||
WARN_ON(IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)
|
||||
&& !fscrypt_using_hardware_encryption(inode));
|
||||
#endif
|
||||
ret = __blockdev_direct_IO(iocb, inode,
|
||||
@@ -3823,8 +3823,8 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
||||
ssize_t ret;
|
||||
int rw = iov_iter_rw(iter);
|
||||
|
||||
#if defined(CONFIG_EXT4_FS_ENCRYPTION)
|
||||
if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)
|
||||
#if defined(CONFIG_FS_ENCRYPTION)
|
||||
if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)
|
||||
&& !fscrypt_using_hardware_encryption(inode))
|
||||
return 0;
|
||||
#endif
|
||||
@@ -4030,7 +4030,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
|
||||
if (!buffer_uptodate(bh)) {
|
||||
err = -EIO;
|
||||
decrypt = S_ISREG(inode->i_mode) &&
|
||||
ext4_encrypted_inode(inode) &&
|
||||
IS_ENCRYPTED(inode) &&
|
||||
!fscrypt_using_hardware_encryption(inode);
|
||||
ll_rw_block(REQ_OP_READ, (decrypt ? REQ_NOENCRYPT : 0), 1, &bh);
|
||||
wait_on_buffer(bh);
|
||||
@@ -4113,12 +4113,7 @@ static int ext4_block_truncate_page(handle_t *handle,
|
||||
struct inode *inode = mapping->host;
|
||||
|
||||
/* If we are processing an encrypted inode during orphan list handling */
|
||||
if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode))
|
||||
return 0;
|
||||
|
||||
/* If we are processing an encrypted inode during orphan list
|
||||
* handling */
|
||||
if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode))
|
||||
if (IS_ENCRYPTED(inode) && !fscrypt_has_encryption_key(inode))
|
||||
return 0;
|
||||
|
||||
blocksize = inode->i_sb->s_blocksize;
|
||||
@@ -4846,6 +4841,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
* not initialized on a new filesystem. */
|
||||
}
|
||||
ei->i_flags = le32_to_cpu(raw_inode->i_flags);
|
||||
ext4_set_inode_flags(inode);
|
||||
inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
|
||||
ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
|
||||
if (ext4_has_feature_64bit(sb))
|
||||
@@ -4956,7 +4952,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
inode->i_op = &ext4_dir_inode_operations;
|
||||
inode->i_fop = &ext4_dir_operations;
|
||||
} else if (S_ISLNK(inode->i_mode)) {
|
||||
if (ext4_encrypted_inode(inode)) {
|
||||
if (IS_ENCRYPTED(inode)) {
|
||||
inode->i_op = &ext4_encrypted_symlink_inode_operations;
|
||||
ext4_set_aops(inode);
|
||||
} else if (ext4_inode_is_fast_symlink(inode)) {
|
||||
@@ -4986,7 +4982,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
|
||||
goto bad_inode;
|
||||
}
|
||||
brelse(iloc.bh);
|
||||
ext4_set_inode_flags(inode);
|
||||
|
||||
unlock_new_inode(inode);
|
||||
return inode;
|
||||
@@ -5416,6 +5411,10 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = fscrypt_prepare_setattr(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (is_quota_modification(inode, attr)) {
|
||||
error = dquot_initialize(inode);
|
||||
if (error)
|
||||
@@ -5461,14 +5460,6 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
loff_t oldsize = inode->i_size;
|
||||
int shrink = (attr->ia_size <= inode->i_size);
|
||||
|
||||
if (ext4_encrypted_inode(inode)) {
|
||||
error = fscrypt_get_encryption_info(inode);
|
||||
if (error)
|
||||
return error;
|
||||
if (!fscrypt_has_encryption_key(inode))
|
||||
return -ENOKEY;
|
||||
}
|
||||
|
||||
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
|
||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ journal_err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
static int uuid_is_zero(__u8 u[16])
|
||||
{
|
||||
int i;
|
||||
@@ -972,7 +972,7 @@ resizefs_out:
|
||||
return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
|
||||
|
||||
case EXT4_IOC_GET_ENCRYPTION_PWSALT: {
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
int err, err2;
|
||||
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
||||
handle_t *handle;
|
||||
|
||||
@@ -604,8 +604,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
|
||||
|
||||
if (!fscrypt_using_hardware_encryption(orig_inode) ||
|
||||
!fscrypt_using_hardware_encryption(donor_inode)) {
|
||||
if (ext4_encrypted_inode(orig_inode) ||
|
||||
ext4_encrypted_inode(donor_inode)) {
|
||||
if (IS_ENCRYPTED(orig_inode) || IS_ENCRYPTED(donor_inode)) {
|
||||
ext4_msg(orig_inode->i_sb, KERN_ERR,
|
||||
"Online defrag not supported for encrypted files");
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -611,7 +611,7 @@ static struct stats dx_show_leaf(struct inode *dir,
|
||||
{
|
||||
if (show_names)
|
||||
{
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
int len;
|
||||
char *name;
|
||||
struct fscrypt_str fname_crypto_str =
|
||||
@@ -620,7 +620,7 @@ static struct stats dx_show_leaf(struct inode *dir,
|
||||
|
||||
name = de->name;
|
||||
len = de->name_len;
|
||||
if (ext4_encrypted_inode(dir))
|
||||
if (IS_ENCRYPTED(dir))
|
||||
res = fscrypt_get_encryption_info(dir);
|
||||
if (res) {
|
||||
printk(KERN_WARNING "Error setting up"
|
||||
@@ -986,9 +986,9 @@ static int htree_dirblock_to_tree(struct file *dir_file,
|
||||
top = (struct ext4_dir_entry_2 *) ((char *) de +
|
||||
dir->i_sb->s_blocksize -
|
||||
EXT4_DIR_REC_LEN(0));
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
/* Check if the directory is encrypted */
|
||||
if (ext4_encrypted_inode(dir)) {
|
||||
if (IS_ENCRYPTED(dir)) {
|
||||
err = fscrypt_get_encryption_info(dir);
|
||||
if (err < 0) {
|
||||
brelse(bh);
|
||||
@@ -1017,7 +1017,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
|
||||
continue;
|
||||
if (de->inode == 0)
|
||||
continue;
|
||||
if (!ext4_encrypted_inode(dir)) {
|
||||
if (!IS_ENCRYPTED(dir)) {
|
||||
tmp_str.name = de->name;
|
||||
tmp_str.len = de->name_len;
|
||||
err = ext4_htree_store_dirent(dir_file,
|
||||
@@ -1049,7 +1049,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
|
||||
}
|
||||
errout:
|
||||
brelse(bh);
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
fscrypt_fname_free_buffer(&fname_crypto_str);
|
||||
#endif
|
||||
return count;
|
||||
@@ -1269,7 +1269,7 @@ static inline bool ext4_match(const struct ext4_filename *fname,
|
||||
|
||||
f.usr_fname = fname->usr_fname;
|
||||
f.disk_name = fname->disk_name;
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
f.crypto_buf = fname->crypto_buf;
|
||||
#endif
|
||||
return fscrypt_match_name(&f, de->name, de->name_len);
|
||||
@@ -1500,7 +1500,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
|
||||
ext4_lblk_t block;
|
||||
int retval;
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
*res_dir = NULL;
|
||||
#endif
|
||||
frame = dx_probe(fname, dir, NULL, frames);
|
||||
@@ -1580,7 +1580,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
|
||||
ino);
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
}
|
||||
if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
|
||||
if (!IS_ERR(inode) && IS_ENCRYPTED(dir) &&
|
||||
(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
|
||||
!fscrypt_has_permitted_context(dir, inode)) {
|
||||
ext4_warning(inode->i_sb,
|
||||
@@ -3193,9 +3193,10 @@ static int ext4_link(struct dentry *old_dentry,
|
||||
|
||||
if (inode->i_nlink >= EXT4_LINK_MAX)
|
||||
return -EMLINK;
|
||||
if (ext4_encrypted_inode(dir) &&
|
||||
!fscrypt_has_permitted_context(dir, inode))
|
||||
return -EPERM;
|
||||
|
||||
err = fscrypt_prepare_link(old_dentry, dir, dentry);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if ((ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) &&
|
||||
(!projid_eq(EXT4_I(dir)->i_projid,
|
||||
@@ -3493,12 +3494,6 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
EXT4_I(old_dentry->d_inode)->i_projid)))
|
||||
return -EXDEV;
|
||||
|
||||
if ((ext4_encrypted_inode(old_dir) &&
|
||||
!fscrypt_has_encryption_key(old_dir)) ||
|
||||
(ext4_encrypted_inode(new_dir) &&
|
||||
!fscrypt_has_encryption_key(new_dir)))
|
||||
return -ENOKEY;
|
||||
|
||||
retval = dquot_initialize(old.dir);
|
||||
if (retval)
|
||||
return retval;
|
||||
@@ -3527,13 +3522,6 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino)
|
||||
goto end_rename;
|
||||
|
||||
if ((old.dir != new.dir) &&
|
||||
ext4_encrypted_inode(new.dir) &&
|
||||
!fscrypt_has_permitted_context(new.dir, old.inode)) {
|
||||
retval = -EPERM;
|
||||
goto end_rename;
|
||||
}
|
||||
|
||||
new.bh = ext4_find_entry(new.dir, &new.dentry->d_name,
|
||||
&new.de, &new.inlined);
|
||||
if (IS_ERR(new.bh)) {
|
||||
@@ -3699,19 +3687,6 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
int retval;
|
||||
struct timespec ctime;
|
||||
|
||||
if ((ext4_encrypted_inode(old_dir) &&
|
||||
!fscrypt_has_encryption_key(old_dir)) ||
|
||||
(ext4_encrypted_inode(new_dir) &&
|
||||
!fscrypt_has_encryption_key(new_dir)))
|
||||
return -ENOKEY;
|
||||
|
||||
if ((ext4_encrypted_inode(old_dir) ||
|
||||
ext4_encrypted_inode(new_dir)) &&
|
||||
(old_dir != new_dir) &&
|
||||
(!fscrypt_has_permitted_context(new_dir, old.inode) ||
|
||||
!fscrypt_has_permitted_context(old_dir, new.inode)))
|
||||
return -EPERM;
|
||||
|
||||
if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT) &&
|
||||
!projid_eq(EXT4_I(new_dir)->i_projid,
|
||||
EXT4_I(old_dentry->d_inode)->i_projid)) ||
|
||||
@@ -3838,12 +3813,19 @@ static int ext4_rename2(struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry,
|
||||
unsigned int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (unlikely(ext4_forced_shutdown(EXT4_SB(old_dir->i_sb))))
|
||||
return -EIO;
|
||||
|
||||
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
|
||||
return -EINVAL;
|
||||
|
||||
err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
|
||||
flags);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (flags & RENAME_EXCHANGE) {
|
||||
return ext4_cross_rename(old_dir, old_dentry,
|
||||
new_dir, new_dentry);
|
||||
|
||||
@@ -66,7 +66,7 @@ static void ext4_finish_bio(struct bio *bio)
|
||||
|
||||
bio_for_each_segment_all(bvec, bio, i) {
|
||||
struct page *page = bvec->bv_page;
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
struct page *data_page = NULL;
|
||||
#endif
|
||||
struct buffer_head *bh, *head;
|
||||
@@ -78,7 +78,7 @@ static void ext4_finish_bio(struct bio *bio)
|
||||
if (!page)
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
if (!page->mapping) {
|
||||
/* The bounce data pages are unmapped. */
|
||||
data_page = page;
|
||||
@@ -111,7 +111,7 @@ static void ext4_finish_bio(struct bio *bio)
|
||||
bit_spin_unlock(BH_Uptodate_Lock, &head->b_state);
|
||||
local_irq_restore(flags);
|
||||
if (!under_io) {
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
if (data_page)
|
||||
fscrypt_restore_control_page(data_page);
|
||||
#endif
|
||||
@@ -480,8 +480,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
|
||||
if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
|
||||
nr_to_submit) {
|
||||
if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && nr_to_submit) {
|
||||
gfp_t gfp_flags = GFP_NOFS;
|
||||
|
||||
retry_encrypt:
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
static inline bool ext4_bio_encrypted(struct bio *bio)
|
||||
{
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
return unlikely(bio->bi_private != NULL);
|
||||
#else
|
||||
return false;
|
||||
@@ -281,8 +281,7 @@ int ext4_mpage_readpages(struct address_space *mapping,
|
||||
if (bio == NULL) {
|
||||
struct fscrypt_ctx *ctx = NULL;
|
||||
|
||||
if (ext4_encrypted_inode(inode) &&
|
||||
S_ISREG(inode->i_mode)) {
|
||||
if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) {
|
||||
ctx = fscrypt_get_ctx(inode, GFP_NOFS);
|
||||
if (IS_ERR(ctx))
|
||||
goto set_error_page;
|
||||
|
||||
@@ -1182,7 +1182,7 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
|
||||
return try_to_free_buffers(page);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
|
||||
{
|
||||
return ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
|
||||
@@ -1865,7 +1865,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
|
||||
*journal_ioprio =
|
||||
IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
|
||||
} else if (token == Opt_test_dummy_encryption) {
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
sbi->s_mount_flags |= EXT4_MF_TEST_DUMMY_ENCRYPTION;
|
||||
ext4_msg(sb, KERN_WARNING,
|
||||
"Test dummy encryption mode enabled");
|
||||
@@ -4111,7 +4111,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
||||
sb->s_op = &ext4_sops;
|
||||
sb->s_export_op = &ext4_export_ops;
|
||||
sb->s_xattr = ext4_xattr_handlers;
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
sb->s_cop = &ext4_cryptops;
|
||||
#endif
|
||||
#ifdef CONFIG_QUOTA
|
||||
|
||||
@@ -224,7 +224,7 @@ static struct attribute *ext4_attrs[] = {
|
||||
EXT4_ATTR_FEATURE(lazy_itable_init);
|
||||
EXT4_ATTR_FEATURE(batched_discard);
|
||||
EXT4_ATTR_FEATURE(meta_bg_resize);
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
EXT4_ATTR_FEATURE(encryption);
|
||||
#endif
|
||||
EXT4_ATTR_FEATURE(metadata_csum_seed);
|
||||
@@ -233,7 +233,7 @@ static struct attribute *ext4_feat_attrs[] = {
|
||||
ATTR_LIST(lazy_itable_init),
|
||||
ATTR_LIST(batched_discard),
|
||||
ATTR_LIST(meta_bg_resize),
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
ATTR_LIST(encryption),
|
||||
#endif
|
||||
ATTR_LIST(metadata_csum_seed),
|
||||
|
||||
@@ -3,6 +3,7 @@ config F2FS_FS
|
||||
depends on BLOCK
|
||||
select CRYPTO
|
||||
select CRYPTO_CRC32
|
||||
select F2FS_FS_XATTR if FS_ENCRYPTION
|
||||
help
|
||||
F2FS is based on Log-structured File System (LFS), which supports
|
||||
versatile "flash-friendly" features. The design has been focused on
|
||||
@@ -77,13 +78,11 @@ config F2FS_CHECK_FS
|
||||
config F2FS_FS_ENCRYPTION
|
||||
bool "F2FS Encryption"
|
||||
depends on F2FS_FS
|
||||
depends on F2FS_FS_XATTR
|
||||
select FS_ENCRYPTION
|
||||
help
|
||||
Enable encryption of f2fs files and directories. This
|
||||
feature is similar to ecryptfs, but it is more memory
|
||||
efficient since it avoids caching the encrypted and
|
||||
decrypted pages in the page cache.
|
||||
This kconfig symbol is deprecated; now it just selects
|
||||
FS_ENCRYPTION. Use CONFIG_FS_ENCRYPTION=y in new config
|
||||
files.
|
||||
|
||||
config F2FS_IO_TRACE
|
||||
bool "F2FS IO tracer"
|
||||
|
||||
@@ -624,7 +624,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
|
||||
f2fs_target_device(sbi, blkaddr, bio);
|
||||
bio->bi_end_io = f2fs_read_end_io;
|
||||
bio_set_op_attrs(bio, REQ_OP_READ,
|
||||
(f2fs_encrypted_inode(inode) ?
|
||||
(IS_ENCRYPTED(inode) ?
|
||||
REQ_NOENCRYPT :
|
||||
op_flag));
|
||||
|
||||
@@ -1532,7 +1532,7 @@ next:
|
||||
}
|
||||
|
||||
if (size) {
|
||||
if (f2fs_encrypted_inode(inode))
|
||||
if (IS_ENCRYPTED(inode))
|
||||
flags |= FIEMAP_EXTENT_DATA_ENCRYPTED;
|
||||
|
||||
ret = fiemap_fill_next_extent(fieinfo, logical,
|
||||
@@ -1816,7 +1816,7 @@ static inline bool check_inplace_update_policy(struct inode *inode,
|
||||
if (policy & (0x1 << F2FS_IPU_ASYNC) &&
|
||||
fio && fio->op == REQ_OP_WRITE &&
|
||||
!(fio->op_flags & REQ_SYNC) &&
|
||||
!f2fs_encrypted_inode(inode))
|
||||
!IS_ENCRYPTED(inode))
|
||||
return true;
|
||||
|
||||
/* this is only set during fdatasync */
|
||||
|
||||
@@ -385,7 +385,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
|
||||
if (err)
|
||||
goto put_error;
|
||||
|
||||
if ((f2fs_encrypted_inode(dir) || dummy_encrypt) &&
|
||||
if ((IS_ENCRYPTED(dir) || dummy_encrypt) &&
|
||||
f2fs_may_encrypt(inode)) {
|
||||
err = fscrypt_inherit_context(dir, inode, page, false);
|
||||
if (err)
|
||||
@@ -399,7 +399,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
|
||||
|
||||
if (new_name) {
|
||||
init_dent_inode(new_name, page);
|
||||
if (f2fs_encrypted_inode(dir))
|
||||
if (IS_ENCRYPTED(dir))
|
||||
file_set_enc_name(inode);
|
||||
}
|
||||
|
||||
@@ -824,7 +824,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (f2fs_encrypted_inode(d->inode)) {
|
||||
if (IS_ENCRYPTED(d->inode)) {
|
||||
int save_len = fstr->len;
|
||||
|
||||
err = fscrypt_fname_disk_to_usr(d->inode,
|
||||
@@ -867,7 +867,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
|
||||
struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
|
||||
int err = 0;
|
||||
|
||||
if (f2fs_encrypted_inode(inode)) {
|
||||
if (IS_ENCRYPTED(inode)) {
|
||||
err = fscrypt_get_encryption_info(inode);
|
||||
if (err && err != -ENOKEY)
|
||||
goto out;
|
||||
@@ -929,7 +929,7 @@ out:
|
||||
|
||||
static int f2fs_dir_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
if (f2fs_encrypted_inode(inode))
|
||||
if (IS_ENCRYPTED(inode))
|
||||
return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <crypto/hash.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_F2FS_FS_ENCRYPTION)
|
||||
#include <linux/fscrypt.h>
|
||||
|
||||
#ifdef CONFIG_F2FS_CHECK_FS
|
||||
@@ -1142,7 +1141,7 @@ enum fsync_mode {
|
||||
FSYNC_MODE_NOBARRIER, /* fsync behaves nobarrier based on posix */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
#define DUMMY_ENCRYPTION_ENABLED(sbi) \
|
||||
(unlikely(F2FS_OPTION(sbi).test_dummy_encryption))
|
||||
#else
|
||||
@@ -3493,19 +3492,14 @@ void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi);
|
||||
/*
|
||||
* crypto support
|
||||
*/
|
||||
static inline bool f2fs_encrypted_inode(struct inode *inode)
|
||||
{
|
||||
return file_is_encrypt(inode);
|
||||
}
|
||||
|
||||
static inline bool f2fs_encrypted_file(struct inode *inode)
|
||||
{
|
||||
return f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode);
|
||||
return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
|
||||
}
|
||||
|
||||
static inline void f2fs_set_encrypted_inode(struct inode *inode)
|
||||
{
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
file_set_encrypt(inode);
|
||||
f2fs_set_inode_flags(inode);
|
||||
#endif
|
||||
@@ -3584,7 +3578,7 @@ static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)
|
||||
|
||||
static inline bool f2fs_may_encrypt(struct inode *inode)
|
||||
{
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
umode_t mode = inode->i_mode;
|
||||
|
||||
return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));
|
||||
|
||||
@@ -582,7 +582,7 @@ truncate_out:
|
||||
zero_user(page, offset, PAGE_SIZE - offset);
|
||||
|
||||
/* An encrypted inode should have a key and truncate the last page. */
|
||||
f2fs_bug_on(F2FS_I_SB(inode), cache_only && f2fs_encrypted_inode(inode));
|
||||
f2fs_bug_on(F2FS_I_SB(inode), cache_only && IS_ENCRYPTED(inode));
|
||||
if (!cache_only)
|
||||
set_page_dirty(page);
|
||||
f2fs_put_page(page, 1);
|
||||
@@ -709,7 +709,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
|
||||
stat->attributes |= STATX_ATTR_APPEND;
|
||||
if (flags & F2FS_COMPR_FL)
|
||||
stat->attributes |= STATX_ATTR_COMPRESSED;
|
||||
if (f2fs_encrypted_inode(inode))
|
||||
if (IS_ENCRYPTED(inode))
|
||||
stat->attributes |= STATX_ATTR_ENCRYPTED;
|
||||
if (flags & F2FS_IMMUTABLE_FL)
|
||||
stat->attributes |= STATX_ATTR_IMMUTABLE;
|
||||
@@ -1558,7 +1558,7 @@ static long f2fs_fallocate(struct file *file, int mode,
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if (f2fs_encrypted_inode(inode) &&
|
||||
if (IS_ENCRYPTED(inode) &&
|
||||
(mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -1642,7 +1642,7 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
unsigned int flags = fi->i_flags;
|
||||
|
||||
if (f2fs_encrypted_inode(inode))
|
||||
if (IS_ENCRYPTED(inode))
|
||||
flags |= F2FS_ENCRYPT_FL;
|
||||
if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
|
||||
flags |= F2FS_INLINE_DATA_FL;
|
||||
@@ -2416,7 +2416,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
|
||||
if (!S_ISREG(src->i_mode) || !S_ISREG(dst->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if (f2fs_encrypted_inode(src) || f2fs_encrypted_inode(dst))
|
||||
if (IS_ENCRYPTED(src) || IS_ENCRYPTED(dst))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (src == dst) {
|
||||
|
||||
@@ -44,7 +44,7 @@ void f2fs_set_inode_flags(struct inode *inode)
|
||||
new_fl |= S_NOATIME;
|
||||
if (flags & F2FS_DIRSYNC_FL)
|
||||
new_fl |= S_DIRSYNC;
|
||||
if (f2fs_encrypted_inode(inode))
|
||||
if (file_is_encrypt(inode))
|
||||
new_fl |= S_ENCRYPTED;
|
||||
inode_set_flags(inode, new_fl,
|
||||
S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|
|
||||
@@ -468,7 +468,7 @@ make_now:
|
||||
inode->i_mapping->a_ops = &f2fs_dblock_aops;
|
||||
inode_nohighmem(inode);
|
||||
} else if (S_ISLNK(inode->i_mode)) {
|
||||
if (f2fs_encrypted_inode(inode))
|
||||
if (file_is_encrypt(inode))
|
||||
inode->i_op = &f2fs_encrypted_symlink_inode_operations;
|
||||
else
|
||||
inode->i_op = &f2fs_symlink_inode_operations;
|
||||
|
||||
@@ -76,7 +76,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
|
||||
set_inode_flag(inode, FI_NEW_INODE);
|
||||
|
||||
/* If the directory encrypted, then we should encrypt the inode. */
|
||||
if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
|
||||
if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
|
||||
f2fs_may_encrypt(inode))
|
||||
f2fs_set_encrypted_inode(inode);
|
||||
|
||||
@@ -477,7 +477,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
if (err)
|
||||
goto out_iput;
|
||||
}
|
||||
if (f2fs_encrypted_inode(dir) &&
|
||||
if (IS_ENCRYPTED(dir) &&
|
||||
(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
|
||||
!fscrypt_has_permitted_context(dir, inode)) {
|
||||
f2fs_msg(inode->i_sb, KERN_WARNING,
|
||||
@@ -804,7 +804,7 @@ static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
if (unlikely(f2fs_cp_error(sbi)))
|
||||
return -EIO;
|
||||
|
||||
if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
|
||||
if (IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
|
||||
int err = fscrypt_get_encryption_info(dir);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -757,7 +757,7 @@ static int parse_options(struct super_block *sb, char *options)
|
||||
kvfree(name);
|
||||
break;
|
||||
case Opt_test_dummy_encryption:
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
if (!f2fs_sb_has_encrypt(sbi)) {
|
||||
f2fs_msg(sb, KERN_ERR, "Encrypt feature is off");
|
||||
return -EINVAL;
|
||||
@@ -1418,7 +1418,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
|
||||
seq_printf(seq, ",whint_mode=%s", "user-based");
|
||||
else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS)
|
||||
seq_printf(seq, ",whint_mode=%s", "fs-based");
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
if (F2FS_OPTION(sbi).test_dummy_encryption)
|
||||
seq_puts(seq, ",test_dummy_encryption");
|
||||
#endif
|
||||
@@ -2204,7 +2204,7 @@ static const struct super_operations f2fs_sops = {
|
||||
.remount_fs = f2fs_remount,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
static int f2fs_get_context(struct inode *inode, void *ctx, size_t len)
|
||||
{
|
||||
return f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
|
||||
@@ -3168,7 +3168,7 @@ try_onemore:
|
||||
#endif
|
||||
|
||||
sb->s_op = &f2fs_sops;
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
sb->s_cop = &f2fs_cryptops;
|
||||
#endif
|
||||
sb->s_xattr = f2fs_xattr_handlers;
|
||||
|
||||
@@ -441,7 +441,7 @@ F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
|
||||
F2FS_GENERAL_RO_ATTR(features);
|
||||
F2FS_GENERAL_RO_ATTR(current_reserved_blocks);
|
||||
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
|
||||
#endif
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
@@ -503,7 +503,7 @@ static struct attribute *f2fs_attrs[] = {
|
||||
};
|
||||
|
||||
static struct attribute *f2fs_feat_attrs[] = {
|
||||
#ifdef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
ATTR_LIST(encryption),
|
||||
#endif
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
|
||||
@@ -57,10 +57,9 @@ config UBIFS_FS_ENCRYPTION
|
||||
select FS_ENCRYPTION
|
||||
default n
|
||||
help
|
||||
Enable encryption of UBIFS files and directories. This
|
||||
feature is similar to ecryptfs, but it is more memory
|
||||
efficient since it avoids caching the encrypted and
|
||||
decrypted pages in the page cache.
|
||||
This kconfig symbol is deprecated; now it just selects
|
||||
FS_ENCRYPTION. Use CONFIG_FS_ENCRYPTION=y in new config
|
||||
files
|
||||
|
||||
config UBIFS_FS_SECURITY
|
||||
bool "UBIFS Security Labels"
|
||||
|
||||
@@ -6,4 +6,4 @@ ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
|
||||
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
|
||||
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o
|
||||
ubifs-y += misc.o
|
||||
ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o
|
||||
ubifs-$(CONFIG_FS_ENCRYPTION) += crypto.o
|
||||
|
||||
@@ -185,7 +185,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
return err;
|
||||
}
|
||||
case FS_IOC_SET_ENCRYPTION_POLICY: {
|
||||
#ifdef CONFIG_UBIFS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
struct ubifs_info *c = inode->i_sb->s_fs_info;
|
||||
|
||||
err = ubifs_enable_encryption(c);
|
||||
@@ -198,7 +198,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
#endif
|
||||
}
|
||||
case FS_IOC_GET_ENCRYPTION_POLICY: {
|
||||
#ifdef CONFIG_UBIFS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
return fscrypt_ioctl_get_policy(file, (void __user *)arg);
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -647,7 +647,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_UBIFS_FS_ENCRYPTION
|
||||
#ifndef CONFIG_FS_ENCRYPTION
|
||||
if (c->encrypted) {
|
||||
ubifs_err(c, "file system contains encrypted files but UBIFS"
|
||||
" was built without crypto support.");
|
||||
|
||||
@@ -2056,7 +2056,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
|
||||
sb->s_op = &ubifs_super_operations;
|
||||
sb->s_xattr = ubifs_xattr_handlers;
|
||||
#ifdef CONFIG_UBIFS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
sb->s_cop = &ubifs_crypt_operations;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <linux/xattr.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_UBIFS_FS_ENCRYPTION)
|
||||
#include <linux/fscrypt.h>
|
||||
|
||||
#include "ubifs-media.h"
|
||||
@@ -139,7 +138,7 @@
|
||||
*/
|
||||
#define WORST_COMPR_FACTOR 2
|
||||
|
||||
#ifdef CONFIG_UBIFS_FS_ENCRYPTION
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
#define UBIFS_CIPHER_BLOCK_SIZE FS_CRYPTO_BLOCK_SIZE
|
||||
#else
|
||||
#define UBIFS_CIPHER_BLOCK_SIZE 0
|
||||
@@ -1808,7 +1807,7 @@ int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len,
|
||||
#include "misc.h"
|
||||
#include "key.h"
|
||||
|
||||
#ifndef CONFIG_UBIFS_FS_ENCRYPTION
|
||||
#ifndef CONFIG_FS_ENCRYPTION
|
||||
static inline int ubifs_encrypt(const struct inode *inode,
|
||||
struct ubifs_data_node *dn,
|
||||
unsigned int in_len, unsigned int *out_len,
|
||||
|
||||
@@ -667,7 +667,7 @@ struct inode {
|
||||
struct fsnotify_mark_connector __rcu *i_fsnotify_marks;
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
struct fscrypt_info *i_crypt_info;
|
||||
#endif
|
||||
|
||||
@@ -1362,8 +1362,9 @@ struct super_block {
|
||||
void *s_security;
|
||||
#endif
|
||||
const struct xattr_handler **s_xattr;
|
||||
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
const struct fscrypt_operations *s_cop;
|
||||
#endif
|
||||
|
||||
struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
|
||||
struct list_head s_mounts; /* list of mounts; _not_ for fs use */
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
/*
|
||||
* fscrypt.h: declarations for per-file encryption
|
||||
*
|
||||
* Filesystems that implement per-file encryption include this header
|
||||
* file with the __FS_HAS_ENCRYPTION set according to whether that filesystem
|
||||
* is being built with encryption support or not.
|
||||
* Filesystems that implement per-file encryption must include this header
|
||||
* file.
|
||||
*
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
*
|
||||
@@ -15,6 +14,8 @@
|
||||
#define _LINUX_FSCRYPT_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define FS_CRYPTO_BLOCK_SIZE 16
|
||||
|
||||
@@ -47,11 +48,411 @@ struct fscrypt_name {
|
||||
/* Maximum value for the third parameter of fscrypt_operations.set_context(). */
|
||||
#define FSCRYPT_SET_CONTEXT_MAX_SIZE 28
|
||||
|
||||
#if __FS_HAS_ENCRYPTION
|
||||
#include <linux/fscrypt_supp.h>
|
||||
#else
|
||||
#include <linux/fscrypt_notsupp.h>
|
||||
#endif
|
||||
#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 *, void *, size_t);
|
||||
int (*set_context)(struct inode *, const void *, size_t, void *);
|
||||
bool (*dummy_context)(struct inode *);
|
||||
bool (*empty_dir)(struct inode *);
|
||||
unsigned int max_namelen;
|
||||
bool (*is_encrypted)(struct inode *);
|
||||
};
|
||||
|
||||
struct fscrypt_ctx {
|
||||
union {
|
||||
struct {
|
||||
struct page *bounce_page; /* Ciphertext page */
|
||||
struct page *control_page; /* Original page */
|
||||
} w;
|
||||
struct {
|
||||
struct bio *bio;
|
||||
struct work_struct work;
|
||||
} r;
|
||||
struct list_head free_list; /* Free list */
|
||||
};
|
||||
u8 flags; /* Flags */
|
||||
};
|
||||
|
||||
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
||||
{
|
||||
return (inode->i_crypt_info != NULL);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return inode->i_sb->s_cop->dummy_context &&
|
||||
inode->i_sb->s_cop->dummy_context(inode);
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
extern void fscrypt_enqueue_decrypt_work(struct work_struct *);
|
||||
extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
|
||||
extern void fscrypt_release_ctx(struct fscrypt_ctx *);
|
||||
extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
|
||||
unsigned int, unsigned int,
|
||||
u64, gfp_t);
|
||||
extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int,
|
||||
unsigned int, u64);
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
|
||||
}
|
||||
|
||||
extern void fscrypt_restore_control_page(struct page *);
|
||||
|
||||
/* policy.c */
|
||||
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
|
||||
extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
|
||||
extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
|
||||
extern int fscrypt_inherit_context(struct inode *, struct inode *,
|
||||
void *, bool);
|
||||
/* keyinfo.c */
|
||||
extern int fscrypt_get_encryption_info(struct inode *);
|
||||
extern void fscrypt_put_encryption_info(struct inode *);
|
||||
|
||||
/* fname.c */
|
||||
extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
|
||||
int lookup, struct fscrypt_name *);
|
||||
|
||||
static inline void fscrypt_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
kfree(fname->crypto_buf.name);
|
||||
}
|
||||
|
||||
extern int fscrypt_fname_alloc_buffer(const struct inode *, u32,
|
||||
struct fscrypt_str *);
|
||||
extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
|
||||
extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
|
||||
const struct fscrypt_str *, struct fscrypt_str *);
|
||||
|
||||
#define FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE 32
|
||||
|
||||
/* Extracts the second-to-last ciphertext block; see explanation below */
|
||||
#define FSCRYPT_FNAME_DIGEST(name, len) \
|
||||
((name) + round_down((len) - FS_CRYPTO_BLOCK_SIZE - 1, \
|
||||
FS_CRYPTO_BLOCK_SIZE))
|
||||
|
||||
#define FSCRYPT_FNAME_DIGEST_SIZE FS_CRYPTO_BLOCK_SIZE
|
||||
|
||||
/**
|
||||
* fscrypt_digested_name - alternate identifier for an on-disk filename
|
||||
*
|
||||
* When userspace lists an encrypted directory without access to the key,
|
||||
* filenames whose ciphertext is longer than FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE
|
||||
* bytes are shown in this abbreviated form (base64-encoded) rather than as the
|
||||
* full ciphertext (base64-encoded). This is necessary to allow supporting
|
||||
* filenames up to NAME_MAX bytes, since base64 encoding expands the length.
|
||||
*
|
||||
* To make it possible for filesystems to still find the correct directory entry
|
||||
* despite not knowing the full on-disk name, we encode any filesystem-specific
|
||||
* 'hash' and/or 'minor_hash' which the filesystem may need for its lookups,
|
||||
* followed by the second-to-last ciphertext block of the filename. Due to the
|
||||
* use of the CBC-CTS encryption mode, the second-to-last ciphertext block
|
||||
* depends on the full plaintext. (Note that ciphertext stealing causes the
|
||||
* last two blocks to appear "flipped".) This makes accidental collisions very
|
||||
* unlikely: just a 1 in 2^128 chance for two filenames to collide even if they
|
||||
* share the same filesystem-specific hashes.
|
||||
*
|
||||
* However, this scheme isn't immune to intentional collisions, which can be
|
||||
* created by anyone able to create arbitrary plaintext filenames and view them
|
||||
* without the key. Making the "digest" be a real cryptographic hash like
|
||||
* SHA-256 over the full ciphertext would prevent this, although it would be
|
||||
* less efficient and harder to implement, especially since the filesystem would
|
||||
* need to calculate it for each directory entry examined during a search.
|
||||
*/
|
||||
struct fscrypt_digested_name {
|
||||
u32 hash;
|
||||
u32 minor_hash;
|
||||
u8 digest[FSCRYPT_FNAME_DIGEST_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* fscrypt_match_name() - test whether the given name matches a directory entry
|
||||
* @fname: the name being searched for
|
||||
* @de_name: the name from the directory entry
|
||||
* @de_name_len: the length of @de_name in bytes
|
||||
*
|
||||
* Normally @fname->disk_name will be set, and in that case we simply compare
|
||||
* that to the name stored in the directory entry. The only exception is that
|
||||
* if we don't have the key for an encrypted directory and a filename in it is
|
||||
* very long, then we won't have the full disk_name and we'll instead need to
|
||||
* match against the fscrypt_digested_name.
|
||||
*
|
||||
* Return: %true if the name matches, otherwise %false.
|
||||
*/
|
||||
static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
const u8 *de_name, u32 de_name_len)
|
||||
{
|
||||
if (unlikely(!fname->disk_name.name)) {
|
||||
const struct fscrypt_digested_name *n =
|
||||
(const void *)fname->crypto_buf.name;
|
||||
if (WARN_ON_ONCE(fname->usr_fname->name[0] != '_'))
|
||||
return false;
|
||||
if (de_name_len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE)
|
||||
return false;
|
||||
return !memcmp(FSCRYPT_FNAME_DIGEST(de_name, de_name_len),
|
||||
n->digest, FSCRYPT_FNAME_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
if (de_name_len != fname->disk_name.len)
|
||||
return false;
|
||||
return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
extern void fscrypt_decrypt_bio(struct bio *);
|
||||
extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio);
|
||||
extern void fscrypt_pullback_bio_page(struct page **, bool);
|
||||
extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
|
||||
unsigned int);
|
||||
|
||||
/* hooks.c */
|
||||
extern int fscrypt_file_open(struct inode *inode, struct file *filp);
|
||||
extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir);
|
||||
extern int __fscrypt_prepare_rename(struct inode *old_dir,
|
||||
struct dentry *old_dentry,
|
||||
struct inode *new_dir,
|
||||
struct dentry *new_dentry,
|
||||
unsigned int flags);
|
||||
extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry);
|
||||
extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
|
||||
unsigned int len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern 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_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_encrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len,
|
||||
unsigned int offs,
|
||||
u64 lblk_num, gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline int fscrypt_decrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len, unsigned int offs,
|
||||
u64 lblk_num)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static inline void fscrypt_restore_control_page(struct page *page)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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_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;
|
||||
}
|
||||
|
||||
/* keyinfo.c */
|
||||
static inline int fscrypt_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_put_encryption_info(struct inode *inode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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(struct fscrypt_name));
|
||||
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(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);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
static inline void fscrypt_decrypt_bio(struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_pullback_bio_page(struct page **page, bool restore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
/**
|
||||
* fscrypt_require_key - require an inode's encryption key
|
||||
@@ -94,7 +495,7 @@ static inline int fscrypt_require_key(struct inode *inode)
|
||||
* in an encrypted directory tree use the same encryption policy.
|
||||
*
|
||||
* Return: 0 on success, -ENOKEY if the directory's encryption key is missing,
|
||||
* -EPERM if the link would result in an inconsistent encryption policy, or
|
||||
* -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,
|
||||
@@ -124,7 +525,7 @@ static inline int fscrypt_prepare_link(struct dentry *old_dentry,
|
||||
* 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, -EPERM if the
|
||||
* 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,
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* fscrypt_notsupp.h
|
||||
*
|
||||
* This stubs out the fscrypt functions for filesystems configured without
|
||||
* encryption support.
|
||||
*
|
||||
* Do not include this file directly. Use fscrypt.h instead!
|
||||
*/
|
||||
#ifndef _LINUX_FSCRYPT_H
|
||||
#error "Incorrect include of linux/fscrypt_notsupp.h!"
|
||||
#endif
|
||||
|
||||
#ifndef _LINUX_FSCRYPT_NOTSUPP_H
|
||||
#define _LINUX_FSCRYPT_NOTSUPP_H
|
||||
|
||||
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_encrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len,
|
||||
unsigned int offs,
|
||||
u64 lblk_num, gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline int fscrypt_decrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len, unsigned int offs,
|
||||
u64 lblk_num)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static inline void fscrypt_restore_control_page(struct page *page)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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_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;
|
||||
}
|
||||
|
||||
/* keyinfo.c */
|
||||
static inline int fscrypt_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_put_encryption_info(struct inode *inode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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(struct fscrypt_name));
|
||||
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(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);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
static inline void fscrypt_decrypt_bio(struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_pullback_bio_page(struct page **page, bool restore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
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 /* _LINUX_FSCRYPT_NOTSUPP_H */
|
||||
@@ -1,205 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* fscrypt_supp.h
|
||||
*
|
||||
* Do not include this file directly. Use fscrypt.h instead!
|
||||
*/
|
||||
#ifndef _LINUX_FSCRYPT_H
|
||||
#error "Incorrect include of linux/fscrypt_supp.h!"
|
||||
#endif
|
||||
|
||||
#ifndef _LINUX_FSCRYPT_SUPP_H
|
||||
#define _LINUX_FSCRYPT_SUPP_H
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/*
|
||||
* 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 *, void *, size_t);
|
||||
int (*set_context)(struct inode *, const void *, size_t, void *);
|
||||
bool (*dummy_context)(struct inode *);
|
||||
bool (*empty_dir)(struct inode *);
|
||||
unsigned int max_namelen;
|
||||
bool (*is_encrypted)(struct inode *);
|
||||
};
|
||||
|
||||
struct fscrypt_ctx {
|
||||
union {
|
||||
struct {
|
||||
struct page *bounce_page; /* Ciphertext page */
|
||||
struct page *control_page; /* Original page */
|
||||
} w;
|
||||
struct {
|
||||
struct bio *bio;
|
||||
struct work_struct work;
|
||||
} r;
|
||||
struct list_head free_list; /* Free list */
|
||||
};
|
||||
u8 flags; /* Flags */
|
||||
};
|
||||
|
||||
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
||||
{
|
||||
return (inode->i_crypt_info != NULL);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return inode->i_sb->s_cop->dummy_context &&
|
||||
inode->i_sb->s_cop->dummy_context(inode);
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
extern void fscrypt_enqueue_decrypt_work(struct work_struct *);
|
||||
extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
|
||||
extern void fscrypt_release_ctx(struct fscrypt_ctx *);
|
||||
extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
|
||||
unsigned int, unsigned int,
|
||||
u64, gfp_t);
|
||||
extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int,
|
||||
unsigned int, u64);
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
|
||||
}
|
||||
|
||||
extern void fscrypt_restore_control_page(struct page *);
|
||||
|
||||
/* policy.c */
|
||||
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
|
||||
extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
|
||||
extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
|
||||
extern int fscrypt_inherit_context(struct inode *, struct inode *,
|
||||
void *, bool);
|
||||
/* keyinfo.c */
|
||||
extern int fscrypt_get_encryption_info(struct inode *);
|
||||
extern void fscrypt_put_encryption_info(struct inode *);
|
||||
|
||||
/* fname.c */
|
||||
extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
|
||||
int lookup, struct fscrypt_name *);
|
||||
|
||||
static inline void fscrypt_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
kfree(fname->crypto_buf.name);
|
||||
}
|
||||
|
||||
extern int fscrypt_fname_alloc_buffer(const struct inode *, u32,
|
||||
struct fscrypt_str *);
|
||||
extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
|
||||
extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
|
||||
const struct fscrypt_str *, struct fscrypt_str *);
|
||||
|
||||
#define FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE 32
|
||||
|
||||
/* Extracts the second-to-last ciphertext block; see explanation below */
|
||||
#define FSCRYPT_FNAME_DIGEST(name, len) \
|
||||
((name) + round_down((len) - FS_CRYPTO_BLOCK_SIZE - 1, \
|
||||
FS_CRYPTO_BLOCK_SIZE))
|
||||
|
||||
#define FSCRYPT_FNAME_DIGEST_SIZE FS_CRYPTO_BLOCK_SIZE
|
||||
|
||||
/**
|
||||
* fscrypt_digested_name - alternate identifier for an on-disk filename
|
||||
*
|
||||
* When userspace lists an encrypted directory without access to the key,
|
||||
* filenames whose ciphertext is longer than FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE
|
||||
* bytes are shown in this abbreviated form (base64-encoded) rather than as the
|
||||
* full ciphertext (base64-encoded). This is necessary to allow supporting
|
||||
* filenames up to NAME_MAX bytes, since base64 encoding expands the length.
|
||||
*
|
||||
* To make it possible for filesystems to still find the correct directory entry
|
||||
* despite not knowing the full on-disk name, we encode any filesystem-specific
|
||||
* 'hash' and/or 'minor_hash' which the filesystem may need for its lookups,
|
||||
* followed by the second-to-last ciphertext block of the filename. Due to the
|
||||
* use of the CBC-CTS encryption mode, the second-to-last ciphertext block
|
||||
* depends on the full plaintext. (Note that ciphertext stealing causes the
|
||||
* last two blocks to appear "flipped".) This makes accidental collisions very
|
||||
* unlikely: just a 1 in 2^128 chance for two filenames to collide even if they
|
||||
* share the same filesystem-specific hashes.
|
||||
*
|
||||
* However, this scheme isn't immune to intentional collisions, which can be
|
||||
* created by anyone able to create arbitrary plaintext filenames and view them
|
||||
* without the key. Making the "digest" be a real cryptographic hash like
|
||||
* SHA-256 over the full ciphertext would prevent this, although it would be
|
||||
* less efficient and harder to implement, especially since the filesystem would
|
||||
* need to calculate it for each directory entry examined during a search.
|
||||
*/
|
||||
struct fscrypt_digested_name {
|
||||
u32 hash;
|
||||
u32 minor_hash;
|
||||
u8 digest[FSCRYPT_FNAME_DIGEST_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* fscrypt_match_name() - test whether the given name matches a directory entry
|
||||
* @fname: the name being searched for
|
||||
* @de_name: the name from the directory entry
|
||||
* @de_name_len: the length of @de_name in bytes
|
||||
*
|
||||
* Normally @fname->disk_name will be set, and in that case we simply compare
|
||||
* that to the name stored in the directory entry. The only exception is that
|
||||
* if we don't have the key for an encrypted directory and a filename in it is
|
||||
* very long, then we won't have the full disk_name and we'll instead need to
|
||||
* match against the fscrypt_digested_name.
|
||||
*
|
||||
* Return: %true if the name matches, otherwise %false.
|
||||
*/
|
||||
static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
const u8 *de_name, u32 de_name_len)
|
||||
{
|
||||
if (unlikely(!fname->disk_name.name)) {
|
||||
const struct fscrypt_digested_name *n =
|
||||
(const void *)fname->crypto_buf.name;
|
||||
if (WARN_ON_ONCE(fname->usr_fname->name[0] != '_'))
|
||||
return false;
|
||||
if (de_name_len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE)
|
||||
return false;
|
||||
return !memcmp(FSCRYPT_FNAME_DIGEST(de_name, de_name_len),
|
||||
n->digest, FSCRYPT_FNAME_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
if (de_name_len != fname->disk_name.len)
|
||||
return false;
|
||||
return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
extern void fscrypt_decrypt_bio(struct bio *);
|
||||
extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio);
|
||||
extern void fscrypt_pullback_bio_page(struct page **, bool);
|
||||
extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
|
||||
unsigned int);
|
||||
|
||||
/* hooks.c */
|
||||
extern int fscrypt_file_open(struct inode *inode, struct file *filp);
|
||||
extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir);
|
||||
extern int __fscrypt_prepare_rename(struct inode *old_dir,
|
||||
struct dentry *old_dentry,
|
||||
struct inode *new_dir,
|
||||
struct dentry *new_dentry,
|
||||
unsigned int flags);
|
||||
extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry);
|
||||
extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
|
||||
unsigned int len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
|
||||
unsigned int max_size,
|
||||
struct delayed_call *done);
|
||||
|
||||
#endif /* _LINUX_FSCRYPT_SUPP_H */
|
||||
@@ -72,8 +72,8 @@
|
||||
|
||||
#define u64_to_user_ptr(x) ( \
|
||||
{ \
|
||||
typecheck(u64, x); \
|
||||
(void __user *)(uintptr_t)x; \
|
||||
typecheck(u64, (x)); \
|
||||
(void __user *)(uintptr_t)(x); \
|
||||
} \
|
||||
)
|
||||
|
||||
|
||||
@@ -178,6 +178,9 @@ struct adv_info {
|
||||
|
||||
#define HCI_MAX_SHORT_NAME_LENGTH 10
|
||||
|
||||
/* Min encryption key size to match with SMP */
|
||||
#define HCI_MIN_ENC_KEY_SIZE 7
|
||||
|
||||
/* Default LE RPA expiry time, 15 minutes */
|
||||
#define HCI_DEFAULT_RPA_TIMEOUT (15 * 60)
|
||||
|
||||
|
||||
188
kernel/futex.c
188
kernel/futex.c
@@ -1324,13 +1324,15 @@ static int lookup_pi_state(u32 __user *uaddr, u32 uval,
|
||||
|
||||
static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval)
|
||||
{
|
||||
int err;
|
||||
u32 uninitialized_var(curval);
|
||||
|
||||
if (unlikely(should_fail_futex(true)))
|
||||
return -EFAULT;
|
||||
|
||||
if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)))
|
||||
return -EFAULT;
|
||||
err = cmpxchg_futex_value_locked(&curval, uaddr, uval, newval);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
/* If user space value changed, let the caller retry */
|
||||
return curval != uval ? -EAGAIN : 0;
|
||||
@@ -1516,10 +1518,8 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_
|
||||
if (unlikely(should_fail_futex(true)))
|
||||
ret = -EFAULT;
|
||||
|
||||
if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) {
|
||||
ret = -EFAULT;
|
||||
|
||||
} else if (curval != uval) {
|
||||
ret = cmpxchg_futex_value_locked(&curval, uaddr, uval, newval);
|
||||
if (!ret && (curval != uval)) {
|
||||
/*
|
||||
* If a unconditional UNLOCK_PI operation (user space did not
|
||||
* try the TID->0 transition) raced with a waiter setting the
|
||||
@@ -1714,32 +1714,32 @@ retry_private:
|
||||
double_lock_hb(hb1, hb2);
|
||||
op_ret = futex_atomic_op_inuser(op, uaddr2);
|
||||
if (unlikely(op_ret < 0)) {
|
||||
|
||||
double_unlock_hb(hb1, hb2);
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
/*
|
||||
* we don't get EFAULT from MMU faults if we don't have an MMU,
|
||||
* but we might get them from range checking
|
||||
*/
|
||||
ret = op_ret;
|
||||
goto out_put_keys;
|
||||
#endif
|
||||
|
||||
if (unlikely(op_ret != -EFAULT)) {
|
||||
if (!IS_ENABLED(CONFIG_MMU) ||
|
||||
unlikely(op_ret != -EFAULT && op_ret != -EAGAIN)) {
|
||||
/*
|
||||
* we don't get EFAULT from MMU faults if we don't have
|
||||
* an MMU, but we might get them from range checking
|
||||
*/
|
||||
ret = op_ret;
|
||||
goto out_put_keys;
|
||||
}
|
||||
|
||||
ret = fault_in_user_writeable(uaddr2);
|
||||
if (ret)
|
||||
goto out_put_keys;
|
||||
if (op_ret == -EFAULT) {
|
||||
ret = fault_in_user_writeable(uaddr2);
|
||||
if (ret)
|
||||
goto out_put_keys;
|
||||
}
|
||||
|
||||
if (!(flags & FLAGS_SHARED))
|
||||
if (!(flags & FLAGS_SHARED)) {
|
||||
cond_resched();
|
||||
goto retry_private;
|
||||
}
|
||||
|
||||
put_futex_key(&key2);
|
||||
put_futex_key(&key1);
|
||||
cond_resched();
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@@ -2364,7 +2364,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
|
||||
u32 uval, uninitialized_var(curval), newval;
|
||||
struct task_struct *oldowner, *newowner;
|
||||
u32 newtid;
|
||||
int ret;
|
||||
int ret, err = 0;
|
||||
|
||||
lockdep_assert_held(q->lock_ptr);
|
||||
|
||||
@@ -2435,14 +2435,17 @@ retry:
|
||||
if (!pi_state->owner)
|
||||
newtid |= FUTEX_OWNER_DIED;
|
||||
|
||||
if (get_futex_value_locked(&uval, uaddr))
|
||||
goto handle_fault;
|
||||
err = get_futex_value_locked(&uval, uaddr);
|
||||
if (err)
|
||||
goto handle_err;
|
||||
|
||||
for (;;) {
|
||||
newval = (uval & FUTEX_OWNER_DIED) | newtid;
|
||||
|
||||
if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
|
||||
goto handle_fault;
|
||||
err = cmpxchg_futex_value_locked(&curval, uaddr, uval, newval);
|
||||
if (err)
|
||||
goto handle_err;
|
||||
|
||||
if (curval == uval)
|
||||
break;
|
||||
uval = curval;
|
||||
@@ -2470,23 +2473,37 @@ retry:
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* To handle the page fault we need to drop the locks here. That gives
|
||||
* the other task (either the highest priority waiter itself or the
|
||||
* task which stole the rtmutex) the chance to try the fixup of the
|
||||
* pi_state. So once we are back from handling the fault we need to
|
||||
* check the pi_state after reacquiring the locks and before trying to
|
||||
* do another fixup. When the fixup has been done already we simply
|
||||
* return.
|
||||
* In order to reschedule or handle a page fault, we need to drop the
|
||||
* locks here. In the case of a fault, this gives the other task
|
||||
* (either the highest priority waiter itself or the task which stole
|
||||
* the rtmutex) the chance to try the fixup of the pi_state. So once we
|
||||
* are back from handling the fault we need to check the pi_state after
|
||||
* reacquiring the locks and before trying to do another fixup. When
|
||||
* the fixup has been done already we simply return.
|
||||
*
|
||||
* Note: we hold both hb->lock and pi_mutex->wait_lock. We can safely
|
||||
* drop hb->lock since the caller owns the hb -> futex_q relation.
|
||||
* Dropping the pi_mutex->wait_lock requires the state revalidate.
|
||||
*/
|
||||
handle_fault:
|
||||
handle_err:
|
||||
raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
|
||||
spin_unlock(q->lock_ptr);
|
||||
|
||||
ret = fault_in_user_writeable(uaddr);
|
||||
switch (err) {
|
||||
case -EFAULT:
|
||||
ret = fault_in_user_writeable(uaddr);
|
||||
break;
|
||||
|
||||
case -EAGAIN:
|
||||
cond_resched();
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
ret = err;
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock(q->lock_ptr);
|
||||
raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
|
||||
@@ -3055,10 +3072,8 @@ retry:
|
||||
* A unconditional UNLOCK_PI op raced against a waiter
|
||||
* setting the FUTEX_WAITERS bit. Try again.
|
||||
*/
|
||||
if (ret == -EAGAIN) {
|
||||
put_futex_key(&key);
|
||||
goto retry;
|
||||
}
|
||||
if (ret == -EAGAIN)
|
||||
goto pi_retry;
|
||||
/*
|
||||
* wake_futex_pi has detected invalid state. Tell user
|
||||
* space.
|
||||
@@ -3073,9 +3088,19 @@ retry:
|
||||
* preserve the WAITERS bit not the OWNER_DIED one. We are the
|
||||
* owner.
|
||||
*/
|
||||
if (cmpxchg_futex_value_locked(&curval, uaddr, uval, 0)) {
|
||||
if ((ret = cmpxchg_futex_value_locked(&curval, uaddr, uval, 0))) {
|
||||
spin_unlock(&hb->lock);
|
||||
goto pi_faulted;
|
||||
switch (ret) {
|
||||
case -EFAULT:
|
||||
goto pi_faulted;
|
||||
|
||||
case -EAGAIN:
|
||||
goto pi_retry;
|
||||
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
goto out_putkey;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3089,6 +3114,11 @@ out_putkey:
|
||||
put_futex_key(&key);
|
||||
return ret;
|
||||
|
||||
pi_retry:
|
||||
put_futex_key(&key);
|
||||
cond_resched();
|
||||
goto retry;
|
||||
|
||||
pi_faulted:
|
||||
put_futex_key(&key);
|
||||
|
||||
@@ -3449,6 +3479,7 @@ err_unlock:
|
||||
int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi)
|
||||
{
|
||||
u32 uval, uninitialized_var(nval), mval;
|
||||
int err;
|
||||
|
||||
/* Futex address must be 32bit aligned */
|
||||
if ((((unsigned long)uaddr) % sizeof(*uaddr)) != 0)
|
||||
@@ -3458,42 +3489,57 @@ retry:
|
||||
if (get_user(uval, uaddr))
|
||||
return -1;
|
||||
|
||||
if ((uval & FUTEX_TID_MASK) == task_pid_vnr(curr)) {
|
||||
/*
|
||||
* Ok, this dying thread is truly holding a futex
|
||||
* of interest. Set the OWNER_DIED bit atomically
|
||||
* via cmpxchg, and if the value had FUTEX_WAITERS
|
||||
* set, wake up a waiter (if any). (We have to do a
|
||||
* futex_wake() even if OWNER_DIED is already set -
|
||||
* to handle the rare but possible case of recursive
|
||||
* thread-death.) The rest of the cleanup is done in
|
||||
* userspace.
|
||||
*/
|
||||
mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
|
||||
/*
|
||||
* We are not holding a lock here, but we want to have
|
||||
* the pagefault_disable/enable() protection because
|
||||
* we want to handle the fault gracefully. If the
|
||||
* access fails we try to fault in the futex with R/W
|
||||
* verification via get_user_pages. get_user() above
|
||||
* does not guarantee R/W access. If that fails we
|
||||
* give up and leave the futex locked.
|
||||
*/
|
||||
if (cmpxchg_futex_value_locked(&nval, uaddr, uval, mval)) {
|
||||
if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Ok, this dying thread is truly holding a futex
|
||||
* of interest. Set the OWNER_DIED bit atomically
|
||||
* via cmpxchg, and if the value had FUTEX_WAITERS
|
||||
* set, wake up a waiter (if any). (We have to do a
|
||||
* futex_wake() even if OWNER_DIED is already set -
|
||||
* to handle the rare but possible case of recursive
|
||||
* thread-death.) The rest of the cleanup is done in
|
||||
* userspace.
|
||||
*/
|
||||
mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
|
||||
|
||||
/*
|
||||
* We are not holding a lock here, but we want to have
|
||||
* the pagefault_disable/enable() protection because
|
||||
* we want to handle the fault gracefully. If the
|
||||
* access fails we try to fault in the futex with R/W
|
||||
* verification via get_user_pages. get_user() above
|
||||
* does not guarantee R/W access. If that fails we
|
||||
* give up and leave the futex locked.
|
||||
*/
|
||||
if ((err = cmpxchg_futex_value_locked(&nval, uaddr, uval, mval))) {
|
||||
switch (err) {
|
||||
case -EFAULT:
|
||||
if (fault_in_user_writeable(uaddr))
|
||||
return -1;
|
||||
goto retry;
|
||||
}
|
||||
if (nval != uval)
|
||||
|
||||
case -EAGAIN:
|
||||
cond_resched();
|
||||
goto retry;
|
||||
|
||||
/*
|
||||
* Wake robust non-PI futexes here. The wakeup of
|
||||
* PI futexes happens in exit_pi_state():
|
||||
*/
|
||||
if (!pi && (uval & FUTEX_WAITERS))
|
||||
futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY);
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (nval != uval)
|
||||
goto retry;
|
||||
|
||||
/*
|
||||
* Wake robust non-PI futexes here. The wakeup of
|
||||
* PI futexes happens in exit_pi_state():
|
||||
*/
|
||||
if (!pi && (uval & FUTEX_WAITERS))
|
||||
futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -323,11 +323,10 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
|
||||
desc->affinity_notify = notify;
|
||||
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
||||
|
||||
if (!notify && old_notify)
|
||||
if (old_notify) {
|
||||
cancel_work_sync(&old_notify->work);
|
||||
|
||||
if (old_notify)
|
||||
kref_put(&old_notify->kref, old_notify->release);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
49
lib/ubsan.c
49
lib/ubsan.c
@@ -86,11 +86,13 @@ static bool is_inline_int(struct type_descriptor *type)
|
||||
return bits <= inline_bits;
|
||||
}
|
||||
|
||||
static s_max get_signed_val(struct type_descriptor *type, unsigned long val)
|
||||
static s_max get_signed_val(struct type_descriptor *type, void *val)
|
||||
{
|
||||
if (is_inline_int(type)) {
|
||||
unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
|
||||
return ((s_max)val) << extra_bits >> extra_bits;
|
||||
unsigned long ulong_val = (unsigned long)val;
|
||||
|
||||
return ((s_max)ulong_val) << extra_bits >> extra_bits;
|
||||
}
|
||||
|
||||
if (type_bit_width(type) == 64)
|
||||
@@ -99,15 +101,15 @@ static s_max get_signed_val(struct type_descriptor *type, unsigned long val)
|
||||
return *(s_max *)val;
|
||||
}
|
||||
|
||||
static bool val_is_negative(struct type_descriptor *type, unsigned long val)
|
||||
static bool val_is_negative(struct type_descriptor *type, void *val)
|
||||
{
|
||||
return type_is_signed(type) && get_signed_val(type, val) < 0;
|
||||
}
|
||||
|
||||
static u_max get_unsigned_val(struct type_descriptor *type, unsigned long val)
|
||||
static u_max get_unsigned_val(struct type_descriptor *type, void *val)
|
||||
{
|
||||
if (is_inline_int(type))
|
||||
return val;
|
||||
return (unsigned long)val;
|
||||
|
||||
if (type_bit_width(type) == 64)
|
||||
return *(u64 *)val;
|
||||
@@ -116,7 +118,7 @@ static u_max get_unsigned_val(struct type_descriptor *type, unsigned long val)
|
||||
}
|
||||
|
||||
static void val_to_string(char *str, size_t size, struct type_descriptor *type,
|
||||
unsigned long value)
|
||||
void *value)
|
||||
{
|
||||
if (type_is_int(type)) {
|
||||
if (type_bit_width(type) == 128) {
|
||||
@@ -163,8 +165,8 @@ static void ubsan_epilogue(unsigned long *flags)
|
||||
current->in_ubsan--;
|
||||
}
|
||||
|
||||
static void handle_overflow(struct overflow_data *data, unsigned long lhs,
|
||||
unsigned long rhs, char op)
|
||||
static void handle_overflow(struct overflow_data *data, void *lhs,
|
||||
void *rhs, char op)
|
||||
{
|
||||
|
||||
struct type_descriptor *type = data->type;
|
||||
@@ -191,8 +193,7 @@ static void handle_overflow(struct overflow_data *data, unsigned long lhs,
|
||||
}
|
||||
|
||||
void __ubsan_handle_add_overflow(struct overflow_data *data,
|
||||
unsigned long lhs,
|
||||
unsigned long rhs)
|
||||
void *lhs, void *rhs)
|
||||
{
|
||||
|
||||
handle_overflow(data, lhs, rhs, '+');
|
||||
@@ -200,23 +201,21 @@ void __ubsan_handle_add_overflow(struct overflow_data *data,
|
||||
EXPORT_SYMBOL(__ubsan_handle_add_overflow);
|
||||
|
||||
void __ubsan_handle_sub_overflow(struct overflow_data *data,
|
||||
unsigned long lhs,
|
||||
unsigned long rhs)
|
||||
void *lhs, void *rhs)
|
||||
{
|
||||
handle_overflow(data, lhs, rhs, '-');
|
||||
}
|
||||
EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
|
||||
|
||||
void __ubsan_handle_mul_overflow(struct overflow_data *data,
|
||||
unsigned long lhs,
|
||||
unsigned long rhs)
|
||||
void *lhs, void *rhs)
|
||||
{
|
||||
handle_overflow(data, lhs, rhs, '*');
|
||||
}
|
||||
EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
|
||||
|
||||
void __ubsan_handle_negate_overflow(struct overflow_data *data,
|
||||
unsigned long old_val)
|
||||
void *old_val)
|
||||
{
|
||||
unsigned long flags;
|
||||
char old_val_str[VALUE_LENGTH];
|
||||
@@ -237,8 +236,7 @@ EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
|
||||
|
||||
|
||||
void __ubsan_handle_divrem_overflow(struct overflow_data *data,
|
||||
unsigned long lhs,
|
||||
unsigned long rhs)
|
||||
void *lhs, void *rhs)
|
||||
{
|
||||
unsigned long flags;
|
||||
char rhs_val_str[VALUE_LENGTH];
|
||||
@@ -323,7 +321,7 @@ static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
|
||||
}
|
||||
|
||||
void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
|
||||
unsigned long ptr)
|
||||
void *ptr)
|
||||
{
|
||||
struct type_mismatch_data_common common_data = {
|
||||
.location = &data->location,
|
||||
@@ -332,12 +330,12 @@ void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
|
||||
.type_check_kind = data->type_check_kind
|
||||
};
|
||||
|
||||
ubsan_type_mismatch_common(&common_data, ptr);
|
||||
ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
|
||||
}
|
||||
EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
|
||||
|
||||
void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
|
||||
unsigned long ptr)
|
||||
void *ptr)
|
||||
{
|
||||
|
||||
struct type_mismatch_data_common common_data = {
|
||||
@@ -347,12 +345,12 @@ void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
|
||||
.type_check_kind = data->type_check_kind
|
||||
};
|
||||
|
||||
ubsan_type_mismatch_common(&common_data, ptr);
|
||||
ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
|
||||
}
|
||||
EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
|
||||
|
||||
void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
|
||||
unsigned long bound)
|
||||
void *bound)
|
||||
{
|
||||
unsigned long flags;
|
||||
char bound_str[VALUE_LENGTH];
|
||||
@@ -369,8 +367,7 @@ void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
|
||||
}
|
||||
EXPORT_SYMBOL(__ubsan_handle_vla_bound_not_positive);
|
||||
|
||||
void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
|
||||
unsigned long index)
|
||||
void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data, void *index)
|
||||
{
|
||||
unsigned long flags;
|
||||
char index_str[VALUE_LENGTH];
|
||||
@@ -388,7 +385,7 @@ void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
|
||||
EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
|
||||
|
||||
void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
|
||||
unsigned long lhs, unsigned long rhs)
|
||||
void *lhs, void *rhs)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct type_descriptor *rhs_type = data->rhs_type;
|
||||
@@ -439,7 +436,7 @@ void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
|
||||
EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
|
||||
|
||||
void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
|
||||
unsigned long val)
|
||||
void *val)
|
||||
{
|
||||
unsigned long flags;
|
||||
char val_str[VALUE_LENGTH];
|
||||
|
||||
@@ -4296,7 +4296,8 @@ static void show_symbol(struct seq_file *m, unsigned long address)
|
||||
|
||||
static int leaks_show(struct seq_file *m, void *p)
|
||||
{
|
||||
struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list);
|
||||
struct kmem_cache *cachep = list_entry(p, struct kmem_cache,
|
||||
root_caches_node);
|
||||
struct page *page;
|
||||
struct kmem_cache_node *n;
|
||||
const char *name;
|
||||
|
||||
@@ -1165,6 +1165,14 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
|
||||
!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
|
||||
return 0;
|
||||
|
||||
/* The minimum encryption key size needs to be enforced by the
|
||||
* host stack before establishing any L2CAP connections. The
|
||||
* specification in theory allows a minimum of 1, but to align
|
||||
* BR/EDR and LE transports, a minimum of 7 is chosen.
|
||||
*/
|
||||
if (conn->enc_key_size < HCI_MIN_ENC_KEY_SIZE)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
|
||||
sockfd_put(csock);
|
||||
return err;
|
||||
}
|
||||
ca.name[sizeof(ca.name)-1] = 0;
|
||||
|
||||
err = hidp_connection_add(&ca, csock, isock);
|
||||
if (!err && copy_to_user(argp, &ca, sizeof(ca)))
|
||||
|
||||
@@ -643,6 +643,7 @@ static const struct regmap_config cs4270_regmap = {
|
||||
.reg_defaults = cs4270_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.write_flag_mask = CS4270_I2C_INCR,
|
||||
|
||||
.readable_reg = cs4270_reg_is_readable,
|
||||
.volatile_reg = cs4270_reg_is_volatile,
|
||||
|
||||
@@ -536,73 +536,71 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
|
||||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
struct hdmi_codec_daifmt cf = { 0 };
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(dai->dev, "%s()\n", __func__);
|
||||
|
||||
if (dai->id == DAI_ID_SPDIF) {
|
||||
cf.fmt = HDMI_SPDIF;
|
||||
} else {
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
cf.bit_clk_master = 1;
|
||||
cf.frame_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFM:
|
||||
cf.frame_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFS:
|
||||
cf.bit_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dai->id == DAI_ID_SPDIF)
|
||||
return 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_IF:
|
||||
cf.frame_clk_inv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
cf.bit_clk_inv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_IF:
|
||||
cf.frame_clk_inv = 1;
|
||||
cf.bit_clk_inv = 1;
|
||||
break;
|
||||
}
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
cf.bit_clk_master = 1;
|
||||
cf.frame_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFM:
|
||||
cf.frame_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFS:
|
||||
cf.bit_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
cf.fmt = HDMI_I2S;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
cf.fmt = HDMI_DSP_A;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
cf.fmt = HDMI_DSP_B;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
cf.fmt = HDMI_RIGHT_J;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
cf.fmt = HDMI_LEFT_J;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_AC97:
|
||||
cf.fmt = HDMI_AC97;
|
||||
break;
|
||||
default:
|
||||
dev_err(dai->dev, "Invalid DAI interface format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_IF:
|
||||
cf.frame_clk_inv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
cf.bit_clk_inv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_IF:
|
||||
cf.frame_clk_inv = 1;
|
||||
cf.bit_clk_inv = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
cf.fmt = HDMI_I2S;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
cf.fmt = HDMI_DSP_A;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
cf.fmt = HDMI_DSP_B;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
cf.fmt = HDMI_RIGHT_J;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
cf.fmt = HDMI_LEFT_J;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_AC97:
|
||||
cf.fmt = HDMI_AC97;
|
||||
break;
|
||||
default:
|
||||
dev_err(dai->dev, "Invalid DAI interface format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hcp->daifmt[dai->id] = cf;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
|
||||
@@ -784,8 +782,10 @@ static int hdmi_codec_probe(struct platform_device *pdev)
|
||||
i++;
|
||||
}
|
||||
|
||||
if (hcd->spdif)
|
||||
if (hcd->spdif) {
|
||||
hcp->daidrv[i] = hdmi_spdif_dai;
|
||||
hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
|
||||
dai_count);
|
||||
|
||||
@@ -414,9 +414,9 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3,
|
||||
NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0],
|
||||
ARRAY_SIZE(nau8810_mono_mixer_controls)),
|
||||
SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3,
|
||||
SND_SOC_DAPM_DAC("DAC", "Playback", NAU8810_REG_POWER3,
|
||||
NAU8810_DAC_EN_SFT, 0),
|
||||
SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2,
|
||||
SND_SOC_DAPM_ADC("ADC", "Capture", NAU8810_REG_POWER2,
|
||||
NAU8810_ADC_EN_SFT, 0),
|
||||
SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3,
|
||||
NAU8810_NSPK_EN_SFT, 0, NULL, 0),
|
||||
|
||||
@@ -634,8 +634,8 @@ static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2,
|
||||
NAU8824_ADCR_EN_SFT, 0),
|
||||
|
||||
SND_SOC_DAPM_AIF_OUT("AIFTX", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("AIFRX", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("AIFRX", "Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC,
|
||||
NAU8824_DACL_EN_SFT, 0),
|
||||
@@ -784,6 +784,36 @@ static void nau8824_int_status_clear_all(struct regmap *regmap)
|
||||
}
|
||||
}
|
||||
|
||||
static void nau8824_dapm_disable_pin(struct nau8824 *nau8824, const char *pin)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = nau8824->dapm;
|
||||
const char *prefix = dapm->component->name_prefix;
|
||||
char prefixed_pin[80];
|
||||
|
||||
if (prefix) {
|
||||
snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s",
|
||||
prefix, pin);
|
||||
snd_soc_dapm_disable_pin(dapm, prefixed_pin);
|
||||
} else {
|
||||
snd_soc_dapm_disable_pin(dapm, pin);
|
||||
}
|
||||
}
|
||||
|
||||
static void nau8824_dapm_enable_pin(struct nau8824 *nau8824, const char *pin)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = nau8824->dapm;
|
||||
const char *prefix = dapm->component->name_prefix;
|
||||
char prefixed_pin[80];
|
||||
|
||||
if (prefix) {
|
||||
snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s",
|
||||
prefix, pin);
|
||||
snd_soc_dapm_force_enable_pin(dapm, prefixed_pin);
|
||||
} else {
|
||||
snd_soc_dapm_force_enable_pin(dapm, pin);
|
||||
}
|
||||
}
|
||||
|
||||
static void nau8824_eject_jack(struct nau8824 *nau8824)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = nau8824->dapm;
|
||||
@@ -792,8 +822,8 @@ static void nau8824_eject_jack(struct nau8824 *nau8824)
|
||||
/* Clear all interruption status */
|
||||
nau8824_int_status_clear_all(regmap);
|
||||
|
||||
snd_soc_dapm_disable_pin(dapm, "SAR");
|
||||
snd_soc_dapm_disable_pin(dapm, "MICBIAS");
|
||||
nau8824_dapm_disable_pin(nau8824, "SAR");
|
||||
nau8824_dapm_disable_pin(nau8824, "MICBIAS");
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
/* Enable the insertion interruption, disable the ejection
|
||||
@@ -822,8 +852,8 @@ static void nau8824_jdet_work(struct work_struct *work)
|
||||
struct regmap *regmap = nau8824->regmap;
|
||||
int adc_value, event = 0, event_mask = 0;
|
||||
|
||||
snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
|
||||
snd_soc_dapm_force_enable_pin(dapm, "SAR");
|
||||
nau8824_dapm_enable_pin(nau8824, "MICBIAS");
|
||||
nau8824_dapm_enable_pin(nau8824, "SAR");
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
msleep(100);
|
||||
@@ -834,8 +864,8 @@ static void nau8824_jdet_work(struct work_struct *work)
|
||||
if (adc_value < HEADSET_SARADC_THD) {
|
||||
event |= SND_JACK_HEADPHONE;
|
||||
|
||||
snd_soc_dapm_disable_pin(dapm, "SAR");
|
||||
snd_soc_dapm_disable_pin(dapm, "MICBIAS");
|
||||
nau8824_dapm_disable_pin(nau8824, "SAR");
|
||||
nau8824_dapm_disable_pin(nau8824, "MICBIAS");
|
||||
snd_soc_dapm_sync(dapm);
|
||||
} else {
|
||||
event |= SND_JACK_HEADSET;
|
||||
|
||||
@@ -462,6 +462,8 @@ static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_INPUT("IN2_R"),
|
||||
SND_SOC_DAPM_INPUT("IN3_L"),
|
||||
SND_SOC_DAPM_INPUT("IN3_R"),
|
||||
SND_SOC_DAPM_INPUT("CM_L"),
|
||||
SND_SOC_DAPM_INPUT("CM_R"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
|
||||
|
||||
@@ -3711,11 +3711,13 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
|
||||
struct regmap *regmap = dsp->regmap;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&dsp->pwr_lock);
|
||||
|
||||
ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val);
|
||||
if (ret) {
|
||||
adsp_err(dsp,
|
||||
"Failed to read Region Lock Ctrl register: %d\n", ret);
|
||||
return IRQ_HANDLED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (val & ADSP2_WDT_TIMEOUT_STS_MASK) {
|
||||
@@ -3734,7 +3736,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
|
||||
adsp_err(dsp,
|
||||
"Failed to read Bus Err Addr register: %d\n",
|
||||
ret);
|
||||
return IRQ_HANDLED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
adsp_err(dsp, "bus error address = 0x%x\n",
|
||||
@@ -3747,7 +3749,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
|
||||
adsp_err(dsp,
|
||||
"Failed to read Pmem Xmem Err Addr register: %d\n",
|
||||
ret);
|
||||
return IRQ_HANDLED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
adsp_err(dsp, "xmem error address = 0x%x\n",
|
||||
@@ -3760,6 +3762,9 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
|
||||
regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL,
|
||||
ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT);
|
||||
|
||||
error:
|
||||
mutex_unlock(&dsp->pwr_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
|
||||
|
||||
@@ -405,7 +405,7 @@ static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
|
||||
};
|
||||
|
||||
static const unsigned int dmic_2ch[] = {
|
||||
4,
|
||||
2,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = {
|
||||
|
||||
@@ -1252,11 +1252,15 @@ struct sst_dsp *sst_dsp_new(struct device *dev,
|
||||
goto irq_err;
|
||||
|
||||
err = sst_dma_new(sst);
|
||||
if (err)
|
||||
dev_warn(dev, "sst_dma_new failed %d\n", err);
|
||||
if (err) {
|
||||
dev_err(dev, "sst_dma_new failed %d\n", err);
|
||||
goto dma_err;
|
||||
}
|
||||
|
||||
return sst;
|
||||
|
||||
dma_err:
|
||||
free_irq(sst->irq, sst);
|
||||
irq_err:
|
||||
if (sst->ops->free)
|
||||
sst->ops->free(sst);
|
||||
|
||||
@@ -208,7 +208,9 @@ static int rockchip_pdm_set_fmt(struct snd_soc_dai *cpu_dai,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(cpu_dai->dev);
|
||||
regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val);
|
||||
pm_runtime_put(cpu_dai->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -66,11 +66,11 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* We add 1 to the rclk_freq value in order to avoid too low clock
|
||||
* We add 2 to the rclk_freq value in order to avoid too low clock
|
||||
* frequency values due to the EPLL output frequency not being exact
|
||||
* multiple of the audio sampling rate.
|
||||
*/
|
||||
rclk_freq = params_rate(params) * rfs + 1;
|
||||
rclk_freq = params_rate(params) * rfs + 2;
|
||||
|
||||
ret = clk_set_rate(priv->sclk_i2s, rclk_freq);
|
||||
if (ret < 0)
|
||||
|
||||
@@ -965,10 +965,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
codec_params = *params;
|
||||
|
||||
/* fixup params based on TDM slot masks */
|
||||
if (codec_dai->tx_mask)
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
codec_dai->tx_mask)
|
||||
soc_pcm_codec_params_fixup(&codec_params,
|
||||
codec_dai->tx_mask);
|
||||
if (codec_dai->rx_mask)
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
|
||||
codec_dai->rx_mask)
|
||||
soc_pcm_codec_params_fixup(&codec_params,
|
||||
codec_dai->rx_mask);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user