Merge 92477dd1fa ("Merge tag 's390-5.15-ebpf-jit-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux") into android-mainline

Steps on the way to 5.15-rc3

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ia35478d4c4a085bff847b8cd484bd3290f9529b8
This commit is contained in:
Greg Kroah-Hartman
2021-09-22 13:53:42 +02:00
77 changed files with 521 additions and 244 deletions

View File

@@ -248,8 +248,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
#define EMIT6_PCREL(op1, op2, b1, b2, i, off, mask) \ #define EMIT6_PCREL(op1, op2, b1, b2, i, off, mask) \
({ \ ({ \
/* Branch instruction needs 6 bytes */ \ int rel = (addrs[(i) + (off) + 1] - jit->prg) / 2; \
int rel = (addrs[(i) + (off) + 1] - (addrs[(i) + 1] - 6)) / 2;\
_EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), (op2) | (mask));\ _EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), (op2) | (mask));\
REG_SET_SEEN(b1); \ REG_SET_SEEN(b1); \
REG_SET_SEEN(b2); \ REG_SET_SEEN(b2); \
@@ -761,10 +760,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT4(0xb9080000, dst_reg, src_reg); EMIT4(0xb9080000, dst_reg, src_reg);
break; break;
case BPF_ALU | BPF_ADD | BPF_K: /* dst = (u32) dst + (u32) imm */ case BPF_ALU | BPF_ADD | BPF_K: /* dst = (u32) dst + (u32) imm */
if (!imm) if (imm != 0) {
break;
/* alfi %dst,imm */ /* alfi %dst,imm */
EMIT6_IMM(0xc20b0000, dst_reg, imm); EMIT6_IMM(0xc20b0000, dst_reg, imm);
}
EMIT_ZERO(dst_reg); EMIT_ZERO(dst_reg);
break; break;
case BPF_ALU64 | BPF_ADD | BPF_K: /* dst = dst + imm */ case BPF_ALU64 | BPF_ADD | BPF_K: /* dst = dst + imm */
@@ -786,17 +785,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT4(0xb9090000, dst_reg, src_reg); EMIT4(0xb9090000, dst_reg, src_reg);
break; break;
case BPF_ALU | BPF_SUB | BPF_K: /* dst = (u32) dst - (u32) imm */ case BPF_ALU | BPF_SUB | BPF_K: /* dst = (u32) dst - (u32) imm */
if (!imm) if (imm != 0) {
break;
/* alfi %dst,-imm */ /* alfi %dst,-imm */
EMIT6_IMM(0xc20b0000, dst_reg, -imm); EMIT6_IMM(0xc20b0000, dst_reg, -imm);
}
EMIT_ZERO(dst_reg); EMIT_ZERO(dst_reg);
break; break;
case BPF_ALU64 | BPF_SUB | BPF_K: /* dst = dst - imm */ case BPF_ALU64 | BPF_SUB | BPF_K: /* dst = dst - imm */
if (!imm) if (!imm)
break; break;
if (imm == -0x80000000) {
/* algfi %dst,0x80000000 */
EMIT6_IMM(0xc20a0000, dst_reg, 0x80000000);
} else {
/* agfi %dst,-imm */ /* agfi %dst,-imm */
EMIT6_IMM(0xc2080000, dst_reg, -imm); EMIT6_IMM(0xc2080000, dst_reg, -imm);
}
break; break;
/* /*
* BPF_MUL * BPF_MUL
@@ -811,10 +815,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT4(0xb90c0000, dst_reg, src_reg); EMIT4(0xb90c0000, dst_reg, src_reg);
break; break;
case BPF_ALU | BPF_MUL | BPF_K: /* dst = (u32) dst * (u32) imm */ case BPF_ALU | BPF_MUL | BPF_K: /* dst = (u32) dst * (u32) imm */
if (imm == 1) if (imm != 1) {
break;
/* msfi %r5,imm */ /* msfi %r5,imm */
EMIT6_IMM(0xc2010000, dst_reg, imm); EMIT6_IMM(0xc2010000, dst_reg, imm);
}
EMIT_ZERO(dst_reg); EMIT_ZERO(dst_reg);
break; break;
case BPF_ALU64 | BPF_MUL | BPF_K: /* dst = dst * imm */ case BPF_ALU64 | BPF_MUL | BPF_K: /* dst = dst * imm */
@@ -867,6 +871,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
if (BPF_OP(insn->code) == BPF_MOD) if (BPF_OP(insn->code) == BPF_MOD)
/* lhgi %dst,0 */ /* lhgi %dst,0 */
EMIT4_IMM(0xa7090000, dst_reg, 0); EMIT4_IMM(0xa7090000, dst_reg, 0);
else
EMIT_ZERO(dst_reg);
break; break;
} }
/* lhi %w0,0 */ /* lhi %w0,0 */
@@ -999,10 +1005,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT4(0xb9820000, dst_reg, src_reg); EMIT4(0xb9820000, dst_reg, src_reg);
break; break;
case BPF_ALU | BPF_XOR | BPF_K: /* dst = (u32) dst ^ (u32) imm */ case BPF_ALU | BPF_XOR | BPF_K: /* dst = (u32) dst ^ (u32) imm */
if (!imm) if (imm != 0) {
break;
/* xilf %dst,imm */ /* xilf %dst,imm */
EMIT6_IMM(0xc0070000, dst_reg, imm); EMIT6_IMM(0xc0070000, dst_reg, imm);
}
EMIT_ZERO(dst_reg); EMIT_ZERO(dst_reg);
break; break;
case BPF_ALU64 | BPF_XOR | BPF_K: /* dst = dst ^ imm */ case BPF_ALU64 | BPF_XOR | BPF_K: /* dst = dst ^ imm */
@@ -1033,10 +1039,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT6_DISP_LH(0xeb000000, 0x000d, dst_reg, dst_reg, src_reg, 0); EMIT6_DISP_LH(0xeb000000, 0x000d, dst_reg, dst_reg, src_reg, 0);
break; break;
case BPF_ALU | BPF_LSH | BPF_K: /* dst = (u32) dst << (u32) imm */ case BPF_ALU | BPF_LSH | BPF_K: /* dst = (u32) dst << (u32) imm */
if (imm == 0) if (imm != 0) {
break;
/* sll %dst,imm(%r0) */ /* sll %dst,imm(%r0) */
EMIT4_DISP(0x89000000, dst_reg, REG_0, imm); EMIT4_DISP(0x89000000, dst_reg, REG_0, imm);
}
EMIT_ZERO(dst_reg); EMIT_ZERO(dst_reg);
break; break;
case BPF_ALU64 | BPF_LSH | BPF_K: /* dst = dst << imm */ case BPF_ALU64 | BPF_LSH | BPF_K: /* dst = dst << imm */
@@ -1058,10 +1064,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT6_DISP_LH(0xeb000000, 0x000c, dst_reg, dst_reg, src_reg, 0); EMIT6_DISP_LH(0xeb000000, 0x000c, dst_reg, dst_reg, src_reg, 0);
break; break;
case BPF_ALU | BPF_RSH | BPF_K: /* dst = (u32) dst >> (u32) imm */ case BPF_ALU | BPF_RSH | BPF_K: /* dst = (u32) dst >> (u32) imm */
if (imm == 0) if (imm != 0) {
break;
/* srl %dst,imm(%r0) */ /* srl %dst,imm(%r0) */
EMIT4_DISP(0x88000000, dst_reg, REG_0, imm); EMIT4_DISP(0x88000000, dst_reg, REG_0, imm);
}
EMIT_ZERO(dst_reg); EMIT_ZERO(dst_reg);
break; break;
case BPF_ALU64 | BPF_RSH | BPF_K: /* dst = dst >> imm */ case BPF_ALU64 | BPF_RSH | BPF_K: /* dst = dst >> imm */
@@ -1083,10 +1089,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
EMIT6_DISP_LH(0xeb000000, 0x000a, dst_reg, dst_reg, src_reg, 0); EMIT6_DISP_LH(0xeb000000, 0x000a, dst_reg, dst_reg, src_reg, 0);
break; break;
case BPF_ALU | BPF_ARSH | BPF_K: /* ((s32) dst >> imm */ case BPF_ALU | BPF_ARSH | BPF_K: /* ((s32) dst >> imm */
if (imm == 0) if (imm != 0) {
break;
/* sra %dst,imm(%r0) */ /* sra %dst,imm(%r0) */
EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm); EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm);
}
EMIT_ZERO(dst_reg); EMIT_ZERO(dst_reg);
break; break;
case BPF_ALU64 | BPF_ARSH | BPF_K: /* ((s64) dst) >>= imm */ case BPF_ALU64 | BPF_ARSH | BPF_K: /* ((s64) dst) >>= imm */

View File

@@ -19,8 +19,10 @@ void ioport_unmap(void __iomem *addr)
EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_map);
EXPORT_SYMBOL(ioport_unmap); EXPORT_SYMBOL(ioport_unmap);
#ifdef CONFIG_PCI
void pci_iounmap(struct pci_dev *dev, void __iomem * addr) void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
{ {
/* nothing to do */ /* nothing to do */
} }
EXPORT_SYMBOL(pci_iounmap); EXPORT_SYMBOL(pci_iounmap);
#endif

View File

@@ -57,7 +57,7 @@ nvkm_control_mthd_pstate_info(struct nvkm_control *ctrl, void *data, u32 size)
args->v0.count = 0; args->v0.count = 0;
args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
args->v0.ustate_dc = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; args->v0.ustate_dc = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
args->v0.pwrsrc = -ENOSYS; args->v0.pwrsrc = -ENODEV;
args->v0.pstate = NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN; args->v0.pstate = NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN;
} }

View File

@@ -269,5 +269,3 @@ module_exit(max14577_regulator_exit);
MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver"); MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:max14577-regulator");
MODULE_ALIAS("platform:max77836-regulator");

View File

@@ -991,7 +991,7 @@ static const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = {
RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"), RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"),
RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"), RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"),
RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"), RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"),
RPMH_VREG("ldo7", "ldo%s6", &pmic5_pldo_lv, "vdd-l7"), RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l7"),
{} {}
}; };

View File

@@ -600,6 +600,12 @@ static int rockchip_spi_transfer_one(
int ret; int ret;
bool use_dma; bool use_dma;
/* Zero length transfers won't trigger an interrupt on completion */
if (!xfer->len) {
spi_finalize_current_transfer(ctlr);
return 1;
}
WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)); (readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY));

View File

@@ -204,9 +204,6 @@ struct tegra_slink_data {
struct dma_async_tx_descriptor *tx_dma_desc; struct dma_async_tx_descriptor *tx_dma_desc;
}; };
static int tegra_slink_runtime_suspend(struct device *dev);
static int tegra_slink_runtime_resume(struct device *dev);
static inline u32 tegra_slink_readl(struct tegra_slink_data *tspi, static inline u32 tegra_slink_readl(struct tegra_slink_data *tspi,
unsigned long reg) unsigned long reg)
{ {
@@ -1185,7 +1182,8 @@ static int tegra_slink_resume(struct device *dev)
} }
#endif #endif
static int __maybe_unused tegra_slink_runtime_suspend(struct device *dev) #ifdef CONFIG_PM
static int tegra_slink_runtime_suspend(struct device *dev)
{ {
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct tegra_slink_data *tspi = spi_master_get_devdata(master); struct tegra_slink_data *tspi = spi_master_get_devdata(master);
@@ -1197,7 +1195,7 @@ static int __maybe_unused tegra_slink_runtime_suspend(struct device *dev)
return 0; return 0;
} }
static int __maybe_unused tegra_slink_runtime_resume(struct device *dev) static int tegra_slink_runtime_resume(struct device *dev)
{ {
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct tegra_slink_data *tspi = spi_master_get_devdata(master); struct tegra_slink_data *tspi = spi_master_get_devdata(master);
@@ -1210,6 +1208,7 @@ static int __maybe_unused tegra_slink_runtime_resume(struct device *dev)
} }
return 0; return 0;
} }
#endif /* CONFIG_PM */
static const struct dev_pm_ops slink_pm_ops = { static const struct dev_pm_ops slink_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_slink_runtime_suspend, SET_RUNTIME_PM_OPS(tegra_slink_runtime_suspend,

View File

@@ -20,6 +20,37 @@
#include <linux/sched.h> #include <linux/sched.h>
#include "internal.h" #include "internal.h"
/*
* Handle invalidation of an mmap'd file. We invalidate all the PTEs referring
* to the pages in this file's pagecache, forcing the kernel to go through
* ->fault() or ->page_mkwrite() - at which point we can handle invalidation
* more fully.
*/
void afs_invalidate_mmap_work(struct work_struct *work)
{
struct afs_vnode *vnode = container_of(work, struct afs_vnode, cb_work);
unmap_mapping_pages(vnode->vfs_inode.i_mapping, 0, 0, false);
}
void afs_server_init_callback_work(struct work_struct *work)
{
struct afs_server *server = container_of(work, struct afs_server, initcb_work);
struct afs_vnode *vnode;
struct afs_cell *cell = server->cell;
down_read(&cell->fs_open_mmaps_lock);
list_for_each_entry(vnode, &cell->fs_open_mmaps, cb_mmap_link) {
if (vnode->cb_server == server) {
clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
queue_work(system_unbound_wq, &vnode->cb_work);
}
}
up_read(&cell->fs_open_mmaps_lock);
}
/* /*
* Allow the fileserver to request callback state (re-)initialisation. * Allow the fileserver to request callback state (re-)initialisation.
* Unfortunately, UUIDs are not guaranteed unique. * Unfortunately, UUIDs are not guaranteed unique.
@@ -29,8 +60,11 @@ void afs_init_callback_state(struct afs_server *server)
rcu_read_lock(); rcu_read_lock();
do { do {
server->cb_s_break++; server->cb_s_break++;
server = rcu_dereference(server->uuid_next); atomic_inc(&server->cell->fs_s_break);
} while (0); if (!list_empty(&server->cell->fs_open_mmaps))
queue_work(system_unbound_wq, &server->initcb_work);
} while ((server = rcu_dereference(server->uuid_next)));
rcu_read_unlock(); rcu_read_unlock();
} }
@@ -44,11 +78,17 @@ void __afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reas
clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
vnode->cb_break++; vnode->cb_break++;
vnode->cb_v_break = vnode->volume->cb_v_break;
afs_clear_permits(vnode); afs_clear_permits(vnode);
if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB) if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB)
afs_lock_may_be_available(vnode); afs_lock_may_be_available(vnode);
if (reason != afs_cb_break_for_deleted &&
vnode->status.type == AFS_FTYPE_FILE &&
atomic_read(&vnode->cb_nr_mmap))
queue_work(system_unbound_wq, &vnode->cb_work);
trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, true); trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, true);
} else { } else {
trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, false); trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, false);

View File

@@ -166,6 +166,8 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
seqlock_init(&cell->volume_lock); seqlock_init(&cell->volume_lock);
cell->fs_servers = RB_ROOT; cell->fs_servers = RB_ROOT;
seqlock_init(&cell->fs_lock); seqlock_init(&cell->fs_lock);
INIT_LIST_HEAD(&cell->fs_open_mmaps);
init_rwsem(&cell->fs_open_mmaps_lock);
rwlock_init(&cell->vl_servers_lock); rwlock_init(&cell->vl_servers_lock);
cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS); cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS);

View File

@@ -1077,9 +1077,9 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
*/ */
static int afs_d_revalidate_rcu(struct dentry *dentry) static int afs_d_revalidate_rcu(struct dentry *dentry)
{ {
struct afs_vnode *dvnode, *vnode; struct afs_vnode *dvnode;
struct dentry *parent; struct dentry *parent;
struct inode *dir, *inode; struct inode *dir;
long dir_version, de_version; long dir_version, de_version;
_enter("%p", dentry); _enter("%p", dentry);
@@ -1109,18 +1109,6 @@ static int afs_d_revalidate_rcu(struct dentry *dentry)
return -ECHILD; return -ECHILD;
} }
/* Check to see if the vnode referred to by the dentry still
* has a callback.
*/
if (d_really_is_positive(dentry)) {
inode = d_inode_rcu(dentry);
if (inode) {
vnode = AFS_FS_I(inode);
if (!afs_check_validity(vnode))
return -ECHILD;
}
}
return 1; /* Still valid */ return 1; /* Still valid */
} }
@@ -1156,17 +1144,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
if (IS_ERR(key)) if (IS_ERR(key))
key = NULL; key = NULL;
if (d_really_is_positive(dentry)) { /* Hold the parent dentry so we can peer at it */
inode = d_inode(dentry);
if (inode) {
vnode = AFS_FS_I(inode);
afs_validate(vnode, key);
if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
goto out_bad;
}
}
/* lock down the parent dentry so we can peer at it */
parent = dget_parent(dentry); parent = dget_parent(dentry);
dir = AFS_FS_I(d_inode(parent)); dir = AFS_FS_I(d_inode(parent));
@@ -1175,7 +1153,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
if (test_bit(AFS_VNODE_DELETED, &dir->flags)) { if (test_bit(AFS_VNODE_DELETED, &dir->flags)) {
_debug("%pd: parent dir deleted", dentry); _debug("%pd: parent dir deleted", dentry);
goto out_bad_parent; goto not_found;
} }
/* We only need to invalidate a dentry if the server's copy changed /* We only need to invalidate a dentry if the server's copy changed
@@ -1201,12 +1179,12 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
case 0: case 0:
/* the filename maps to something */ /* the filename maps to something */
if (d_really_is_negative(dentry)) if (d_really_is_negative(dentry))
goto out_bad_parent; goto not_found;
inode = d_inode(dentry); inode = d_inode(dentry);
if (is_bad_inode(inode)) { if (is_bad_inode(inode)) {
printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n", printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n",
dentry); dentry);
goto out_bad_parent; goto not_found;
} }
vnode = AFS_FS_I(inode); vnode = AFS_FS_I(inode);
@@ -1228,9 +1206,6 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
dentry, fid.unique, dentry, fid.unique,
vnode->fid.unique, vnode->fid.unique,
vnode->vfs_inode.i_generation); vnode->vfs_inode.i_generation);
write_seqlock(&vnode->cb_lock);
set_bit(AFS_VNODE_DELETED, &vnode->flags);
write_sequnlock(&vnode->cb_lock);
goto not_found; goto not_found;
} }
goto out_valid; goto out_valid;
@@ -1245,7 +1220,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
default: default:
_debug("failed to iterate dir %pd: %d", _debug("failed to iterate dir %pd: %d",
parent, ret); parent, ret);
goto out_bad_parent; goto not_found;
} }
out_valid: out_valid:
@@ -1256,16 +1231,9 @@ out_valid_noupdate:
_leave(" = 1 [valid]"); _leave(" = 1 [valid]");
return 1; return 1;
/* the dirent, if it exists, now points to a different vnode */
not_found: not_found:
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_NFSFS_RENAMED;
spin_unlock(&dentry->d_lock);
out_bad_parent:
_debug("dropping dentry %pd2", dentry); _debug("dropping dentry %pd2", dentry);
dput(parent); dput(parent);
out_bad:
key_put(key); key_put(key);
_leave(" = 0 [bad]"); _leave(" = 0 [bad]");
@@ -1792,6 +1760,10 @@ static int afs_link(struct dentry *from, struct inode *dir,
goto error; goto error;
} }
ret = afs_validate(vnode, op->key);
if (ret < 0)
goto error_op;
afs_op_set_vnode(op, 0, dvnode); afs_op_set_vnode(op, 0, dvnode);
afs_op_set_vnode(op, 1, vnode); afs_op_set_vnode(op, 1, vnode);
op->file[0].dv_delta = 1; op->file[0].dv_delta = 1;
@@ -1805,6 +1777,8 @@ static int afs_link(struct dentry *from, struct inode *dir,
op->create.reason = afs_edit_dir_for_link; op->create.reason = afs_edit_dir_for_link;
return afs_do_sync_operation(op); return afs_do_sync_operation(op);
error_op:
afs_put_operation(op);
error: error:
d_drop(dentry); d_drop(dentry);
_leave(" = %d", ret); _leave(" = %d", ret);
@@ -1989,6 +1963,11 @@ static int afs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
if (IS_ERR(op)) if (IS_ERR(op))
return PTR_ERR(op); return PTR_ERR(op);
ret = afs_validate(vnode, op->key);
op->error = ret;
if (ret < 0)
goto error;
afs_op_set_vnode(op, 0, orig_dvnode); afs_op_set_vnode(op, 0, orig_dvnode);
afs_op_set_vnode(op, 1, new_dvnode); /* May be same as orig_dvnode */ afs_op_set_vnode(op, 1, new_dvnode); /* May be same as orig_dvnode */
op->file[0].dv_delta = 1; op->file[0].dv_delta = 1;

View File

@@ -263,7 +263,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode,
if (b == nr_blocks) { if (b == nr_blocks) {
_debug("init %u", b); _debug("init %u", b);
afs_edit_init_block(meta, block, b); afs_edit_init_block(meta, block, b);
i_size_write(&vnode->vfs_inode, (b + 1) * AFS_DIR_BLOCK_SIZE); afs_set_i_size(vnode, (b + 1) * AFS_DIR_BLOCK_SIZE);
} }
/* Only lower dir pages have a counter in the header. */ /* Only lower dir pages have a counter in the header. */
@@ -296,7 +296,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode,
new_directory: new_directory:
afs_edit_init_block(meta, meta, 0); afs_edit_init_block(meta, meta, 0);
i_size = AFS_DIR_BLOCK_SIZE; i_size = AFS_DIR_BLOCK_SIZE;
i_size_write(&vnode->vfs_inode, i_size); afs_set_i_size(vnode, i_size);
slot = AFS_DIR_RESV_BLOCKS0; slot = AFS_DIR_RESV_BLOCKS0;
page = page0; page = page0;
block = meta; block = meta;

View File

@@ -24,12 +24,16 @@ static void afs_invalidatepage(struct page *page, unsigned int offset,
static int afs_releasepage(struct page *page, gfp_t gfp_flags); static int afs_releasepage(struct page *page, gfp_t gfp_flags);
static void afs_readahead(struct readahead_control *ractl); static void afs_readahead(struct readahead_control *ractl);
static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
static void afs_vm_open(struct vm_area_struct *area);
static void afs_vm_close(struct vm_area_struct *area);
static vm_fault_t afs_vm_map_pages(struct vm_fault *vmf, pgoff_t start_pgoff, pgoff_t end_pgoff);
const struct file_operations afs_file_operations = { const struct file_operations afs_file_operations = {
.open = afs_open, .open = afs_open,
.release = afs_release, .release = afs_release,
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
.read_iter = generic_file_read_iter, .read_iter = afs_file_read_iter,
.write_iter = afs_file_write, .write_iter = afs_file_write,
.mmap = afs_file_mmap, .mmap = afs_file_mmap,
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
@@ -59,8 +63,10 @@ const struct address_space_operations afs_fs_aops = {
}; };
static const struct vm_operations_struct afs_vm_ops = { static const struct vm_operations_struct afs_vm_ops = {
.open = afs_vm_open,
.close = afs_vm_close,
.fault = filemap_fault, .fault = filemap_fault,
.map_pages = filemap_map_pages, .map_pages = afs_vm_map_pages,
.page_mkwrite = afs_page_mkwrite, .page_mkwrite = afs_page_mkwrite,
}; };
@@ -295,7 +301,7 @@ static void afs_req_issue_op(struct netfs_read_subrequest *subreq)
fsreq->subreq = subreq; fsreq->subreq = subreq;
fsreq->pos = subreq->start + subreq->transferred; fsreq->pos = subreq->start + subreq->transferred;
fsreq->len = subreq->len - subreq->transferred; fsreq->len = subreq->len - subreq->transferred;
fsreq->key = subreq->rreq->netfs_priv; fsreq->key = key_get(subreq->rreq->netfs_priv);
fsreq->vnode = vnode; fsreq->vnode = vnode;
fsreq->iter = &fsreq->def_iter; fsreq->iter = &fsreq->def_iter;
@@ -304,6 +310,7 @@ static void afs_req_issue_op(struct netfs_read_subrequest *subreq)
fsreq->pos, fsreq->len); fsreq->pos, fsreq->len);
afs_fetch_data(fsreq->vnode, fsreq); afs_fetch_data(fsreq->vnode, fsreq);
afs_put_read(fsreq);
} }
static int afs_symlink_readpage(struct page *page) static int afs_symlink_readpage(struct page *page)
@@ -490,15 +497,88 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)
return 1; return 1;
} }
static void afs_add_open_mmap(struct afs_vnode *vnode)
{
if (atomic_inc_return(&vnode->cb_nr_mmap) == 1) {
down_write(&vnode->volume->cell->fs_open_mmaps_lock);
list_add_tail(&vnode->cb_mmap_link,
&vnode->volume->cell->fs_open_mmaps);
up_write(&vnode->volume->cell->fs_open_mmaps_lock);
}
}
static void afs_drop_open_mmap(struct afs_vnode *vnode)
{
if (!atomic_dec_and_test(&vnode->cb_nr_mmap))
return;
down_write(&vnode->volume->cell->fs_open_mmaps_lock);
if (atomic_read(&vnode->cb_nr_mmap) == 0)
list_del_init(&vnode->cb_mmap_link);
up_write(&vnode->volume->cell->fs_open_mmaps_lock);
flush_work(&vnode->cb_work);
}
/* /*
* Handle setting up a memory mapping on an AFS file. * Handle setting up a memory mapping on an AFS file.
*/ */
static int afs_file_mmap(struct file *file, struct vm_area_struct *vma) static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
{ {
struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
int ret; int ret;
afs_add_open_mmap(vnode);
ret = generic_file_mmap(file, vma); ret = generic_file_mmap(file, vma);
if (ret == 0) if (ret == 0)
vma->vm_ops = &afs_vm_ops; vma->vm_ops = &afs_vm_ops;
else
afs_drop_open_mmap(vnode);
return ret; return ret;
} }
static void afs_vm_open(struct vm_area_struct *vma)
{
afs_add_open_mmap(AFS_FS_I(file_inode(vma->vm_file)));
}
static void afs_vm_close(struct vm_area_struct *vma)
{
afs_drop_open_mmap(AFS_FS_I(file_inode(vma->vm_file)));
}
static vm_fault_t afs_vm_map_pages(struct vm_fault *vmf, pgoff_t start_pgoff, pgoff_t end_pgoff)
{
struct afs_vnode *vnode = AFS_FS_I(file_inode(vmf->vma->vm_file));
struct afs_file *af = vmf->vma->vm_file->private_data;
switch (afs_validate(vnode, af->key)) {
case 0:
return filemap_map_pages(vmf, start_pgoff, end_pgoff);
case -ENOMEM:
return VM_FAULT_OOM;
case -EINTR:
case -ERESTARTSYS:
return VM_FAULT_RETRY;
case -ESTALE:
default:
return VM_FAULT_SIGBUS;
}
}
static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
struct afs_vnode *vnode = AFS_FS_I(file_inode(iocb->ki_filp));
struct afs_file *af = iocb->ki_filp->private_data;
int ret;
ret = afs_validate(vnode, af->key);
if (ret < 0)
return ret;
return generic_file_read_iter(iocb, iter);
}

View File

@@ -9,6 +9,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "afs_fs.h" #include "afs_fs.h"
#include "internal.h" #include "internal.h"
#include "protocol_afs.h"
#include "protocol_yfs.h" #include "protocol_yfs.h"
static unsigned int afs_fs_probe_fast_poll_interval = 30 * HZ; static unsigned int afs_fs_probe_fast_poll_interval = 30 * HZ;
@@ -102,7 +103,7 @@ void afs_fileserver_probe_result(struct afs_call *call)
struct afs_addr_list *alist = call->alist; struct afs_addr_list *alist = call->alist;
struct afs_server *server = call->server; struct afs_server *server = call->server;
unsigned int index = call->addr_ix; unsigned int index = call->addr_ix;
unsigned int rtt_us = 0; unsigned int rtt_us = 0, cap0;
int ret = call->error; int ret = call->error;
_enter("%pU,%u", &server->uuid, index); _enter("%pU,%u", &server->uuid, index);
@@ -159,6 +160,11 @@ responded:
clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags); clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags);
alist->addrs[index].srx_service = call->service_id; alist->addrs[index].srx_service = call->service_id;
} }
cap0 = ntohl(call->tmp);
if (cap0 & AFS3_VICED_CAPABILITY_64BITFILES)
set_bit(AFS_SERVER_FL_HAS_FS64, &server->flags);
else
clear_bit(AFS_SERVER_FL_HAS_FS64, &server->flags);
} }
if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) && if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) &&

View File

@@ -456,9 +456,7 @@ void afs_fs_fetch_data(struct afs_operation *op)
struct afs_read *req = op->fetch.req; struct afs_read *req = op->fetch.req;
__be32 *bp; __be32 *bp;
if (upper_32_bits(req->pos) || if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))
upper_32_bits(req->len) ||
upper_32_bits(req->pos + req->len))
return afs_fs_fetch_data64(op); return afs_fs_fetch_data64(op);
_enter(""); _enter("");
@@ -1113,9 +1111,7 @@ void afs_fs_store_data(struct afs_operation *op)
(unsigned long long)op->store.pos, (unsigned long long)op->store.pos,
(unsigned long long)op->store.i_size); (unsigned long long)op->store.i_size);
if (upper_32_bits(op->store.pos) || if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))
upper_32_bits(op->store.size) ||
upper_32_bits(op->store.i_size))
return afs_fs_store_data64(op); return afs_fs_store_data64(op);
call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData, call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData,
@@ -1229,7 +1225,7 @@ static void afs_fs_setattr_size(struct afs_operation *op)
key_serial(op->key), vp->fid.vid, vp->fid.vnode); key_serial(op->key), vp->fid.vid, vp->fid.vnode);
ASSERT(attr->ia_valid & ATTR_SIZE); ASSERT(attr->ia_valid & ATTR_SIZE);
if (upper_32_bits(attr->ia_size)) if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))
return afs_fs_setattr_size64(op); return afs_fs_setattr_size64(op);
call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status, call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status,
@@ -1657,20 +1653,33 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call)
return ret; return ret;
count = ntohl(call->tmp); count = ntohl(call->tmp);
call->count = count; call->count = count;
call->count2 = count; call->count2 = count;
afs_extract_discard(call, count * sizeof(__be32)); if (count == 0) {
call->unmarshall = 4;
call->tmp = 0;
break;
}
/* Extract the first word of the capabilities to call->tmp */
afs_extract_to_tmp(call);
call->unmarshall++; call->unmarshall++;
fallthrough; fallthrough;
/* Extract capabilities words */
case 2: case 2:
ret = afs_extract_data(call, false); ret = afs_extract_data(call, false);
if (ret < 0) if (ret < 0)
return ret; return ret;
/* TODO: Examine capabilities */ afs_extract_discard(call, (count - 1) * sizeof(__be32));
call->unmarshall++;
fallthrough;
/* Extract remaining capabilities words */
case 3:
ret = afs_extract_data(call, false);
if (ret < 0)
return ret;
call->unmarshall++; call->unmarshall++;
break; break;

View File

@@ -53,16 +53,6 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren
dump_stack(); dump_stack();
} }
/*
* Set the file size and block count. Estimate the number of 512 bytes blocks
* used, rounded up to nearest 1K for consistency with other AFS clients.
*/
static void afs_set_i_size(struct afs_vnode *vnode, u64 size)
{
i_size_write(&vnode->vfs_inode, size);
vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1;
}
/* /*
* Initialise an inode from the vnode status. * Initialise an inode from the vnode status.
*/ */
@@ -587,22 +577,32 @@ static void afs_zap_data(struct afs_vnode *vnode)
} }
/* /*
* Get the server reinit counter for a vnode's current server. * Check to see if we have a server currently serving this volume and that it
* hasn't been reinitialised or dropped from the list.
*/ */
static bool afs_get_s_break_rcu(struct afs_vnode *vnode, unsigned int *_s_break) static bool afs_check_server_good(struct afs_vnode *vnode)
{ {
struct afs_server_list *slist = rcu_dereference(vnode->volume->servers); struct afs_server_list *slist;
struct afs_server *server; struct afs_server *server;
bool good;
int i; int i;
if (vnode->cb_fs_s_break == atomic_read(&vnode->volume->cell->fs_s_break))
return true;
rcu_read_lock();
slist = rcu_dereference(vnode->volume->servers);
for (i = 0; i < slist->nr_servers; i++) { for (i = 0; i < slist->nr_servers; i++) {
server = slist->servers[i].server; server = slist->servers[i].server;
if (server == vnode->cb_server) { if (server == vnode->cb_server) {
*_s_break = READ_ONCE(server->cb_s_break); good = (vnode->cb_s_break == server->cb_s_break);
return true; rcu_read_unlock();
return good;
} }
} }
rcu_read_unlock();
return false; return false;
} }
@@ -611,57 +611,46 @@ static bool afs_get_s_break_rcu(struct afs_vnode *vnode, unsigned int *_s_break)
*/ */
bool afs_check_validity(struct afs_vnode *vnode) bool afs_check_validity(struct afs_vnode *vnode)
{ {
struct afs_volume *volume = vnode->volume;
enum afs_cb_break_reason need_clear = afs_cb_break_no_break; enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
time64_t now = ktime_get_real_seconds(); time64_t now = ktime_get_real_seconds();
bool valid; unsigned int cb_break;
unsigned int cb_break, cb_s_break, cb_v_break;
int seq = 0; int seq = 0;
do { do {
read_seqbegin_or_lock(&vnode->cb_lock, &seq); read_seqbegin_or_lock(&vnode->cb_lock, &seq);
cb_v_break = READ_ONCE(volume->cb_v_break);
cb_break = vnode->cb_break; cb_break = vnode->cb_break;
if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) && if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
afs_get_s_break_rcu(vnode, &cb_s_break)) { if (vnode->cb_v_break != vnode->volume->cb_v_break)
if (vnode->cb_s_break != cb_s_break || need_clear = afs_cb_break_for_v_break;
vnode->cb_v_break != cb_v_break) { else if (!afs_check_server_good(vnode))
vnode->cb_s_break = cb_s_break; need_clear = afs_cb_break_for_s_reinit;
vnode->cb_v_break = cb_v_break; else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags))
need_clear = afs_cb_break_for_vsbreak;
valid = false;
} else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
need_clear = afs_cb_break_for_zap; need_clear = afs_cb_break_for_zap;
valid = false; else if (vnode->cb_expires_at - 10 <= now)
} else if (vnode->cb_expires_at - 10 <= now) {
need_clear = afs_cb_break_for_lapsed; need_clear = afs_cb_break_for_lapsed;
valid = false;
} else {
valid = true;
}
} else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
valid = true; ;
} else { } else {
vnode->cb_v_break = cb_v_break; need_clear = afs_cb_break_no_promise;
valid = false;
} }
} while (need_seqretry(&vnode->cb_lock, seq)); } while (need_seqretry(&vnode->cb_lock, seq));
done_seqretry(&vnode->cb_lock, seq); done_seqretry(&vnode->cb_lock, seq);
if (need_clear != afs_cb_break_no_break) { if (need_clear == afs_cb_break_no_break)
return true;
write_seqlock(&vnode->cb_lock); write_seqlock(&vnode->cb_lock);
if (cb_break == vnode->cb_break) if (need_clear == afs_cb_break_no_promise)
vnode->cb_v_break = vnode->volume->cb_v_break;
else if (cb_break == vnode->cb_break)
__afs_break_callback(vnode, need_clear); __afs_break_callback(vnode, need_clear);
else else
trace_afs_cb_miss(&vnode->fid, need_clear); trace_afs_cb_miss(&vnode->fid, need_clear);
write_sequnlock(&vnode->cb_lock); write_sequnlock(&vnode->cb_lock);
valid = false; return false;
}
return valid;
} }
/* /*
@@ -675,21 +664,20 @@ bool afs_check_validity(struct afs_vnode *vnode)
*/ */
int afs_validate(struct afs_vnode *vnode, struct key *key) int afs_validate(struct afs_vnode *vnode, struct key *key)
{ {
bool valid;
int ret; int ret;
_enter("{v={%llx:%llu} fl=%lx},%x", _enter("{v={%llx:%llu} fl=%lx},%x",
vnode->fid.vid, vnode->fid.vnode, vnode->flags, vnode->fid.vid, vnode->fid.vnode, vnode->flags,
key_serial(key)); key_serial(key));
rcu_read_lock(); if (unlikely(test_bit(AFS_VNODE_DELETED, &vnode->flags))) {
valid = afs_check_validity(vnode); if (vnode->vfs_inode.i_nlink)
rcu_read_unlock();
if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
clear_nlink(&vnode->vfs_inode); clear_nlink(&vnode->vfs_inode);
goto valid;
}
if (valid) if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) &&
afs_check_validity(vnode))
goto valid; goto valid;
down_write(&vnode->validate_lock); down_write(&vnode->validate_lock);

View File

@@ -390,6 +390,9 @@ struct afs_cell {
/* Active fileserver interaction state. */ /* Active fileserver interaction state. */
struct rb_root fs_servers; /* afs_server (by server UUID) */ struct rb_root fs_servers; /* afs_server (by server UUID) */
seqlock_t fs_lock; /* For fs_servers */ seqlock_t fs_lock; /* For fs_servers */
struct rw_semaphore fs_open_mmaps_lock;
struct list_head fs_open_mmaps; /* List of vnodes that are mmapped */
atomic_t fs_s_break; /* Counter of CB.InitCallBackState messages */
/* VL server list. */ /* VL server list. */
rwlock_t vl_servers_lock; /* Lock on vl_servers */ rwlock_t vl_servers_lock; /* Lock on vl_servers */
@@ -503,6 +506,7 @@ struct afs_server {
struct hlist_node addr4_link; /* Link in net->fs_addresses4 */ struct hlist_node addr4_link; /* Link in net->fs_addresses4 */
struct hlist_node addr6_link; /* Link in net->fs_addresses6 */ struct hlist_node addr6_link; /* Link in net->fs_addresses6 */
struct hlist_node proc_link; /* Link in net->fs_proc */ struct hlist_node proc_link; /* Link in net->fs_proc */
struct work_struct initcb_work; /* Work for CB.InitCallBackState* */
struct afs_server *gc_next; /* Next server in manager's list */ struct afs_server *gc_next; /* Next server in manager's list */
time64_t unuse_time; /* Time at which last unused */ time64_t unuse_time; /* Time at which last unused */
unsigned long flags; unsigned long flags;
@@ -516,6 +520,7 @@ struct afs_server {
#define AFS_SERVER_FL_IS_YFS 16 /* Server is YFS not AFS */ #define AFS_SERVER_FL_IS_YFS 16 /* Server is YFS not AFS */
#define AFS_SERVER_FL_NO_IBULK 17 /* Fileserver doesn't support FS.InlineBulkStatus */ #define AFS_SERVER_FL_NO_IBULK 17 /* Fileserver doesn't support FS.InlineBulkStatus */
#define AFS_SERVER_FL_NO_RM2 18 /* Fileserver doesn't support YFS.RemoveFile2 */ #define AFS_SERVER_FL_NO_RM2 18 /* Fileserver doesn't support YFS.RemoveFile2 */
#define AFS_SERVER_FL_HAS_FS64 19 /* Fileserver supports FS.{Fetch,Store}Data64 */
atomic_t ref; /* Object refcount */ atomic_t ref; /* Object refcount */
atomic_t active; /* Active user count */ atomic_t active; /* Active user count */
u32 addr_version; /* Address list version */ u32 addr_version; /* Address list version */
@@ -657,7 +662,11 @@ struct afs_vnode {
afs_lock_type_t lock_type : 8; afs_lock_type_t lock_type : 8;
/* outstanding callback notification on this file */ /* outstanding callback notification on this file */
struct work_struct cb_work; /* Work for mmap'd files */
struct list_head cb_mmap_link; /* Link in cell->fs_open_mmaps */
void *cb_server; /* Server with callback/filelock */ void *cb_server; /* Server with callback/filelock */
atomic_t cb_nr_mmap; /* Number of mmaps */
unsigned int cb_fs_s_break; /* Mass server break counter (cell->fs_s_break) */
unsigned int cb_s_break; /* Mass break counter on ->server */ unsigned int cb_s_break; /* Mass break counter on ->server */
unsigned int cb_v_break; /* Mass break counter on ->volume */ unsigned int cb_v_break; /* Mass break counter on ->volume */
unsigned int cb_break; /* Break counter on vnode */ unsigned int cb_break; /* Break counter on vnode */
@@ -965,6 +974,8 @@ extern struct fscache_cookie_def afs_vnode_cache_index_def;
/* /*
* callback.c * callback.c
*/ */
extern void afs_invalidate_mmap_work(struct work_struct *);
extern void afs_server_init_callback_work(struct work_struct *work);
extern void afs_init_callback_state(struct afs_server *); extern void afs_init_callback_state(struct afs_server *);
extern void __afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason); extern void __afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);
extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason); extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);
@@ -1585,6 +1596,16 @@ static inline void afs_update_dentry_version(struct afs_operation *op,
(void *)(unsigned long)dir_vp->scb.status.data_version; (void *)(unsigned long)dir_vp->scb.status.data_version;
} }
/*
* Set the file size and block count. Estimate the number of 512 bytes blocks
* used, rounded up to nearest 1K for consistency with other AFS clients.
*/
static inline void afs_set_i_size(struct afs_vnode *vnode, u64 size)
{
i_size_write(&vnode->vfs_inode, size);
vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1;
}
/* /*
* Check for a conflicting operation on a directory that we just unlinked from. * Check for a conflicting operation on a directory that we just unlinked from.
* If someone managed to sneak a link or an unlink in on the file we just * If someone managed to sneak a link or an unlink in on the file we just

15
fs/afs/protocol_afs.h Normal file
View File

@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* AFS protocol bits
*
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#define AFSCAPABILITIESMAX 196 /* Maximum number of words in a capability set */
/* AFS3 Fileserver capabilities word 0 */
#define AFS3_VICED_CAPABILITY_ERRORTRANS 0x0001 /* Uses UAE errors */
#define AFS3_VICED_CAPABILITY_64BITFILES 0x0002 /* FetchData64 & StoreData64 supported */
#define AFS3_VICED_CAPABILITY_WRITELOCKACL 0x0004 /* Can lock a file even without lock perm */
#define AFS3_VICED_CAPABILITY_SANEACLS 0x0008 /* ACLs reviewed for sanity - don't use */

View File

@@ -168,3 +168,9 @@ enum yfs_lock_type {
yfs_LockMandatoryWrite = 0x101, yfs_LockMandatoryWrite = 0x101,
yfs_LockMandatoryExtend = 0x102, yfs_LockMandatoryExtend = 0x102,
}; };
/* RXYFS Viced Capability Flags */
#define YFS_VICED_CAPABILITY_ERRORTRANS 0x0001 /* Deprecated v0.195 */
#define YFS_VICED_CAPABILITY_64BITFILES 0x0002 /* Deprecated v0.195 */
#define YFS_VICED_CAPABILITY_WRITELOCKACL 0x0004 /* Can lock a file even without lock perm */
#define YFS_VICED_CAPABILITY_SANEACLS 0x0008 /* Deprecated v0.195 */

View File

@@ -374,6 +374,7 @@ selected_server:
if (vnode->cb_server != server) { if (vnode->cb_server != server) {
vnode->cb_server = server; vnode->cb_server = server;
vnode->cb_s_break = server->cb_s_break; vnode->cb_s_break = server->cb_s_break;
vnode->cb_fs_s_break = atomic_read(&server->cell->fs_s_break);
vnode->cb_v_break = vnode->volume->cb_v_break; vnode->cb_v_break = vnode->volume->cb_v_break;
clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
} }

View File

@@ -235,6 +235,7 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell,
server->addr_version = alist->version; server->addr_version = alist->version;
server->uuid = *uuid; server->uuid = *uuid;
rwlock_init(&server->fs_lock); rwlock_init(&server->fs_lock);
INIT_WORK(&server->initcb_work, afs_server_init_callback_work);
init_waitqueue_head(&server->probe_wq); init_waitqueue_head(&server->probe_wq);
INIT_LIST_HEAD(&server->probe_link); INIT_LIST_HEAD(&server->probe_link);
spin_lock_init(&server->probe_lock); spin_lock_init(&server->probe_lock);
@@ -467,6 +468,7 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags)) if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
afs_give_up_callbacks(net, server); afs_give_up_callbacks(net, server);
flush_work(&server->initcb_work);
afs_put_server(net, server, afs_server_trace_destroy); afs_put_server(net, server, afs_server_trace_destroy);
} }

View File

@@ -698,6 +698,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
vnode->lock_state = AFS_VNODE_LOCK_NONE; vnode->lock_state = AFS_VNODE_LOCK_NONE;
init_rwsem(&vnode->rmdir_lock); init_rwsem(&vnode->rmdir_lock);
INIT_WORK(&vnode->cb_work, afs_invalidate_mmap_work);
_leave(" = %p", &vnode->vfs_inode); _leave(" = %p", &vnode->vfs_inode);
return &vnode->vfs_inode; return &vnode->vfs_inode;

View File

@@ -137,7 +137,7 @@ int afs_write_end(struct file *file, struct address_space *mapping,
write_seqlock(&vnode->cb_lock); write_seqlock(&vnode->cb_lock);
i_size = i_size_read(&vnode->vfs_inode); i_size = i_size_read(&vnode->vfs_inode);
if (maybe_i_size > i_size) if (maybe_i_size > i_size)
i_size_write(&vnode->vfs_inode, maybe_i_size); afs_set_i_size(vnode, maybe_i_size);
write_sequnlock(&vnode->cb_lock); write_sequnlock(&vnode->cb_lock);
} }
@@ -471,13 +471,18 @@ static void afs_extend_writeback(struct address_space *mapping,
} }
/* Has the page moved or been split? */ /* Has the page moved or been split? */
if (unlikely(page != xas_reload(&xas))) if (unlikely(page != xas_reload(&xas))) {
put_page(page);
break; break;
}
if (!trylock_page(page)) if (!trylock_page(page)) {
put_page(page);
break; break;
}
if (!PageDirty(page) || PageWriteback(page)) { if (!PageDirty(page) || PageWriteback(page)) {
unlock_page(page); unlock_page(page);
put_page(page);
break; break;
} }
@@ -487,6 +492,7 @@ static void afs_extend_writeback(struct address_space *mapping,
t = afs_page_dirty_to(page, priv); t = afs_page_dirty_to(page, priv);
if (f != 0 && !new_content) { if (f != 0 && !new_content) {
unlock_page(page); unlock_page(page);
put_page(page);
break; break;
} }
@@ -801,6 +807,7 @@ int afs_writepages(struct address_space *mapping,
ssize_t afs_file_write(struct kiocb *iocb, struct iov_iter *from) ssize_t afs_file_write(struct kiocb *iocb, struct iov_iter *from)
{ {
struct afs_vnode *vnode = AFS_FS_I(file_inode(iocb->ki_filp)); struct afs_vnode *vnode = AFS_FS_I(file_inode(iocb->ki_filp));
struct afs_file *af = iocb->ki_filp->private_data;
ssize_t result; ssize_t result;
size_t count = iov_iter_count(from); size_t count = iov_iter_count(from);
@@ -816,6 +823,10 @@ ssize_t afs_file_write(struct kiocb *iocb, struct iov_iter *from)
if (!count) if (!count)
return 0; return 0;
result = afs_validate(vnode, af->key);
if (result < 0)
return result;
result = generic_file_write_iter(iocb, from); result = generic_file_write_iter(iocb, from);
_leave(" = %zd", result); _leave(" = %zd", result);
@@ -829,13 +840,18 @@ ssize_t afs_file_write(struct kiocb *iocb, struct iov_iter *from)
*/ */
int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync) int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{ {
struct inode *inode = file_inode(file); struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
struct afs_vnode *vnode = AFS_FS_I(inode); struct afs_file *af = file->private_data;
int ret;
_enter("{%llx:%llu},{n=%pD},%d", _enter("{%llx:%llu},{n=%pD},%d",
vnode->fid.vid, vnode->fid.vnode, file, vnode->fid.vid, vnode->fid.vnode, file,
datasync); datasync);
ret = afs_validate(vnode, af->key);
if (ret < 0)
return ret;
return file_write_and_wait_range(file, start, end); return file_write_and_wait_range(file, start, end);
} }
@@ -849,11 +865,14 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf)
struct file *file = vmf->vma->vm_file; struct file *file = vmf->vma->vm_file;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct afs_vnode *vnode = AFS_FS_I(inode); struct afs_vnode *vnode = AFS_FS_I(inode);
struct afs_file *af = file->private_data;
unsigned long priv; unsigned long priv;
vm_fault_t ret = VM_FAULT_RETRY; vm_fault_t ret = VM_FAULT_RETRY;
_enter("{{%llx:%llu}},{%lx}", vnode->fid.vid, vnode->fid.vnode, page->index); _enter("{{%llx:%llu}},{%lx}", vnode->fid.vid, vnode->fid.vnode, page->index);
afs_validate(vnode, af->key);
sb_start_pagefault(inode->i_sb); sb_start_pagefault(inode->i_sb);
/* Wait for the page to be written to the cache before we allow it to /* Wait for the page to be written to the cache before we allow it to

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/cache.c - CIFS filesystem cache index structure definitions * CIFS filesystem cache index structure definitions
* *
* Copyright (c) 2010 Novell, Inc. * Copyright (c) 2010 Novell, Inc.
* Authors(s): Suresh Jayaraman (sjayaraman@suse.de> * Authors(s): Suresh Jayaraman (sjayaraman@suse.de>

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* fs/cifs_debug.c
* *
* Copyright (C) International Business Machines Corp., 2000,2005 * Copyright (C) International Business Machines Corp., 2000,2005
* *

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifs_fs_sb.h
* *
* Copyright (c) International Business Machines Corp., 2002,2004 * Copyright (c) International Business Machines Corp., 2002,2004
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifs_ioctl.h
* *
* Structure definitions for io control for cifs/smb3 * Structure definitions for io control for cifs/smb3
* *

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/cifs_spnego.c -- SPNEGO upcall management for CIFS * SPNEGO upcall management for CIFS
* *
* Copyright (c) 2007 Red Hat, Inc. * Copyright (c) 2007 Red Hat, Inc.
* Author(s): Jeff Layton (jlayton@redhat.com) * Author(s): Jeff Layton (jlayton@redhat.com)

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifs_spnego.h -- SPNEGO upcall management for CIFS * SPNEGO upcall management for CIFS
* *
* Copyright (c) 2007 Red Hat, Inc. * Copyright (c) 2007 Red Hat, Inc.
* Author(s): Jeff Layton (jlayton@redhat.com) * Author(s): Jeff Layton (jlayton@redhat.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* fs/cifs/cifs_unicode.c
* *
* Copyright (c) International Business Machines Corp., 2000,2009 * Copyright (c) International Business Machines Corp., 2000,2009
* Modified by Steve French (sfrench@us.ibm.com) * Modified by Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/cifsacl.c
* *
* Copyright (C) International Business Machines Corp., 2007,2008 * Copyright (C) International Business Machines Corp., 2007,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifsacl.h
* *
* Copyright (c) International Business Machines Corp., 2007 * Copyright (c) International Business Machines Corp., 2007
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/cifsencrypt.c
* *
* Encryption and hashing operations relating to NTLM, NTLMv2. See MS-NLMP * Encryption and hashing operations relating to NTLM, NTLMv2. See MS-NLMP
* for more detailed information * for more detailed information

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/cifsfs.c
* *
* Copyright (C) International Business Machines Corp., 2002,2008 * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifsfs.h
* *
* Copyright (c) International Business Machines Corp., 2002, 2007 * Copyright (c) International Business Machines Corp., 2002, 2007
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifsglob.h
* *
* Copyright (C) International Business Machines Corp., 2002,2008 * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
@@ -1400,6 +1399,7 @@ struct cifsInodeInfo {
#define CIFS_INO_INVALID_MAPPING (4) /* pagecache is invalid */ #define CIFS_INO_INVALID_MAPPING (4) /* pagecache is invalid */
#define CIFS_INO_LOCK (5) /* lock bit for synchronization */ #define CIFS_INO_LOCK (5) /* lock bit for synchronization */
#define CIFS_INO_MODIFIED_ATTR (6) /* Indicate change in mtime/ctime */ #define CIFS_INO_MODIFIED_ATTR (6) /* Indicate change in mtime/ctime */
#define CIFS_INO_CLOSE_ON_LOCK (7) /* Not to defer the close when lock is set */
unsigned long flags; unsigned long flags;
spinlock_t writers_lock; spinlock_t writers_lock;
unsigned int writers; /* Number of writers on this inode */ unsigned int writers; /* Number of writers on this inode */

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifspdu.h
* *
* Copyright (c) International Business Machines Corp., 2002,2009 * Copyright (c) International Business Machines Corp., 2002,2009
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/cifsproto.h
* *
* Copyright (c) International Business Machines Corp., 2002,2008 * Copyright (c) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
@@ -268,6 +267,9 @@ extern void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon); extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
const char *path);
extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx); extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx);
extern void cifs_put_tcp_session(struct TCP_Server_Info *server, extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
int from_reconnect); int from_reconnect);

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/cifssmb.c
* *
* Copyright (C) International Business Machines Corp., 2002,2010 * Copyright (C) International Business Machines Corp., 2002,2010
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/connect.c
* *
* Copyright (C) International Business Machines Corp., 2002,2011 * Copyright (C) International Business Machines Corp., 2002,2011
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
@@ -1090,7 +1089,7 @@ next_pdu:
module_put_and_exit(0); module_put_and_exit(0);
} }
/** /*
* Returns true if srcaddr isn't specified and rhs isn't specified, or * Returns true if srcaddr isn't specified and rhs isn't specified, or
* if srcaddr is specified and matches the IP address of the rhs argument * if srcaddr is specified and matches the IP address of the rhs argument
*/ */
@@ -1550,6 +1549,9 @@ static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
/** /**
* cifs_setup_ipc - helper to setup the IPC tcon for the session * cifs_setup_ipc - helper to setup the IPC tcon for the session
* @ses: smb session to issue the request on
* @ctx: the superblock configuration context to use for building the
* new tree connection for the IPC (interprocess communication RPC)
* *
* A new IPC connection is made and stored in the session * A new IPC connection is made and stored in the session
* tcon_ipc. The IPC tcon has the same lifetime as the session. * tcon_ipc. The IPC tcon has the same lifetime as the session.
@@ -1605,6 +1607,7 @@ out:
/** /**
* cifs_free_ipc - helper to release the session IPC tcon * cifs_free_ipc - helper to release the session IPC tcon
* @ses: smb session to unmount the IPC from
* *
* Needs to be called everytime a session is destroyed. * Needs to be called everytime a session is destroyed.
* *
@@ -1855,6 +1858,8 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx __attribute__((unused)),
/** /**
* cifs_get_smb_ses - get a session matching @ctx data from @server * cifs_get_smb_ses - get a session matching @ctx data from @server
* @server: server to setup the session to
* @ctx: superblock configuration context to use to setup the session
* *
* This function assumes it is being called from cifs_mount() where we * This function assumes it is being called from cifs_mount() where we
* already got a server reference (server refcount +1). See * already got a server reference (server refcount +1). See
@@ -2065,6 +2070,8 @@ cifs_put_tcon(struct cifs_tcon *tcon)
/** /**
* cifs_get_tcon - get a tcon matching @ctx data from @ses * cifs_get_tcon - get a tcon matching @ctx data from @ses
* @ses: smb session to issue the request on
* @ctx: the superblock configuration context to use for building the
* *
* - tcon refcount is the number of mount points using the tcon. * - tcon refcount is the number of mount points using the tcon.
* - ses refcount is the number of tcon using the session. * - ses refcount is the number of tcon using the session.
@@ -3030,7 +3037,7 @@ build_unc_path_to_root(const struct smb3_fs_context *ctx,
return full_path; return full_path;
} }
/** /*
* expand_dfs_referral - Perform a dfs referral query and update the cifs_sb * expand_dfs_referral - Perform a dfs referral query and update the cifs_sb
* *
* If a referral is found, cifs_sb->ctx->mount_options will be (re-)allocated * If a referral is found, cifs_sb->ctx->mount_options will be (re-)allocated

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/dir.c
* *
* vfs operations that deal with dentries * vfs operations that deal with dentries
* *

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/dns_resolve.c
* *
* Copyright (c) 2007 Igor Mammedov * Copyright (c) 2007 Igor Mammedov
* Author(s): Igor Mammedov (niallain@gmail.com) * Author(s): Igor Mammedov (niallain@gmail.com)

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/dns_resolve.h -- DNS Resolver upcall management for CIFS DFS * DNS Resolver upcall management for CIFS DFS
* Handles host name to IP address resolution * Handles host name to IP address resolution
* *
* Copyright (c) International Business Machines Corp., 2008 * Copyright (c) International Business Machines Corp., 2008

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/export.c
* *
* Copyright (C) International Business Machines Corp., 2007 * Copyright (C) International Business Machines Corp., 2007
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/file.c
* *
* vfs operations that deal with files * vfs operations that deal with files
* *
@@ -883,6 +882,7 @@ int cifs_close(struct inode *inode, struct file *file)
dclose = kmalloc(sizeof(struct cifs_deferred_close), GFP_KERNEL); dclose = kmalloc(sizeof(struct cifs_deferred_close), GFP_KERNEL);
if ((cinode->oplock == CIFS_CACHE_RHW_FLG) && if ((cinode->oplock == CIFS_CACHE_RHW_FLG) &&
cinode->lease_granted && cinode->lease_granted &&
!test_bit(CIFS_INO_CLOSE_ON_LOCK, &cinode->flags) &&
dclose) { dclose) {
if (test_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags)) { if (test_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags)) {
inode->i_ctime = inode->i_mtime = current_time(inode); inode->i_ctime = inode->i_mtime = current_time(inode);
@@ -1865,6 +1865,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag, cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag,
tcon->ses->server); tcon->ses->server);
cifs_sb = CIFS_FILE_SB(file); cifs_sb = CIFS_FILE_SB(file);
set_bit(CIFS_INO_CLOSE_ON_LOCK, &CIFS_I(d_inode(cfile->dentry))->flags);
if (cap_unix(tcon->ses) && if (cap_unix(tcon->ses) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/fscache.c - CIFS filesystem cache interface * CIFS filesystem cache interface
* *
* Copyright (c) 2010 Novell, Inc. * Copyright (c) 2010 Novell, Inc.
* Author(s): Suresh Jayaraman <sjayaraman@suse.de> * Author(s): Suresh Jayaraman <sjayaraman@suse.de>

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/fscache.h - CIFS filesystem cache interface definitions * CIFS filesystem cache interface definitions
* *
* Copyright (c) 2010 Novell, Inc. * Copyright (c) 2010 Novell, Inc.
* Authors(s): Suresh Jayaraman (sjayaraman@suse.de> * Authors(s): Suresh Jayaraman (sjayaraman@suse.de>

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/inode.c
* *
* Copyright (C) International Business Machines Corp., 2002,2010 * Copyright (C) International Business Machines Corp., 2002,2010
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
@@ -1625,7 +1624,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
goto unlink_out; goto unlink_out;
} }
cifs_close_deferred_file(CIFS_I(inode)); cifs_close_deferred_file_under_dentry(tcon, full_path);
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) { le64_to_cpu(tcon->fsUnixInfo.Capability))) {
rc = CIFSPOSIXDelFile(xid, tcon, full_path, rc = CIFSPOSIXDelFile(xid, tcon, full_path,
@@ -2114,9 +2113,9 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
goto cifs_rename_exit; goto cifs_rename_exit;
} }
cifs_close_deferred_file(CIFS_I(d_inode(source_dentry))); cifs_close_deferred_file_under_dentry(tcon, from_name);
if (d_inode(target_dentry) != NULL) if (d_inode(target_dentry) != NULL)
cifs_close_deferred_file(CIFS_I(d_inode(target_dentry))); cifs_close_deferred_file_under_dentry(tcon, to_name);
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
to_name); to_name);

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/ioctl.c
* *
* vfs operations that deal with io control * vfs operations that deal with io control
* *
@@ -359,7 +358,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
if (pSMBFile == NULL) if (pSMBFile == NULL)
break; break;
tcon = tlink_tcon(pSMBFile->tlink); tcon = tlink_tcon(pSMBFile->tlink);
caps = le64_to_cpu(tcon->fsUnixInfo.Capability); /* caps = le64_to_cpu(tcon->fsUnixInfo.Capability); */
if (get_user(ExtAttrBits, (int __user *)arg)) { if (get_user(ExtAttrBits, (int __user *)arg)) {
rc = -EFAULT; rc = -EFAULT;

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/link.c
* *
* Copyright (C) International Business Machines Corp., 2002,2008 * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/misc.c
* *
* Copyright (C) International Business Machines Corp., 2002,2008 * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
@@ -736,7 +735,7 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
if (cancel_delayed_work(&cfile->deferred)) { if (cancel_delayed_work(&cfile->deferred)) {
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC); tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL) if (tmp_list == NULL)
continue; break;
tmp_list->cfile = cfile; tmp_list->cfile = cfile;
list_add_tail(&tmp_list->list, &file_head); list_add_tail(&tmp_list->list, &file_head);
} }
@@ -767,7 +766,7 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
if (cancel_delayed_work(&cfile->deferred)) { if (cancel_delayed_work(&cfile->deferred)) {
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC); tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL) if (tmp_list == NULL)
continue; break;
tmp_list->cfile = cfile; tmp_list->cfile = cfile;
list_add_tail(&tmp_list->list, &file_head); list_add_tail(&tmp_list->list, &file_head);
} }
@@ -781,6 +780,43 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
kfree(tmp_list); kfree(tmp_list);
} }
} }
void
cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
{
struct cifsFileInfo *cfile;
struct list_head *tmp;
struct file_list *tmp_list, *tmp_next_list;
struct list_head file_head;
void *page;
const char *full_path;
INIT_LIST_HEAD(&file_head);
page = alloc_dentry_path();
spin_lock(&tcon->open_file_lock);
list_for_each(tmp, &tcon->openFileList) {
cfile = list_entry(tmp, struct cifsFileInfo, tlist);
full_path = build_path_from_dentry(cfile->dentry, page);
if (strstr(full_path, path)) {
if (delayed_work_pending(&cfile->deferred)) {
if (cancel_delayed_work(&cfile->deferred)) {
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL)
break;
tmp_list->cfile = cfile;
list_add_tail(&tmp_list->list, &file_head);
}
}
}
}
spin_unlock(&tcon->open_file_lock);
list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) {
_cifsFileInfo_put(tmp_list->cfile, true, false);
list_del(&tmp_list->list);
kfree(tmp_list);
}
free_dentry_path(page);
}
/* parses DFS refferal V3 structure /* parses DFS refferal V3 structure
* caller is responsible for freeing target_nodes * caller is responsible for freeing target_nodes

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* fs/cifs/netmisc.c
* *
* Copyright (c) International Business Machines Corp., 2002,2008 * Copyright (c) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/ntlmssp.h
* *
* Copyright (c) International Business Machines Corp., 2002,2007 * Copyright (c) International Business Machines Corp., 2002,2007
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/readdir.c
* *
* Directory search handling * Directory search handling
* *

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/rfc1002pdu.h
* *
* Protocol Data Unit definitions for RFC 1001/1002 support * Protocol Data Unit definitions for RFC 1001/1002 support
* *

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/sess.c
* *
* SMB/CIFS session setup handling routines * SMB/CIFS session setup handling routines
* *

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/smb2file.c
* *
* Copyright (C) International Business Machines Corp., 2002, 2011 * Copyright (C) International Business Machines Corp., 2002, 2011
* Author(s): Steve French (sfrench@us.ibm.com), * Author(s): Steve French (sfrench@us.ibm.com),

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/smb2glob.h
* *
* Definitions for various global variables and structures * Definitions for various global variables and structures
* *

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/smb2inode.c
* *
* Copyright (C) International Business Machines Corp., 2002, 2011 * Copyright (C) International Business Machines Corp., 2002, 2011
* Etersoft, 2012 * Etersoft, 2012

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/smb2misc.c
* *
* Copyright (C) International Business Machines Corp., 2002,2011 * Copyright (C) International Business Machines Corp., 2002,2011
* Etersoft, 2012 * Etersoft, 2012

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/smb2pdu.c
* *
* Copyright (C) International Business Machines Corp., 2009, 2013 * Copyright (C) International Business Machines Corp., 2009, 2013
* Etersoft, 2012 * Etersoft, 2012

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/smb2pdu.h
* *
* Copyright (c) International Business Machines Corp., 2009, 2013 * Copyright (c) International Business Machines Corp., 2009, 2013
* Etersoft, 2012 * Etersoft, 2012

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/smb2proto.h
* *
* Copyright (c) International Business Machines Corp., 2002, 2011 * Copyright (c) International Business Machines Corp., 2002, 2011
* Etersoft, 2012 * Etersoft, 2012

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/smb2status.h
* *
* SMB2 Status code (network error) definitions * SMB2 Status code (network error) definitions
* Definitions are from MS-ERREF * Definitions are from MS-ERREF

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/smb2transport.c
* *
* Copyright (C) International Business Machines Corp., 2002, 2011 * Copyright (C) International Business Machines Corp., 2002, 2011
* Etersoft, 2012 * Etersoft, 2012

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1 */ /* SPDX-License-Identifier: LGPL-2.1 */
/* /*
* fs/cifs/smberr.h
* *
* Copyright (c) International Business Machines Corp., 2002,2004 * Copyright (c) International Business Machines Corp., 2002,2004
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/transport.c
* *
* Copyright (C) International Business Machines Corp., 2002,2008 * Copyright (C) International Business Machines Corp., 2002,2008
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* fs/cifs/winucase.c
* *
* Copyright (c) Jeffrey Layton <jlayton@redhat.com>, 2013 * Copyright (c) Jeffrey Layton <jlayton@redhat.com>, 2013
* *

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1 // SPDX-License-Identifier: LGPL-2.1
/* /*
* fs/cifs/xattr.c
* *
* Copyright (c) International Business Machines Corp., 2003, 2007 * Copyright (c) International Business Machines Corp., 2003, 2007
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -191,19 +191,77 @@ int get_nlink(struct kstat *st)
return nlink; return nlink;
} }
void ksmbd_conv_path_to_unix(char *path) char *ksmbd_conv_path_to_unix(char *path)
{ {
size_t path_len, remain_path_len, out_path_len;
char *out_path, *out_next;
int i, pre_dotdot_cnt = 0, slash_cnt = 0;
bool is_last;
strreplace(path, '\\', '/'); strreplace(path, '\\', '/');
path_len = strlen(path);
remain_path_len = path_len;
if (path_len == 0)
return ERR_PTR(-EINVAL);
out_path = kzalloc(path_len + 2, GFP_KERNEL);
if (!out_path)
return ERR_PTR(-ENOMEM);
out_path_len = 0;
out_next = out_path;
do {
char *name = path + path_len - remain_path_len;
char *next = strchrnul(name, '/');
size_t name_len = next - name;
is_last = !next[0];
if (name_len == 2 && name[0] == '.' && name[1] == '.') {
pre_dotdot_cnt++;
/* handle the case that path ends with "/.." */
if (is_last)
goto follow_dotdot;
} else {
if (pre_dotdot_cnt) {
follow_dotdot:
slash_cnt = 0;
for (i = out_path_len - 1; i >= 0; i--) {
if (out_path[i] == '/' &&
++slash_cnt == pre_dotdot_cnt + 1)
break;
} }
void ksmbd_strip_last_slash(char *path) if (i < 0 &&
{ slash_cnt != pre_dotdot_cnt) {
int len = strlen(path); kfree(out_path);
return ERR_PTR(-EINVAL);
while (len && path[len - 1] == '/') {
path[len - 1] = '\0';
len--;
} }
out_next = &out_path[i+1];
*out_next = '\0';
out_path_len = i + 1;
}
if (name_len != 0 &&
!(name_len == 1 && name[0] == '.') &&
!(name_len == 2 && name[0] == '.' && name[1] == '.')) {
next[0] = '\0';
sprintf(out_next, "%s/", name);
out_next += name_len + 1;
out_path_len += name_len + 1;
next[0] = '/';
}
pre_dotdot_cnt = 0;
}
remain_path_len -= name_len + 1;
} while (!is_last);
if (out_path_len > 0)
out_path[out_path_len-1] = '\0';
path[path_len] = '\0';
return out_path;
} }
void ksmbd_conv_path_to_windows(char *path) void ksmbd_conv_path_to_windows(char *path)

View File

@@ -16,8 +16,7 @@ int ksmbd_validate_filename(char *filename);
int parse_stream_name(char *filename, char **stream_name, int *s_type); int parse_stream_name(char *filename, char **stream_name, int *s_type);
char *convert_to_nt_pathname(char *filename, char *sharepath); char *convert_to_nt_pathname(char *filename, char *sharepath);
int get_nlink(struct kstat *st); int get_nlink(struct kstat *st);
void ksmbd_conv_path_to_unix(char *path); char *ksmbd_conv_path_to_unix(char *path);
void ksmbd_strip_last_slash(char *path);
void ksmbd_conv_path_to_windows(char *path); void ksmbd_conv_path_to_windows(char *path);
char *ksmbd_extract_sharename(char *treename); char *ksmbd_extract_sharename(char *treename);
char *convert_to_unix_name(struct ksmbd_share_config *share, char *name); char *convert_to_unix_name(struct ksmbd_share_config *share, char *name);

View File

@@ -634,7 +634,7 @@ static char *
smb2_get_name(struct ksmbd_share_config *share, const char *src, smb2_get_name(struct ksmbd_share_config *share, const char *src,
const int maxlen, struct nls_table *local_nls) const int maxlen, struct nls_table *local_nls)
{ {
char *name, *unixname; char *name, *norm_name, *unixname;
name = smb_strndup_from_utf16(src, maxlen, 1, local_nls); name = smb_strndup_from_utf16(src, maxlen, 1, local_nls);
if (IS_ERR(name)) { if (IS_ERR(name)) {
@@ -643,11 +643,15 @@ smb2_get_name(struct ksmbd_share_config *share, const char *src,
} }
/* change it to absolute unix name */ /* change it to absolute unix name */
ksmbd_conv_path_to_unix(name); norm_name = ksmbd_conv_path_to_unix(name);
ksmbd_strip_last_slash(name); if (IS_ERR(norm_name)) {
unixname = convert_to_unix_name(share, name);
kfree(name); kfree(name);
return norm_name;
}
kfree(name);
unixname = convert_to_unix_name(share, norm_name);
kfree(norm_name);
if (!unixname) { if (!unixname) {
pr_err("can not convert absolute name\n"); pr_err("can not convert absolute name\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
@@ -4041,6 +4045,10 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
path = &fp->filp->f_path; path = &fp->filp->f_path;
/* single EA entry is requested with given user.* name */ /* single EA entry is requested with given user.* name */
if (req->InputBufferLength) { if (req->InputBufferLength) {
if (le32_to_cpu(req->InputBufferLength) <
sizeof(struct smb2_ea_info_req))
return -EINVAL;
ea_req = (struct smb2_ea_info_req *)req->Buffer; ea_req = (struct smb2_ea_info_req *)req->Buffer;
} else { } else {
/* need to send all EAs, if no specific EA is requested*/ /* need to send all EAs, if no specific EA is requested*/

View File

@@ -20,7 +20,6 @@
#define SUBMOD_NAME "smb_direct" #define SUBMOD_NAME "smb_direct"
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/rwlock.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/mempool.h> #include <linux/mempool.h>
#include <linux/highmem.h> #include <linux/highmem.h>

View File

@@ -20,12 +20,33 @@
* depending on the status field in the last byte. The * depending on the status field in the last byte. The
* first byte is where the name start either way, and a * first byte is where the name start either way, and a
* zero means it's empty. * zero means it's empty.
*
* Also, due to a bug in gcc, we don't want to use the
* real (differently sized) name arrays in the inode and
* link entries, but always the 'de_name[]' one in the
* fake struct entry.
*
* See
*
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578#c6
*
* for details, but basically gcc will take the size of the
* 'name' array from one of the used union entries randomly.
*
* This use of 'de_name[]' (48 bytes) avoids the false positive
* warnings that would happen if gcc decides to use 'inode.di_name'
* (16 bytes) even when the pointer and size were to come from
* 'link.dl_name' (48 bytes).
*
* In all cases the actual name pointer itself is the same, it's
* only the gcc internal 'what is the size of this field' logic
* that can get confused.
*/ */
union qnx4_directory_entry { union qnx4_directory_entry {
struct { struct {
char de_name; const char de_name[48];
char de_pad[62]; u8 de_pad[15];
char de_status; u8 de_status;
}; };
struct qnx4_inode_entry inode; struct qnx4_inode_entry inode;
struct qnx4_link_info link; struct qnx4_link_info link;
@@ -53,29 +74,26 @@ static int qnx4_readdir(struct file *file, struct dir_context *ctx)
ix = (ctx->pos >> QNX4_DIR_ENTRY_SIZE_BITS) % QNX4_INODES_PER_BLOCK; ix = (ctx->pos >> QNX4_DIR_ENTRY_SIZE_BITS) % QNX4_INODES_PER_BLOCK;
for (; ix < QNX4_INODES_PER_BLOCK; ix++, ctx->pos += QNX4_DIR_ENTRY_SIZE) { for (; ix < QNX4_INODES_PER_BLOCK; ix++, ctx->pos += QNX4_DIR_ENTRY_SIZE) {
union qnx4_directory_entry *de; union qnx4_directory_entry *de;
const char *name;
offset = ix * QNX4_DIR_ENTRY_SIZE; offset = ix * QNX4_DIR_ENTRY_SIZE;
de = (union qnx4_directory_entry *) (bh->b_data + offset); de = (union qnx4_directory_entry *) (bh->b_data + offset);
if (!de->de_name) if (!de->de_name[0])
continue; continue;
if (!(de->de_status & (QNX4_FILE_USED|QNX4_FILE_LINK))) if (!(de->de_status & (QNX4_FILE_USED|QNX4_FILE_LINK)))
continue; continue;
if (!(de->de_status & QNX4_FILE_LINK)) { if (!(de->de_status & QNX4_FILE_LINK)) {
size = sizeof(de->inode.di_fname); size = sizeof(de->inode.di_fname);
name = de->inode.di_fname;
ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1; ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1;
} else { } else {
size = sizeof(de->link.dl_fname); size = sizeof(de->link.dl_fname);
name = de->link.dl_fname;
ino = ( le32_to_cpu(de->link.dl_inode_blk) - 1 ) * ino = ( le32_to_cpu(de->link.dl_inode_blk) - 1 ) *
QNX4_INODES_PER_BLOCK + QNX4_INODES_PER_BLOCK +
de->link.dl_inode_ndx; de->link.dl_inode_ndx;
} }
size = strnlen(name, size); size = strnlen(de->de_name, size);
QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, name)); QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, name));
if (!dir_emit(ctx, name, size, ino, DT_UNKNOWN)) { if (!dir_emit(ctx, de->de_name, size, ino, DT_UNKNOWN)) {
brelse(bh); brelse(bh);
return 0; return 0;
} }

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
/* /*
* fs/cifs/smbfsctl.h: SMB, CIFS, SMB2 FSCTL definitions * SMB, CIFS, SMB2 FSCTL definitions
* *
* Copyright (c) International Business Machines Corp., 2002,2013 * Copyright (c) International Business Machines Corp., 2002,2013
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)

View File

@@ -306,11 +306,13 @@ enum afs_flock_operation {
enum afs_cb_break_reason { enum afs_cb_break_reason {
afs_cb_break_no_break, afs_cb_break_no_break,
afs_cb_break_no_promise,
afs_cb_break_for_callback, afs_cb_break_for_callback,
afs_cb_break_for_deleted, afs_cb_break_for_deleted,
afs_cb_break_for_lapsed, afs_cb_break_for_lapsed,
afs_cb_break_for_s_reinit,
afs_cb_break_for_unlink, afs_cb_break_for_unlink,
afs_cb_break_for_vsbreak, afs_cb_break_for_v_break,
afs_cb_break_for_volume_callback, afs_cb_break_for_volume_callback,
afs_cb_break_for_zap, afs_cb_break_for_zap,
}; };
@@ -602,11 +604,13 @@ enum afs_cb_break_reason {
#define afs_cb_break_reasons \ #define afs_cb_break_reasons \
EM(afs_cb_break_no_break, "no-break") \ EM(afs_cb_break_no_break, "no-break") \
EM(afs_cb_break_no_promise, "no-promise") \
EM(afs_cb_break_for_callback, "break-cb") \ EM(afs_cb_break_for_callback, "break-cb") \
EM(afs_cb_break_for_deleted, "break-del") \ EM(afs_cb_break_for_deleted, "break-del") \
EM(afs_cb_break_for_lapsed, "break-lapsed") \ EM(afs_cb_break_for_lapsed, "break-lapsed") \
EM(afs_cb_break_for_s_reinit, "s-reinit") \
EM(afs_cb_break_for_unlink, "break-unlink") \ EM(afs_cb_break_for_unlink, "break-unlink") \
EM(afs_cb_break_for_vsbreak, "break-vs") \ EM(afs_cb_break_for_v_break, "break-v") \
EM(afs_cb_break_for_volume_callback, "break-v-cb") \ EM(afs_cb_break_for_volume_callback, "break-v-cb") \
E_(afs_cb_break_for_zap, "break-zap") E_(afs_cb_break_for_zap, "break-zap")

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1+ WITH Linux-syscall-note */ /* SPDX-License-Identifier: LGPL-2.1+ WITH Linux-syscall-note */
/* /*
* include/uapi/linux/cifs/cifs_mount.h
* *
* Author(s): Scott Lovenberg (scott.lovenberg@gmail.com) * Author(s): Scott Lovenberg (scott.lovenberg@gmail.com)
* *

View File

@@ -3417,6 +3417,7 @@ void unmap_mapping_pages(struct address_space *mapping, pgoff_t start,
unmap_mapping_range_tree(&mapping->i_mmap, &details); unmap_mapping_range_tree(&mapping->i_mmap, &details);
i_mmap_unlock_write(mapping); i_mmap_unlock_write(mapping);
} }
EXPORT_SYMBOL_GPL(unmap_mapping_pages);
/** /**
* unmap_mapping_range - unmap the portion of all mmaps in the specified * unmap_mapping_range - unmap the portion of all mmaps in the specified