mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge android11-5.4.197+ (3970bc6) into msm-5.4
* refs/heads/tmp-3970bc6:
UPSTREAM: Revert "net: af_key: add check for pfkey_broadcast in function pfkey_process"
FROMGIT: arm64: fix oops in concurrently setting insn_emulation sysctls
ANDROID: abi_gki_aarch64_qcom: Add vmemdup_user to qcom symbol list
ANDROID: GKI: update Sony KMI symbol list
UPSTREAM: mm: fix misplaced unlock_page in do_wp_page()
BACKPORT: mm: do_wp_page() simplification
UPSTREAM: mm/ksm: Remove reuse_ksm_page()
BACKPORT: ALSA: pcm: Fix races among concurrent prealloc proc writes
BACKPORT: ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
BACKPORT: ALSA: pcm: Fix races among concurrent read/write and buffer changes
ANDROID: Fix up abi issue with struct snd_pcm_runtime
BACKPORT: ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
BACKPORT: nfc: nfcmrvl: main: reorder destructive operations in nfcmrvl_nci_unregister_dev to avoid bugs
Linux 5.4.197
bpf: Enlarge offset check value to INT_MAX in bpf_skb_{load,store}_bytes
NFSD: Fix possible sleep during nfsd4_release_lockowner()
NFS: Memory allocation failures are not server fatal errors
docs: submitting-patches: Fix crossref to 'The canonical patch format'
tpm: ibmvtpm: Correct the return value in tpm_ibmvtpm_probe()
tpm: Fix buffer access in tpm2_get_tpm_pt()
HID: multitouch: Add support for Google Whiskers Touchpad
raid5: introduce MD_BROKEN
dm verity: set DM_TARGET_IMMUTABLE feature flag
dm stats: add cond_resched when looping over entries
dm crypt: make printing of the key constant-time
dm integrity: fix error code in dm_integrity_ctr()
zsmalloc: fix races between asynchronous zspage free and page migration
crypto: ecrdsa - Fix incorrect use of vli_cmp
netfilter: conntrack: re-fetch conntrack after insertion
exec: Force single empty string when argv is empty
drm/i915: Fix -Wstringop-overflow warning in call to intel_read_wm_latency()
cfg80211: set custom regdomain after wiphy registration
assoc_array: Fix BUG_ON during garbage collect
drivers: i2c: thunderx: Allow driver to work with ACPI defined TWSI controllers
i2c: ismt: Provide a DMA buffer for Interrupt Cause Logging
net: ftgmac100: Disable hardware checksum on AST2600
net: af_key: check encryption module availability consistency
pinctrl: sunxi: fix f1c100s uart2 function
ACPI: sysfs: Fix BERT error region memory mapping
ACPI: sysfs: Make sparse happy about address space in use
media: vim2m: initialize the media device earlier
media: vim2m: Register video device after setting up internals
secure_seq: use the 64 bits of the siphash for port offset calculation
tcp: change source port randomizarion at connect() time
Input: goodix - fix spurious key release events
staging: rtl8723bs: prevent ->Ssid overflow in rtw_wx_set_scan()
x86/pci/xen: Disable PCI/MSI[-X] masking for XEN_HVM guests
lockdown: also lock down previous kgdb use
Linux 5.4.196
afs: Fix afs_getattr() to refetch file status if callback break occurred
i2c: mt7621: fix missing clk_disable_unprepare() on error in mtk_i2c_probe()
x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
x86/xen: fix booting 32-bit pv guest
Reinstate some of "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
firmware_loader: use kernel credentials when reading firmware
net: stmmac: disable Split Header (SPH) for Intel platforms
block: return ELEVATOR_DISCARD_MERGE if possible
Input: ili210x - fix reset timing
net: atlantic: verify hw_head_ lies within TX buffer ring
net: stmmac: fix missing pci_disable_device() on error in stmmac_pci_probe()
ethernet: tulip: fix missing pci_disable_device() on error in tulip_init_one()
selftests: add ping test with ping_group_range tuned
mac80211: fix rx reordering with non explicit / psmp ack policy
scsi: qla2xxx: Fix missed DMA unmap for aborted commands
perf bench numa: Address compiler error on s390
gpio: mvebu/pwm: Refuse requests with inverted polarity
gpio: gpio-vf610: do not touch other bits when set the target bit
net: bridge: Clear offload_fwd_mark when passing frame up bridge interface.
igb: skip phy status check where unavailable
ARM: 9197/1: spectre-bhb: fix loop8 sequence for Thumb2
ARM: 9196/1: spectre-bhb: enable for Cortex-A15
net: af_key: add check for pfkey_broadcast in function pfkey_process
net/mlx5e: Properly block LRO when XDP is enabled
NFC: nci: fix sleep in atomic context bugs caused by nci_skb_alloc
net/qla3xxx: Fix a test in ql_reset_work()
clk: at91: generated: consider range when calculating best rate
ice: fix possible under reporting of ethtool Tx and Rx statistics
net: vmxnet3: fix possible NULL pointer dereference in vmxnet3_rq_cleanup()
net: vmxnet3: fix possible use-after-free bugs in vmxnet3_rq_alloc_rx_buf()
net/sched: act_pedit: sanitize shift argument before usage
net: macb: Increment rx bd head after allocating skb and buffer
ARM: dts: aspeed-g6: fix SPI1/SPI2 quad pin group
ARM: dts: aspeed-g6: remove FWQSPID group in pinctrl dtsi
dma-buf: fix use of DMA_BUF_SET_NAME_{A,B} in userspace
drm/dp/mst: fix a possible memory leak in fetch_monitor_name()
crypto: qcom-rng - fix infinite loop on requests not multiple of WORD_SZ
KVM: x86/mmu: Update number of zapped pages even if page list is stable
PCI/PM: Avoid putting Elo i2 PCIe Ports in D3cold
Fix double fget() in vhost_net_set_backend()
perf: Fix sys_perf_event_open() race against self
ALSA: wavefront: Proper check of get_user() error
SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()
SUNRPC: Don't call connect() more than once on a TCP socket
SUNRPC: Prevent immediate close+reconnect
SUNRPC: Clean up scheduling of autoclose
mmc: core: Default to generic_cmd6_time as timeout in __mmc_switch()
mmc: block: Use generic_cmd6_time when modifying INAND_CMD38_ARG_EXT_CSD
mmc: core: Specify timeouts for BKOPS and CACHE_FLUSH for eMMC
nilfs2: fix lockdep warnings during disk space reclamation
nilfs2: fix lockdep warnings in page operations for btree nodes
ARM: 9191/1: arm/stacktrace, kasan: Silence KASAN warnings in unwind_frame()
platform/chrome: cros_ec_debugfs: detach log reader wq from devm
drbd: remove usage of list iterator variable after loop
MIPS: lantiq: check the return value of kzalloc()
rtc: mc146818-lib: Fix the AltCentury for AMD platforms
nvme-multipath: fix hang when disk goes live over reconnect
ALSA: hda/realtek: Enable headset mic on Lenovo P360
crypto: x86/chacha20 - Avoid spurious jumps to other functions
crypto: stm32 - fix reference leak in stm32_crc_remove
Input: stmfts - fix reference leak in stmfts_input_open
Input: add bounds checking to input_set_capability()
um: Cleanup syscall_handler_t definition/cast, fix warning
rtc: fix use-after-free on device removal
x86/xen: Make the secondary CPU idle tasks reliable
x86/xen: Make the boot CPU idle task reliable
floppy: use a statically allocated error counter
ANDROID: fix up abi issue with struct snd_pcm_runtime
Linux 5.4.195
tty/serial: digicolor: fix possible null-ptr-deref in digicolor_uart_probe()
ping: fix address binding wrt vrf
arm[64]/memremap: don't abuse pfn_valid() to ensure presence of linear map
net: phy: Fix race condition on link status change
MIPS: fix build with gcc-12
drm/vmwgfx: Initialize drm_mode_fb_cmd2
cgroup/cpuset: Remove cpus_allowed/mems_allowed setup in cpuset_init_smp()
i40e: i40e_main: fix a missing check on list iterator
drm/nouveau/tegra: Stop using iommu_present()
serial: 8250_mtk: Fix register address for XON/XOFF character
serial: 8250_mtk: Fix UART_EFR register address
slimbus: qcom: Fix IRQ check in qcom_slim_probe
USB: serial: option: add Fibocom MA510 modem
USB: serial: option: add Fibocom L610 modem
USB: serial: qcserial: add support for Sierra Wireless EM7590
USB: serial: pl2303: add device id for HP LM930 Display
usb: typec: tcpci: Don't skip cleanup in .remove() on error
usb: cdc-wdm: fix reading stuck on device close
tty: n_gsm: fix mux activation issues in gsm_config()
tcp: resalt the secret every 10 seconds
net: emaclite: Don't advertise 1000BASE-T and do auto negotiation
s390: disable -Warray-bounds
ASoC: ops: Validate input values in snd_soc_put_volsw_range()
ASoC: max98090: Generate notifications on changes for custom control
ASoC: max98090: Reject invalid values in custom control put()
hwmon: (f71882fg) Fix negative temperature
gfs2: Fix filesystem block deallocation for short writes
net: sfc: ef10: fix memory leak in efx_ef10_mtd_probe()
net/smc: non blocking recvmsg() return -EAGAIN when no data and signal_pending
net/sched: act_pedit: really ensure the skb is writable
s390/lcs: fix variable dereferenced before check
s390/ctcm: fix potential memory leak
s390/ctcm: fix variable dereferenced before check
hwmon: (ltq-cputemp) restrict it to SOC_XWAY
dim: initialize all struct fields
mac80211_hwsim: call ieee80211_tx_prepare_skb under RCU protection
netlink: do not reset transport header in netlink_recvmsg()
drm/nouveau: Fix a potential theorical leak in nouveau_get_backlight_name()
ipv4: drop dst in multicast routing path
net: Fix features skip in for_each_netdev_feature()
mac80211: Reset MBSSID parameters upon connection
hwmon: (tmp401) Add OF device ID table
batman-adv: Don't skb_split skbuffs with frag_list
Linux 5.4.194
mm: userfaultfd: fix missing cache flush in mcopy_atomic_pte() and __mcopy_atomic()
mm: hugetlb: fix missing cache flush in copy_huge_page_from_user()
mm: fix missing cache flush for all tail pages of compound page
Bluetooth: Fix the creation of hdev->name
KVM: x86/svm: Account for family 17h event renumberings in amd_pmc_perf_hw_id
x86: kprobes: Prohibit probing on instruction which has emulate prefix
x86: xen: insn: Decode Xen and KVM emulate-prefix signature
x86: xen: kvm: Gather the definition of emulate prefixes
x86/asm: Allow to pass macros to __ASM_FORM()
KVM: x86/pmu: Refactoring find_arch_event() to pmc_perf_hw_id()
arm: remove CONFIG_ARCH_HAS_HOLES_MEMORYMODEL
can: grcan: only use the NAPI poll budget for RX
can: grcan: grcan_probe(): fix broken system id check for errata workaround needs
nfp: bpf: silence bitwise vs. logical OR warning
drm/i915: Cast remain to unsigned long in eb_relocate_vma
drm/amd/display/dc/gpio/gpio_service: Pass around correct dce_{version, environment} types
block: drbd: drbd_nl: Make conversion to 'enum drbd_ret_code' explicit
MIPS: Use address-of operator on section symbols
ANDROID: GKI: update the abi .xml file
Revert "tcp: ensure to use the most recently sent skb when filling the rate sample"
Linux 5.4.193
mmc: rtsx: add 74 Clocks in power on flow
PCI: aardvark: Fix reading MSI interrupt number
PCI: aardvark: Clear all MSIs at setup
dm: interlock pending dm_io and dm_wait_for_bios_completion
dm: fix mempool NULL pointer race when completing IO
tcp: make sure treq->af_specific is initialized
ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
ALSA: pcm: Fix races among concurrent prealloc proc writes
ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
ALSA: pcm: Fix races among concurrent read/write and buffer changes
ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
mm: fix unexpected zeroed page mapping with zram swap
block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern
net: ipv6: ensure we call ipv6_mc_down() at most once
KVM: LAPIC: Enable timer posted-interrupt only when mwait/hlt is advertised
x86/kvm: Preserve BSP MSR_KVM_POLL_CONTROL across suspend/resume
kvm: x86/cpuid: Only provide CPUID leaf 0xA if host has architectural PMU
NFSv4: Don't invalidate inode attributes on delegation return
drm/amdkfd: Use drm_priv to pass VM from KFD to amdgpu
net: igmp: respect RCU rules in ip_mc_source() and ip_mc_msfilter()
btrfs: always log symlinks in full mode
smsc911x: allow using IRQ0
bnxt_en: Fix possible bnxt_open() failure caused by wrong RFS flag
selftests: mirror_gre_bridge_1q: Avoid changing PVID while interface is operational
net: emaclite: Add error handling for of_address_to_resource()
net: stmmac: dwmac-sun8i: add missing of_node_put() in sun8i_dwmac_register_mdio_mux()
net: ethernet: mediatek: add missing of_node_put() in mtk_sgmii_init()
RDMA/siw: Fix a condition race issue in MPA request processing
ASoC: dmaengine: Restore NULL prepare_slave_config() callback
hwmon: (adt7470) Fix warning on module removal
NFC: netlink: fix sleep in atomic bug when firmware download timeout
nfc: nfcmrvl: main: reorder destructive operations in nfcmrvl_nci_unregister_dev to avoid bugs
nfc: replace improper check device_is_registered() in netlink related functions
can: grcan: use ofdev->dev when allocating DMA memory
can: grcan: grcan_close(): fix deadlock
s390/dasd: Fix read inconsistency for ESE DASD devices
s390/dasd: Fix read for ESE with blksize < 4k
s390/dasd: prevent double format of tracks for ESE devices
s390/dasd: fix data corruption for ESE devices
ASoC: meson: Fix event generation for G12A tohdmi mux
ASoC: wm8958: Fix change notifications for DSP controls
ASoC: da7219: Fix change notifications for tone generator frequency
genirq: Synchronize interrupt thread startup
ACPICA: Always create namespace nodes using acpi_ns_create_node()
firewire: core: extend card->lock in fw_core_handle_bus_reset
firewire: remove check of list iterator against head past the loop body
firewire: fix potential uaf in outbound_phy_packet_callback()
Revert "SUNRPC: attempt AF_LOCAL connect on setup"
gpiolib: of: fix bounds check for 'gpio-reserved-ranges'
ALSA: fireworks: fix wrong return count shorter than expected by 4 bytes
parisc: Merge model and model name into one line in /proc/cpuinfo
MIPS: Fix CP0 counter erratum detection for R4k CPUs
Linux 5.4.192
mm, hugetlb: allow for "high" userspace addresses
hugetlbfs: get unmapped area below TASK_UNMAPPED_BASE for hugetlbfs
tty: n_gsm: fix incorrect UA handling
tty: n_gsm: fix wrong command frame length field encoding
tty: n_gsm: fix wrong command retry handling
tty: n_gsm: fix missing explicit ldisc flush
tty: n_gsm: fix insufficient txframe size
netfilter: nft_socket: only do sk lookups when indev is available
tty: n_gsm: fix malformed counter for out of frame data
tty: n_gsm: fix wrong signal octet encoding in convergence layer type 2
x86/cpu: Load microcode during restore_processor_state()
net: ethernet: stmmac: fix write to sgmii_adapter_base
drivers: net: hippi: Fix deadlock in rr_close()
cifs: destage any unwritten data to the server before calling copychunk_write
x86: __memcpy_flushcache: fix wrong alignment if size > 2^32
ip6_gre: Avoid updating tunnel->tun_hlen in __gre6_xmit()
ASoC: wm8731: Disable the regulator when probing fails
tcp: fix F-RTO may not work correctly when receiving DSACK
ixgbe: ensure IPsec VF<->PF compatibility
bnx2x: fix napi API usage sequence
tls: Skip tls_append_frag on zero copy size
drm/amd/display: Fix memory leak in dcn21_clock_source_create
net: dsa: lantiq_gswip: Don't set GSWIP_MII_CFG_RMII_CLK
net: bcmgenet: hide status block before TX timestamping
clk: sunxi: sun9i-mmc: check return value after calling platform_get_resource()
bus: sunxi-rsb: Fix the return value of sunxi_rsb_device_create()
tcp: fix potential xmit stalls caused by TCP_NOTSENT_LOWAT
ip_gre: Make o_seqno start from 0 in native mode
net/smc: sync err code when tcp connection was refused
net: hns3: add validity check for message data length
cpufreq: fix memory leak in sun50i_cpufreq_nvmem_probe
pinctrl: pistachio: fix use of irq_of_parse_and_map()
arm64: dts: imx8mn-ddr4-evk: Describe the 32.768 kHz PMIC clock
ARM: dts: imx6ull-colibri: fix vqmmc regulator
sctp: check asoc strreset_chunk in sctp_generate_reconf_event
tcp: ensure to use the most recently sent skb when filling the rate sample
tcp: md5: incorrect tcp_header_len for incoming connections
bpf, lwt: Fix crash when using bpf_skb_set_tunnel_key() from bpf_xmit lwt hook
mtd: rawnand: Fix return value check of wait_for_completion_timeout
ipvs: correctly print the memory size of ip_vs_conn_tab
ARM: dts: logicpd-som-lv: Fix wrong pinmuxing on OMAP35
ARM: dts: am3517-evm: Fix misc pinmuxing
ARM: dts: Fix mmc order for omap3-gta04
phy: ti: Add missing pm_runtime_disable() in serdes_am654_probe
phy: mapphone-mdm6600: Fix PM error handling in phy_mdm6600_probe
ARM: dts: at91: Map MCLK for wm8731 on at91sam9g20ek
phy: ti: omap-usb2: Fix error handling in omap_usb2_enable_clocks
ARM: OMAP2+: Fix refcount leak in omap_gic_of_init
phy: samsung: exynos5250-sata: fix missing device put in probe error paths
phy: samsung: Fix missing of_node_put() in exynos_sata_phy_probe
ARM: dts: imx6qdl-apalis: Fix sgtl5000 detection issue
USB: Fix xhci event ring dequeue pointer ERDP update issue
mtd: rawnand: fix ecc parameters for mt7622
arm64: dts: meson: remove CPU opps below 1GHz for SM1 boards
arm64: dts: meson: remove CPU opps below 1GHz for G12B boards
video: fbdev: udlfb: properly check endpoint type
hex2bin: fix access beyond string end
hex2bin: make the function hex_to_bin constant-time
arch_topology: Do not set llc_sibling if llc_id is invalid
serial: 8250: Correct the clock for EndRun PTP/1588 PCIe device
serial: 8250: Also set sticky MCR bits in console restoration
serial: imx: fix overrun interrupts in DMA mode
usb: dwc3: gadget: Return proper request status
usb: dwc3: core: Fix tx/rx threshold settings
usb: gadget: configfs: clear deactivation flag in configfs_composite_unbind()
usb: gadget: uvc: Fix crash when encoding data for usb request
usb: typec: ucsi: Fix role swapping
usb: misc: fix improper handling of refcount in uss720_probe()
iio: magnetometer: ak8975: Fix the error handling in ak8975_power_on()
iio: dac: ad5446: Fix read_raw not returning set value
iio: dac: ad5592r: Fix the missing return value.
xhci: increase usb U3 -> U0 link resume timeout from 100ms to 500ms
xhci: stop polling roothubs after shutdown
USB: serial: option: add Telit 0x1057, 0x1058, 0x1075 compositions
USB: serial: option: add support for Cinterion MV32-WA/MV32-WB
USB: serial: cp210x: add PIDs for Kamstrup USB Meter Reader
USB: serial: whiteheat: fix heap overflow in WHITEHEAT_GET_DTR_RTS
USB: quirks: add STRING quirk for VCOM device
USB: quirks: add a Realtek card reader
usb: mtu3: fix USB 3.0 dual-role-switch from device to host
lightnvm: disable the subsystem
hamradio: remove needs_free_netdev to avoid UAF
hamradio: defer 6pack kfree after unregister_netdev
floppy: disable FDRAWCMD by default
Conflicts:
drivers/usb/dwc3/gadget.c
include/linux/dma-mapping.h
include/linux/stmmac.h
mm/memory.c
Change-Id: I3bf49e11ae4aeaf1db353efbdfee950cd12de8cf
Signed-off-by: Srinivasarao Pathipati <[email protected]>
This commit is contained in:
commit
630e7df8c5
357 changed files with 111890 additions and 113902 deletions
|
|
@ -734,10 +734,22 @@ int afs_getattr(const struct path *path, struct kstat *stat,
|
|||
{
|
||||
struct inode *inode = d_inode(path->dentry);
|
||||
struct afs_vnode *vnode = AFS_FS_I(inode);
|
||||
int seq = 0;
|
||||
struct key *key;
|
||||
int ret, seq = 0;
|
||||
|
||||
_enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation);
|
||||
|
||||
if (!(query_flags & AT_STATX_DONT_SYNC) &&
|
||||
!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
|
||||
key = afs_request_key(vnode->volume->cell);
|
||||
if (IS_ERR(key))
|
||||
return PTR_ERR(key);
|
||||
ret = afs_validate(vnode, key);
|
||||
key_put(key);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
do {
|
||||
read_seqbegin_or_lock(&vnode->cb_lock, &seq);
|
||||
generic_fillattr(inode, stat);
|
||||
|
|
|
|||
|
|
@ -5294,6 +5294,18 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
|||
mutex_lock(&inode->log_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* For symlinks, we must always log their content, which is stored in an
|
||||
* inline extent, otherwise we could end up with an empty symlink after
|
||||
* log replay, which is invalid on linux (symlink(2) returns -ENOENT if
|
||||
* one attempts to create an empty symlink).
|
||||
* We don't need to worry about flushing delalloc, because when we create
|
||||
* the inline extent when the symlink is created (we never have delalloc
|
||||
* for symlinks).
|
||||
*/
|
||||
if (S_ISLNK(inode->vfs_inode.i_mode))
|
||||
inode_only = LOG_INODE_ALL;
|
||||
|
||||
/*
|
||||
* a brute force approach to making sure we get the most uptodate
|
||||
* copies of everything.
|
||||
|
|
@ -5707,7 +5719,7 @@ process_leaf:
|
|||
}
|
||||
|
||||
ctx->log_new_dentries = false;
|
||||
if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
|
||||
if (type == BTRFS_FT_DIR)
|
||||
log_mode = LOG_INODE_ALL;
|
||||
ret = btrfs_log_inode(trans, root, BTRFS_I(di_inode),
|
||||
log_mode, 0, LLONG_MAX, ctx);
|
||||
|
|
|
|||
|
|
@ -1643,9 +1643,17 @@ smb2_copychunk_range(const unsigned int xid,
|
|||
int chunks_copied = 0;
|
||||
bool chunk_sizes_updated = false;
|
||||
ssize_t bytes_written, total_bytes_written = 0;
|
||||
struct inode *inode;
|
||||
|
||||
pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
|
||||
|
||||
/*
|
||||
* We need to flush all unwritten data before we can send the
|
||||
* copychunk ioctl to the server.
|
||||
*/
|
||||
inode = d_inode(trgtfile->dentry);
|
||||
filemap_write_and_wait(inode->i_mapping);
|
||||
|
||||
if (pcchunk == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
25
fs/exec.c
25
fs/exec.c
|
|
@ -454,6 +454,9 @@ static int prepare_arg_pages(struct linux_binprm *bprm,
|
|||
unsigned long limit, ptr_size;
|
||||
|
||||
bprm->argc = count(argv, MAX_ARG_STRINGS);
|
||||
if (bprm->argc == 0)
|
||||
pr_warn_once("process '%s' launched '%s' with NULL argv: empty string added\n",
|
||||
current->comm, bprm->filename);
|
||||
if (bprm->argc < 0)
|
||||
return bprm->argc;
|
||||
|
||||
|
|
@ -482,8 +485,14 @@ static int prepare_arg_pages(struct linux_binprm *bprm,
|
|||
* the stack. They aren't stored until much later when we can't
|
||||
* signal to the parent that the child has run out of stack space.
|
||||
* Instead, calculate it here so it's possible to fail gracefully.
|
||||
*
|
||||
* In the case of argc = 0, make sure there is space for adding a
|
||||
* empty string (which will bump argc to 1), to ensure confused
|
||||
* userspace programs don't start processing from argv[1], thinking
|
||||
* argc can never be 0, to keep them from walking envp by accident.
|
||||
* See do_execveat_common().
|
||||
*/
|
||||
ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
|
||||
ptr_size = (max(bprm->argc, 1) + bprm->envc) * sizeof(void *);
|
||||
if (limit <= ptr_size)
|
||||
return -E2BIG;
|
||||
limit -= ptr_size;
|
||||
|
|
@ -1832,6 +1841,20 @@ static int __do_execve_file(int fd, struct filename *filename,
|
|||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* When argv is empty, add an empty string ("") as argv[0] to
|
||||
* ensure confused userspace programs that start processing
|
||||
* from argv[1] won't end up walking envp. See also
|
||||
* bprm_stack_limits().
|
||||
*/
|
||||
if (bprm->argc == 0) {
|
||||
const char *argv[] = { "", NULL };
|
||||
retval = copy_strings_kernel(1, argv, bprm);
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
bprm->argc = 1;
|
||||
}
|
||||
|
||||
retval = exec_binprm(bprm);
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -375,6 +375,7 @@ void __fput_sync(struct file *file)
|
|||
}
|
||||
|
||||
EXPORT_SYMBOL(fput);
|
||||
EXPORT_SYMBOL(__fput_sync);
|
||||
|
||||
void __init files_init(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1233,13 +1233,12 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
|
|||
|
||||
if (length != written && (iomap->flags & IOMAP_F_NEW)) {
|
||||
/* Deallocate blocks that were just allocated. */
|
||||
loff_t blockmask = i_blocksize(inode) - 1;
|
||||
loff_t end = (pos + length) & ~blockmask;
|
||||
loff_t hstart = round_up(pos + written, i_blocksize(inode));
|
||||
loff_t hend = iomap->offset + iomap->length;
|
||||
|
||||
pos = (pos + written + blockmask) & ~blockmask;
|
||||
if (pos < end) {
|
||||
truncate_pagecache_range(inode, pos, end - 1);
|
||||
punch_hole(ip, pos, end - pos);
|
||||
if (hstart < hend) {
|
||||
truncate_pagecache_range(inode, hstart, hend - 1);
|
||||
punch_hole(ip, hstart, hend - hstart);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <linux/uio.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
static const struct super_operations hugetlbfs_ops;
|
||||
static const struct address_space_operations hugetlbfs_aops;
|
||||
|
|
@ -200,6 +201,54 @@ out:
|
|||
*/
|
||||
|
||||
#ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
|
||||
static unsigned long
|
||||
hugetlb_get_unmapped_area_bottomup(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
struct hstate *h = hstate_file(file);
|
||||
struct vm_unmapped_area_info info;
|
||||
|
||||
info.flags = 0;
|
||||
info.length = len;
|
||||
info.low_limit = current->mm->mmap_base;
|
||||
info.high_limit = arch_get_mmap_end(addr);
|
||||
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
|
||||
info.align_offset = 0;
|
||||
return vm_unmapped_area(&info);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
hugetlb_get_unmapped_area_topdown(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
struct hstate *h = hstate_file(file);
|
||||
struct vm_unmapped_area_info info;
|
||||
|
||||
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
|
||||
info.length = len;
|
||||
info.low_limit = max(PAGE_SIZE, mmap_min_addr);
|
||||
info.high_limit = arch_get_mmap_base(addr, current->mm->mmap_base);
|
||||
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
|
||||
info.align_offset = 0;
|
||||
addr = vm_unmapped_area(&info);
|
||||
|
||||
/*
|
||||
* A failed mmap() very likely causes application failure,
|
||||
* so fall back to the bottom-up function here. This scenario
|
||||
* can happen with large stack limits and large mmap()
|
||||
* allocations.
|
||||
*/
|
||||
if (unlikely(offset_in_page(addr))) {
|
||||
VM_BUG_ON(addr != -ENOMEM);
|
||||
info.flags = 0;
|
||||
info.low_limit = current->mm->mmap_base;
|
||||
info.high_limit = arch_get_mmap_end(addr);
|
||||
addr = vm_unmapped_area(&info);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
|
|
@ -207,7 +256,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
|
|||
struct mm_struct *mm = current->mm;
|
||||
struct vm_area_struct *vma;
|
||||
struct hstate *h = hstate_file(file);
|
||||
struct vm_unmapped_area_info info;
|
||||
const unsigned long mmap_end = arch_get_mmap_end(addr);
|
||||
|
||||
if (len & ~huge_page_mask(h))
|
||||
return -EINVAL;
|
||||
|
|
@ -223,18 +272,21 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
|
|||
if (addr) {
|
||||
addr = ALIGN(addr, huge_page_size(h));
|
||||
vma = find_vma(mm, addr);
|
||||
if (TASK_SIZE - len >= addr &&
|
||||
if (mmap_end - len >= addr &&
|
||||
(!vma || addr + len <= vm_start_gap(vma)))
|
||||
return addr;
|
||||
}
|
||||
|
||||
info.flags = 0;
|
||||
info.length = len;
|
||||
info.low_limit = TASK_UNMAPPED_BASE;
|
||||
info.high_limit = TASK_SIZE;
|
||||
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
|
||||
info.align_offset = 0;
|
||||
return vm_unmapped_area(&info);
|
||||
/*
|
||||
* Use mm->get_unmapped_area value as a hint to use topdown routine.
|
||||
* If architectures have special needs, they should define their own
|
||||
* version of hugetlb_get_unmapped_area.
|
||||
*/
|
||||
if (mm->get_unmapped_area == arch_get_unmapped_area_topdown)
|
||||
return hugetlb_get_unmapped_area_topdown(file, addr, len,
|
||||
pgoff, flags);
|
||||
return hugetlb_get_unmapped_area_bottomup(file, addr, len,
|
||||
pgoff, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -775,6 +775,7 @@ static inline bool nfs_error_is_fatal_on_server(int err)
|
|||
case 0:
|
||||
case -ERESTARTSYS:
|
||||
case -EINTR:
|
||||
case -ENOMEM:
|
||||
return false;
|
||||
}
|
||||
return nfs_error_is_fatal(err);
|
||||
|
|
|
|||
|
|
@ -359,6 +359,14 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
|
|||
kunmap_atomic(start);
|
||||
}
|
||||
|
||||
static void nfs4_fattr_set_prechange(struct nfs_fattr *fattr, u64 version)
|
||||
{
|
||||
if (!(fattr->valid & NFS_ATTR_FATTR_PRECHANGE)) {
|
||||
fattr->pre_change_attr = version;
|
||||
fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
static void nfs4_test_and_free_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
const struct cred *cred)
|
||||
|
|
@ -6307,7 +6315,9 @@ static void nfs4_delegreturn_release(void *calldata)
|
|||
pnfs_roc_release(&data->lr.arg, &data->lr.res,
|
||||
data->res.lr_ret);
|
||||
if (inode) {
|
||||
nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
|
||||
nfs4_fattr_set_prechange(&data->fattr,
|
||||
inode_peek_iversion_raw(inode));
|
||||
nfs_refresh_inode(inode, &data->fattr);
|
||||
nfs_iput_and_deactive(inode);
|
||||
}
|
||||
kfree(calldata);
|
||||
|
|
|
|||
|
|
@ -6894,16 +6894,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
|
|||
if (sop->so_is_open_owner || !same_owner_str(sop, owner))
|
||||
continue;
|
||||
|
||||
/* see if there are still any locks associated with it */
|
||||
lo = lockowner(sop);
|
||||
list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
|
||||
if (check_for_locks(stp->st_stid.sc_file, lo)) {
|
||||
status = nfserr_locks_held;
|
||||
spin_unlock(&clp->cl_lock);
|
||||
return status;
|
||||
}
|
||||
if (atomic_read(&sop->so_count) != 1) {
|
||||
spin_unlock(&clp->cl_lock);
|
||||
return nfserr_locks_held;
|
||||
}
|
||||
|
||||
lo = lockowner(sop);
|
||||
nfs4_get_stateowner(sop);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,23 @@
|
|||
#include "page.h"
|
||||
#include "btnode.h"
|
||||
|
||||
|
||||
/**
|
||||
* nilfs_init_btnc_inode - initialize B-tree node cache inode
|
||||
* @btnc_inode: inode to be initialized
|
||||
*
|
||||
* nilfs_init_btnc_inode() sets up an inode for B-tree node cache.
|
||||
*/
|
||||
void nilfs_init_btnc_inode(struct inode *btnc_inode)
|
||||
{
|
||||
struct nilfs_inode_info *ii = NILFS_I(btnc_inode);
|
||||
|
||||
btnc_inode->i_mode = S_IFREG;
|
||||
ii->i_flags = 0;
|
||||
memset(&ii->i_bmap_data, 0, sizeof(struct nilfs_bmap));
|
||||
mapping_set_gfp_mask(btnc_inode->i_mapping, GFP_NOFS);
|
||||
}
|
||||
|
||||
void nilfs_btnode_cache_clear(struct address_space *btnc)
|
||||
{
|
||||
invalidate_mapping_pages(btnc, 0, -1);
|
||||
|
|
@ -29,7 +46,7 @@ void nilfs_btnode_cache_clear(struct address_space *btnc)
|
|||
struct buffer_head *
|
||||
nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
|
||||
{
|
||||
struct inode *inode = NILFS_BTNC_I(btnc);
|
||||
struct inode *inode = btnc->host;
|
||||
struct buffer_head *bh;
|
||||
|
||||
bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node));
|
||||
|
|
@ -57,7 +74,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
|
|||
struct buffer_head **pbh, sector_t *submit_ptr)
|
||||
{
|
||||
struct buffer_head *bh;
|
||||
struct inode *inode = NILFS_BTNC_I(btnc);
|
||||
struct inode *inode = btnc->host;
|
||||
struct page *page;
|
||||
int err;
|
||||
|
||||
|
|
@ -157,7 +174,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
|
|||
struct nilfs_btnode_chkey_ctxt *ctxt)
|
||||
{
|
||||
struct buffer_head *obh, *nbh;
|
||||
struct inode *inode = NILFS_BTNC_I(btnc);
|
||||
struct inode *inode = btnc->host;
|
||||
__u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
|
||||
int err;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ struct nilfs_btnode_chkey_ctxt {
|
|||
struct buffer_head *newbh;
|
||||
};
|
||||
|
||||
void nilfs_init_btnc_inode(struct inode *btnc_inode);
|
||||
void nilfs_btnode_cache_clear(struct address_space *);
|
||||
struct buffer_head *nilfs_btnode_create_block(struct address_space *btnc,
|
||||
__u64 blocknr);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ static void nilfs_btree_free_path(struct nilfs_btree_path *path)
|
|||
static int nilfs_btree_get_new_block(const struct nilfs_bmap *btree,
|
||||
__u64 ptr, struct buffer_head **bhp)
|
||||
{
|
||||
struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
|
||||
struct inode *btnc_inode = NILFS_BMAP_I(btree)->i_assoc_inode;
|
||||
struct address_space *btnc = btnc_inode->i_mapping;
|
||||
struct buffer_head *bh;
|
||||
|
||||
bh = nilfs_btnode_create_block(btnc, ptr);
|
||||
|
|
@ -470,7 +471,8 @@ static int __nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
|
|||
struct buffer_head **bhp,
|
||||
const struct nilfs_btree_readahead_info *ra)
|
||||
{
|
||||
struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
|
||||
struct inode *btnc_inode = NILFS_BMAP_I(btree)->i_assoc_inode;
|
||||
struct address_space *btnc = btnc_inode->i_mapping;
|
||||
struct buffer_head *bh, *ra_bh;
|
||||
sector_t submit_ptr = 0;
|
||||
int ret;
|
||||
|
|
@ -1742,6 +1744,10 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *btree, __u64 key,
|
|||
dat = nilfs_bmap_get_dat(btree);
|
||||
}
|
||||
|
||||
ret = nilfs_attach_btree_node_cache(&NILFS_BMAP_I(btree)->vfs_inode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nilfs_bmap_prepare_alloc_ptr(btree, dreq, dat);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -1914,7 +1920,7 @@ static int nilfs_btree_prepare_update_v(struct nilfs_bmap *btree,
|
|||
path[level].bp_ctxt.newkey = path[level].bp_newreq.bpr_ptr;
|
||||
path[level].bp_ctxt.bh = path[level].bp_bh;
|
||||
ret = nilfs_btnode_prepare_change_key(
|
||||
&NILFS_BMAP_I(btree)->i_btnode_cache,
|
||||
NILFS_BMAP_I(btree)->i_assoc_inode->i_mapping,
|
||||
&path[level].bp_ctxt);
|
||||
if (ret < 0) {
|
||||
nilfs_dat_abort_update(dat,
|
||||
|
|
@ -1940,7 +1946,7 @@ static void nilfs_btree_commit_update_v(struct nilfs_bmap *btree,
|
|||
|
||||
if (buffer_nilfs_node(path[level].bp_bh)) {
|
||||
nilfs_btnode_commit_change_key(
|
||||
&NILFS_BMAP_I(btree)->i_btnode_cache,
|
||||
NILFS_BMAP_I(btree)->i_assoc_inode->i_mapping,
|
||||
&path[level].bp_ctxt);
|
||||
path[level].bp_bh = path[level].bp_ctxt.bh;
|
||||
}
|
||||
|
|
@ -1959,7 +1965,7 @@ static void nilfs_btree_abort_update_v(struct nilfs_bmap *btree,
|
|||
&path[level].bp_newreq.bpr_req);
|
||||
if (buffer_nilfs_node(path[level].bp_bh))
|
||||
nilfs_btnode_abort_change_key(
|
||||
&NILFS_BMAP_I(btree)->i_btnode_cache,
|
||||
NILFS_BMAP_I(btree)->i_assoc_inode->i_mapping,
|
||||
&path[level].bp_ctxt);
|
||||
}
|
||||
|
||||
|
|
@ -2135,7 +2141,8 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_bmap *btree,
|
|||
static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *btree,
|
||||
struct list_head *listp)
|
||||
{
|
||||
struct address_space *btcache = &NILFS_BMAP_I(btree)->i_btnode_cache;
|
||||
struct inode *btnc_inode = NILFS_BMAP_I(btree)->i_assoc_inode;
|
||||
struct address_space *btcache = btnc_inode->i_mapping;
|
||||
struct list_head lists[NILFS_BTREE_LEVEL_MAX];
|
||||
struct pagevec pvec;
|
||||
struct buffer_head *bh, *head;
|
||||
|
|
@ -2189,12 +2196,12 @@ static int nilfs_btree_assign_p(struct nilfs_bmap *btree,
|
|||
path[level].bp_ctxt.newkey = blocknr;
|
||||
path[level].bp_ctxt.bh = *bh;
|
||||
ret = nilfs_btnode_prepare_change_key(
|
||||
&NILFS_BMAP_I(btree)->i_btnode_cache,
|
||||
NILFS_BMAP_I(btree)->i_assoc_inode->i_mapping,
|
||||
&path[level].bp_ctxt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
nilfs_btnode_commit_change_key(
|
||||
&NILFS_BMAP_I(btree)->i_btnode_cache,
|
||||
NILFS_BMAP_I(btree)->i_assoc_inode->i_mapping,
|
||||
&path[level].bp_ctxt);
|
||||
*bh = path[level].bp_ctxt.bh;
|
||||
}
|
||||
|
|
@ -2399,6 +2406,10 @@ int nilfs_btree_init(struct nilfs_bmap *bmap)
|
|||
|
||||
if (nilfs_btree_root_broken(nilfs_btree_get_root(bmap), bmap->b_inode))
|
||||
ret = -EIO;
|
||||
else
|
||||
ret = nilfs_attach_btree_node_cache(
|
||||
&NILFS_BMAP_I(bmap)->vfs_inode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -497,7 +497,9 @@ int nilfs_dat_read(struct super_block *sb, size_t entry_size,
|
|||
di = NILFS_DAT_I(dat);
|
||||
lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
|
||||
nilfs_palloc_setup_cache(dat, &di->palloc_cache);
|
||||
nilfs_mdt_setup_shadow_map(dat, &di->shadow);
|
||||
err = nilfs_mdt_setup_shadow_map(dat, &di->shadow);
|
||||
if (err)
|
||||
goto failed;
|
||||
|
||||
err = nilfs_read_inode_common(dat, raw_inode);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -126,9 +126,10 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
|
|||
int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn,
|
||||
__u64 vbn, struct buffer_head **out_bh)
|
||||
{
|
||||
struct inode *btnc_inode = NILFS_I(inode)->i_assoc_inode;
|
||||
int ret;
|
||||
|
||||
ret = nilfs_btnode_submit_block(&NILFS_I(inode)->i_btnode_cache,
|
||||
ret = nilfs_btnode_submit_block(btnc_inode->i_mapping,
|
||||
vbn ? : pbn, pbn, REQ_OP_READ, 0,
|
||||
out_bh, &pbn);
|
||||
if (ret == -EEXIST) /* internal code (cache hit) */
|
||||
|
|
@ -170,7 +171,7 @@ int nilfs_init_gcinode(struct inode *inode)
|
|||
ii->i_flags = 0;
|
||||
nilfs_bmap_init_gc(ii->i_bmap);
|
||||
|
||||
return 0;
|
||||
return nilfs_attach_btree_node_cache(inode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -185,7 +186,7 @@ void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs)
|
|||
ii = list_first_entry(head, struct nilfs_inode_info, i_dirty);
|
||||
list_del_init(&ii->i_dirty);
|
||||
truncate_inode_pages(&ii->vfs_inode.i_data, 0);
|
||||
nilfs_btnode_cache_clear(&ii->i_btnode_cache);
|
||||
nilfs_btnode_cache_clear(ii->i_assoc_inode->i_mapping);
|
||||
iput(&ii->vfs_inode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,12 +28,16 @@
|
|||
* @cno: checkpoint number
|
||||
* @root: pointer on NILFS root object (mounted checkpoint)
|
||||
* @for_gc: inode for GC flag
|
||||
* @for_btnc: inode for B-tree node cache flag
|
||||
* @for_shadow: inode for shadowed page cache flag
|
||||
*/
|
||||
struct nilfs_iget_args {
|
||||
u64 ino;
|
||||
__u64 cno;
|
||||
struct nilfs_root *root;
|
||||
int for_gc;
|
||||
bool for_gc;
|
||||
bool for_btnc;
|
||||
bool for_shadow;
|
||||
};
|
||||
|
||||
static int nilfs_iget_test(struct inode *inode, void *opaque);
|
||||
|
|
@ -322,7 +326,8 @@ static int nilfs_insert_inode_locked(struct inode *inode,
|
|||
unsigned long ino)
|
||||
{
|
||||
struct nilfs_iget_args args = {
|
||||
.ino = ino, .root = root, .cno = 0, .for_gc = 0
|
||||
.ino = ino, .root = root, .cno = 0, .for_gc = false,
|
||||
.for_btnc = false, .for_shadow = false
|
||||
};
|
||||
|
||||
return insert_inode_locked4(inode, ino, nilfs_iget_test, &args);
|
||||
|
|
@ -534,6 +539,19 @@ static int nilfs_iget_test(struct inode *inode, void *opaque)
|
|||
return 0;
|
||||
|
||||
ii = NILFS_I(inode);
|
||||
if (test_bit(NILFS_I_BTNC, &ii->i_state)) {
|
||||
if (!args->for_btnc)
|
||||
return 0;
|
||||
} else if (args->for_btnc) {
|
||||
return 0;
|
||||
}
|
||||
if (test_bit(NILFS_I_SHADOW, &ii->i_state)) {
|
||||
if (!args->for_shadow)
|
||||
return 0;
|
||||
} else if (args->for_shadow) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!test_bit(NILFS_I_GCINODE, &ii->i_state))
|
||||
return !args->for_gc;
|
||||
|
||||
|
|
@ -545,15 +563,17 @@ static int nilfs_iget_set(struct inode *inode, void *opaque)
|
|||
struct nilfs_iget_args *args = opaque;
|
||||
|
||||
inode->i_ino = args->ino;
|
||||
if (args->for_gc) {
|
||||
NILFS_I(inode)->i_cno = args->cno;
|
||||
NILFS_I(inode)->i_root = args->root;
|
||||
if (args->root && args->ino == NILFS_ROOT_INO)
|
||||
nilfs_get_root(args->root);
|
||||
|
||||
if (args->for_gc)
|
||||
NILFS_I(inode)->i_state = BIT(NILFS_I_GCINODE);
|
||||
NILFS_I(inode)->i_cno = args->cno;
|
||||
NILFS_I(inode)->i_root = NULL;
|
||||
} else {
|
||||
if (args->root && args->ino == NILFS_ROOT_INO)
|
||||
nilfs_get_root(args->root);
|
||||
NILFS_I(inode)->i_root = args->root;
|
||||
}
|
||||
if (args->for_btnc)
|
||||
NILFS_I(inode)->i_state |= BIT(NILFS_I_BTNC);
|
||||
if (args->for_shadow)
|
||||
NILFS_I(inode)->i_state |= BIT(NILFS_I_SHADOW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -561,7 +581,8 @@ struct inode *nilfs_ilookup(struct super_block *sb, struct nilfs_root *root,
|
|||
unsigned long ino)
|
||||
{
|
||||
struct nilfs_iget_args args = {
|
||||
.ino = ino, .root = root, .cno = 0, .for_gc = 0
|
||||
.ino = ino, .root = root, .cno = 0, .for_gc = false,
|
||||
.for_btnc = false, .for_shadow = false
|
||||
};
|
||||
|
||||
return ilookup5(sb, ino, nilfs_iget_test, &args);
|
||||
|
|
@ -571,7 +592,8 @@ struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root,
|
|||
unsigned long ino)
|
||||
{
|
||||
struct nilfs_iget_args args = {
|
||||
.ino = ino, .root = root, .cno = 0, .for_gc = 0
|
||||
.ino = ino, .root = root, .cno = 0, .for_gc = false,
|
||||
.for_btnc = false, .for_shadow = false
|
||||
};
|
||||
|
||||
return iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args);
|
||||
|
|
@ -602,7 +624,8 @@ struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino,
|
|||
__u64 cno)
|
||||
{
|
||||
struct nilfs_iget_args args = {
|
||||
.ino = ino, .root = NULL, .cno = cno, .for_gc = 1
|
||||
.ino = ino, .root = NULL, .cno = cno, .for_gc = true,
|
||||
.for_btnc = false, .for_shadow = false
|
||||
};
|
||||
struct inode *inode;
|
||||
int err;
|
||||
|
|
@ -622,6 +645,113 @@ struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino,
|
|||
return inode;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_attach_btree_node_cache - attach a B-tree node cache to the inode
|
||||
* @inode: inode object
|
||||
*
|
||||
* nilfs_attach_btree_node_cache() attaches a B-tree node cache to @inode,
|
||||
* or does nothing if the inode already has it. This function allocates
|
||||
* an additional inode to maintain page cache of B-tree nodes one-on-one.
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On errors, one of the following
|
||||
* negative error code is returned.
|
||||
*
|
||||
* %-ENOMEM - Insufficient memory available.
|
||||
*/
|
||||
int nilfs_attach_btree_node_cache(struct inode *inode)
|
||||
{
|
||||
struct nilfs_inode_info *ii = NILFS_I(inode);
|
||||
struct inode *btnc_inode;
|
||||
struct nilfs_iget_args args;
|
||||
|
||||
if (ii->i_assoc_inode)
|
||||
return 0;
|
||||
|
||||
args.ino = inode->i_ino;
|
||||
args.root = ii->i_root;
|
||||
args.cno = ii->i_cno;
|
||||
args.for_gc = test_bit(NILFS_I_GCINODE, &ii->i_state) != 0;
|
||||
args.for_btnc = true;
|
||||
args.for_shadow = test_bit(NILFS_I_SHADOW, &ii->i_state) != 0;
|
||||
|
||||
btnc_inode = iget5_locked(inode->i_sb, inode->i_ino, nilfs_iget_test,
|
||||
nilfs_iget_set, &args);
|
||||
if (unlikely(!btnc_inode))
|
||||
return -ENOMEM;
|
||||
if (btnc_inode->i_state & I_NEW) {
|
||||
nilfs_init_btnc_inode(btnc_inode);
|
||||
unlock_new_inode(btnc_inode);
|
||||
}
|
||||
NILFS_I(btnc_inode)->i_assoc_inode = inode;
|
||||
NILFS_I(btnc_inode)->i_bmap = ii->i_bmap;
|
||||
ii->i_assoc_inode = btnc_inode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_detach_btree_node_cache - detach the B-tree node cache from the inode
|
||||
* @inode: inode object
|
||||
*
|
||||
* nilfs_detach_btree_node_cache() detaches the B-tree node cache and its
|
||||
* holder inode bound to @inode, or does nothing if @inode doesn't have it.
|
||||
*/
|
||||
void nilfs_detach_btree_node_cache(struct inode *inode)
|
||||
{
|
||||
struct nilfs_inode_info *ii = NILFS_I(inode);
|
||||
struct inode *btnc_inode = ii->i_assoc_inode;
|
||||
|
||||
if (btnc_inode) {
|
||||
NILFS_I(btnc_inode)->i_assoc_inode = NULL;
|
||||
ii->i_assoc_inode = NULL;
|
||||
iput(btnc_inode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_iget_for_shadow - obtain inode for shadow mapping
|
||||
* @inode: inode object that uses shadow mapping
|
||||
*
|
||||
* nilfs_iget_for_shadow() allocates a pair of inodes that holds page
|
||||
* caches for shadow mapping. The page cache for data pages is set up
|
||||
* in one inode and the one for b-tree node pages is set up in the
|
||||
* other inode, which is attached to the former inode.
|
||||
*
|
||||
* Return Value: On success, a pointer to the inode for data pages is
|
||||
* returned. On errors, one of the following negative error code is returned
|
||||
* in a pointer type.
|
||||
*
|
||||
* %-ENOMEM - Insufficient memory available.
|
||||
*/
|
||||
struct inode *nilfs_iget_for_shadow(struct inode *inode)
|
||||
{
|
||||
struct nilfs_iget_args args = {
|
||||
.ino = inode->i_ino, .root = NULL, .cno = 0, .for_gc = false,
|
||||
.for_btnc = false, .for_shadow = true
|
||||
};
|
||||
struct inode *s_inode;
|
||||
int err;
|
||||
|
||||
s_inode = iget5_locked(inode->i_sb, inode->i_ino, nilfs_iget_test,
|
||||
nilfs_iget_set, &args);
|
||||
if (unlikely(!s_inode))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (!(s_inode->i_state & I_NEW))
|
||||
return inode;
|
||||
|
||||
NILFS_I(s_inode)->i_flags = 0;
|
||||
memset(NILFS_I(s_inode)->i_bmap, 0, sizeof(struct nilfs_bmap));
|
||||
mapping_set_gfp_mask(s_inode->i_mapping, GFP_NOFS);
|
||||
|
||||
err = nilfs_attach_btree_node_cache(s_inode);
|
||||
if (unlikely(err)) {
|
||||
iget_failed(s_inode);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
unlock_new_inode(s_inode);
|
||||
return s_inode;
|
||||
}
|
||||
|
||||
void nilfs_write_inode_common(struct inode *inode,
|
||||
struct nilfs_inode *raw_inode, int has_bmap)
|
||||
{
|
||||
|
|
@ -770,7 +900,8 @@ static void nilfs_clear_inode(struct inode *inode)
|
|||
if (test_bit(NILFS_I_BMAP, &ii->i_state))
|
||||
nilfs_bmap_clear(ii->i_bmap);
|
||||
|
||||
nilfs_btnode_cache_clear(&ii->i_btnode_cache);
|
||||
if (!test_bit(NILFS_I_BTNC, &ii->i_state))
|
||||
nilfs_detach_btree_node_cache(inode);
|
||||
|
||||
if (ii->i_root && inode->i_ino == NILFS_ROOT_INO)
|
||||
nilfs_put_root(ii->i_root);
|
||||
|
|
|
|||
|
|
@ -469,9 +469,18 @@ int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz)
|
|||
void nilfs_mdt_clear(struct inode *inode)
|
||||
{
|
||||
struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
|
||||
struct nilfs_shadow_map *shadow = mdi->mi_shadow;
|
||||
|
||||
if (mdi->mi_palloc_cache)
|
||||
nilfs_palloc_destroy_cache(inode);
|
||||
|
||||
if (shadow) {
|
||||
struct inode *s_inode = shadow->inode;
|
||||
|
||||
shadow->inode = NULL;
|
||||
iput(s_inode);
|
||||
mdi->mi_shadow = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -505,12 +514,15 @@ int nilfs_mdt_setup_shadow_map(struct inode *inode,
|
|||
struct nilfs_shadow_map *shadow)
|
||||
{
|
||||
struct nilfs_mdt_info *mi = NILFS_MDT(inode);
|
||||
struct inode *s_inode;
|
||||
|
||||
INIT_LIST_HEAD(&shadow->frozen_buffers);
|
||||
address_space_init_once(&shadow->frozen_data);
|
||||
nilfs_mapping_init(&shadow->frozen_data, inode);
|
||||
address_space_init_once(&shadow->frozen_btnodes);
|
||||
nilfs_mapping_init(&shadow->frozen_btnodes, inode);
|
||||
|
||||
s_inode = nilfs_iget_for_shadow(inode);
|
||||
if (IS_ERR(s_inode))
|
||||
return PTR_ERR(s_inode);
|
||||
|
||||
shadow->inode = s_inode;
|
||||
mi->mi_shadow = shadow;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -524,14 +536,15 @@ int nilfs_mdt_save_to_shadow_map(struct inode *inode)
|
|||
struct nilfs_mdt_info *mi = NILFS_MDT(inode);
|
||||
struct nilfs_inode_info *ii = NILFS_I(inode);
|
||||
struct nilfs_shadow_map *shadow = mi->mi_shadow;
|
||||
struct inode *s_inode = shadow->inode;
|
||||
int ret;
|
||||
|
||||
ret = nilfs_copy_dirty_pages(&shadow->frozen_data, inode->i_mapping);
|
||||
ret = nilfs_copy_dirty_pages(s_inode->i_mapping, inode->i_mapping);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = nilfs_copy_dirty_pages(&shadow->frozen_btnodes,
|
||||
&ii->i_btnode_cache);
|
||||
ret = nilfs_copy_dirty_pages(NILFS_I(s_inode)->i_assoc_inode->i_mapping,
|
||||
ii->i_assoc_inode->i_mapping);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
|
@ -547,7 +560,7 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)
|
|||
struct page *page;
|
||||
int blkbits = inode->i_blkbits;
|
||||
|
||||
page = grab_cache_page(&shadow->frozen_data, bh->b_page->index);
|
||||
page = grab_cache_page(shadow->inode->i_mapping, bh->b_page->index);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -579,7 +592,7 @@ nilfs_mdt_get_frozen_buffer(struct inode *inode, struct buffer_head *bh)
|
|||
struct page *page;
|
||||
int n;
|
||||
|
||||
page = find_lock_page(&shadow->frozen_data, bh->b_page->index);
|
||||
page = find_lock_page(shadow->inode->i_mapping, bh->b_page->index);
|
||||
if (page) {
|
||||
if (page_has_buffers(page)) {
|
||||
n = bh_offset(bh) >> inode->i_blkbits;
|
||||
|
|
@ -620,10 +633,11 @@ void nilfs_mdt_restore_from_shadow_map(struct inode *inode)
|
|||
nilfs_palloc_clear_cache(inode);
|
||||
|
||||
nilfs_clear_dirty_pages(inode->i_mapping, true);
|
||||
nilfs_copy_back_pages(inode->i_mapping, &shadow->frozen_data);
|
||||
nilfs_copy_back_pages(inode->i_mapping, shadow->inode->i_mapping);
|
||||
|
||||
nilfs_clear_dirty_pages(&ii->i_btnode_cache, true);
|
||||
nilfs_copy_back_pages(&ii->i_btnode_cache, &shadow->frozen_btnodes);
|
||||
nilfs_clear_dirty_pages(ii->i_assoc_inode->i_mapping, true);
|
||||
nilfs_copy_back_pages(ii->i_assoc_inode->i_mapping,
|
||||
NILFS_I(shadow->inode)->i_assoc_inode->i_mapping);
|
||||
|
||||
nilfs_bmap_restore(ii->i_bmap, &shadow->bmap_store);
|
||||
|
||||
|
|
@ -638,10 +652,11 @@ void nilfs_mdt_clear_shadow_map(struct inode *inode)
|
|||
{
|
||||
struct nilfs_mdt_info *mi = NILFS_MDT(inode);
|
||||
struct nilfs_shadow_map *shadow = mi->mi_shadow;
|
||||
struct inode *shadow_btnc_inode = NILFS_I(shadow->inode)->i_assoc_inode;
|
||||
|
||||
down_write(&mi->mi_sem);
|
||||
nilfs_release_frozen_buffers(shadow);
|
||||
truncate_inode_pages(&shadow->frozen_data, 0);
|
||||
truncate_inode_pages(&shadow->frozen_btnodes, 0);
|
||||
truncate_inode_pages(shadow->inode->i_mapping, 0);
|
||||
truncate_inode_pages(shadow_btnc_inode->i_mapping, 0);
|
||||
up_write(&mi->mi_sem);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,12 @@
|
|||
/**
|
||||
* struct nilfs_shadow_map - shadow mapping of meta data file
|
||||
* @bmap_store: shadow copy of bmap state
|
||||
* @frozen_data: shadowed dirty data pages
|
||||
* @frozen_btnodes: shadowed dirty b-tree nodes' pages
|
||||
* @inode: holder of page caches used in shadow mapping
|
||||
* @frozen_buffers: list of frozen buffers
|
||||
*/
|
||||
struct nilfs_shadow_map {
|
||||
struct nilfs_bmap_store bmap_store;
|
||||
struct address_space frozen_data;
|
||||
struct address_space frozen_btnodes;
|
||||
struct inode *inode;
|
||||
struct list_head frozen_buffers;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
* @i_xattr: <TODO>
|
||||
* @i_dir_start_lookup: page index of last successful search
|
||||
* @i_cno: checkpoint number for GC inode
|
||||
* @i_btnode_cache: cached pages of b-tree nodes
|
||||
* @i_assoc_inode: associated inode (B-tree node cache holder or back pointer)
|
||||
* @i_dirty: list for connecting dirty files
|
||||
* @xattr_sem: semaphore for extended attributes processing
|
||||
* @i_bh: buffer contains disk inode
|
||||
|
|
@ -43,7 +43,7 @@ struct nilfs_inode_info {
|
|||
__u64 i_xattr; /* sector_t ??? */
|
||||
__u32 i_dir_start_lookup;
|
||||
__u64 i_cno; /* check point number for GC inode */
|
||||
struct address_space i_btnode_cache;
|
||||
struct inode *i_assoc_inode;
|
||||
struct list_head i_dirty; /* List for connecting dirty files */
|
||||
|
||||
#ifdef CONFIG_NILFS_XATTR
|
||||
|
|
@ -75,13 +75,6 @@ NILFS_BMAP_I(const struct nilfs_bmap *bmap)
|
|||
return container_of(bmap, struct nilfs_inode_info, i_bmap_data);
|
||||
}
|
||||
|
||||
static inline struct inode *NILFS_BTNC_I(struct address_space *btnc)
|
||||
{
|
||||
struct nilfs_inode_info *ii =
|
||||
container_of(btnc, struct nilfs_inode_info, i_btnode_cache);
|
||||
return &ii->vfs_inode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dynamic state flags of NILFS on-memory inode (i_state)
|
||||
*/
|
||||
|
|
@ -98,6 +91,8 @@ enum {
|
|||
NILFS_I_INODE_SYNC, /* dsync is not allowed for inode */
|
||||
NILFS_I_BMAP, /* has bmap and btnode_cache */
|
||||
NILFS_I_GCINODE, /* inode for GC, on memory only */
|
||||
NILFS_I_BTNC, /* inode for btree node cache */
|
||||
NILFS_I_SHADOW, /* inode for shadowed page cache */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -264,6 +259,9 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root,
|
|||
unsigned long ino);
|
||||
extern struct inode *nilfs_iget_for_gc(struct super_block *sb,
|
||||
unsigned long ino, __u64 cno);
|
||||
int nilfs_attach_btree_node_cache(struct inode *inode);
|
||||
void nilfs_detach_btree_node_cache(struct inode *inode);
|
||||
struct inode *nilfs_iget_for_shadow(struct inode *inode);
|
||||
extern void nilfs_update_inode(struct inode *, struct buffer_head *, int);
|
||||
extern void nilfs_truncate(struct inode *);
|
||||
extern void nilfs_evict_inode(struct inode *);
|
||||
|
|
|
|||
|
|
@ -450,10 +450,9 @@ void nilfs_mapping_init(struct address_space *mapping, struct inode *inode)
|
|||
/*
|
||||
* NILFS2 needs clear_page_dirty() in the following two cases:
|
||||
*
|
||||
* 1) For B-tree node pages and data pages of the dat/gcdat, NILFS2 clears
|
||||
* page dirty flags when it copies back pages from the shadow cache
|
||||
* (gcdat->{i_mapping,i_btnode_cache}) to its original cache
|
||||
* (dat->{i_mapping,i_btnode_cache}).
|
||||
* 1) For B-tree node pages and data pages of DAT file, NILFS2 clears dirty
|
||||
* flag of pages when it copies back pages from shadow cache to the
|
||||
* original cache.
|
||||
*
|
||||
* 2) Some B-tree operations like insertion or deletion may dispose buffers
|
||||
* in dirty state, and this needs to cancel the dirty state of their pages.
|
||||
|
|
|
|||
|
|
@ -738,15 +738,18 @@ static void nilfs_lookup_dirty_node_buffers(struct inode *inode,
|
|||
struct list_head *listp)
|
||||
{
|
||||
struct nilfs_inode_info *ii = NILFS_I(inode);
|
||||
struct address_space *mapping = &ii->i_btnode_cache;
|
||||
struct inode *btnc_inode = ii->i_assoc_inode;
|
||||
struct pagevec pvec;
|
||||
struct buffer_head *bh, *head;
|
||||
unsigned int i;
|
||||
pgoff_t index = 0;
|
||||
|
||||
if (!btnc_inode)
|
||||
return;
|
||||
|
||||
pagevec_init(&pvec);
|
||||
|
||||
while (pagevec_lookup_tag(&pvec, mapping, &index,
|
||||
while (pagevec_lookup_tag(&pvec, btnc_inode->i_mapping, &index,
|
||||
PAGECACHE_TAG_DIRTY)) {
|
||||
for (i = 0; i < pagevec_count(&pvec); i++) {
|
||||
bh = head = page_buffers(pvec.pages[i]);
|
||||
|
|
@ -2410,7 +2413,7 @@ nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head)
|
|||
continue;
|
||||
list_del_init(&ii->i_dirty);
|
||||
truncate_inode_pages(&ii->vfs_inode.i_data, 0);
|
||||
nilfs_btnode_cache_clear(&ii->i_btnode_cache);
|
||||
nilfs_btnode_cache_clear(ii->i_assoc_inode->i_mapping);
|
||||
iput(&ii->vfs_inode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,7 +151,8 @@ struct inode *nilfs_alloc_inode(struct super_block *sb)
|
|||
ii->i_bh = NULL;
|
||||
ii->i_state = 0;
|
||||
ii->i_cno = 0;
|
||||
nilfs_mapping_init(&ii->i_btnode_cache, &ii->vfs_inode);
|
||||
ii->i_assoc_inode = NULL;
|
||||
ii->i_bmap = &ii->i_bmap_data;
|
||||
return &ii->vfs_inode;
|
||||
}
|
||||
|
||||
|
|
@ -1375,8 +1376,6 @@ static void nilfs_inode_init_once(void *obj)
|
|||
#ifdef CONFIG_NILFS_XATTR
|
||||
init_rwsem(&ii->xattr_sem);
|
||||
#endif
|
||||
address_space_init_once(&ii->i_btnode_cache);
|
||||
ii->i_bmap = &ii->i_bmap_data;
|
||||
inode_init_once(&ii->vfs_inode);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,8 +193,6 @@ kclist_add_private(unsigned long pfn, unsigned long nr_pages, void *arg)
|
|||
return 1;
|
||||
|
||||
p = pfn_to_page(pfn);
|
||||
if (!memmap_valid_within(pfn, p, page_zone(p)))
|
||||
return 1;
|
||||
|
||||
ent = kmalloc(sizeof(*ent), GFP_KERNEL);
|
||||
if (!ent)
|
||||
|
|
|
|||
Loading…
Reference in a new issue