[Devel] [PATCH rh7 v1] KVM: x86: set TMR when the interrupt is accepted
From: Paolo Bonzini <pbonz...@redhat.com> Do not compute TMR in advance. Instead, set the TMR just before the interrupt is accepted into the IRR. This limits the coupling between IOAPIC and LAPIC. Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- arch/x86/kvm/ioapic.c | 6 +- arch/x86/kvm/ioapic.h | 3 +-- arch/x86/kvm/lapic.c | 19 ++- arch/x86/kvm/lapic.h | 1 - arch/x86/kvm/x86.c| 5 + 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index d442d94..dc2ae8d 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -246,8 +246,7 @@ static void update_handled_vectors(struct kvm_ioapic *ioapic) smp_wmb(); } -void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, - u32 *tmr) +void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) { struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; union kvm_ioapic_redirect_entry *e; @@ -265,9 +264,6 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, kvm_apic_pending_eoi(vcpu, e->fields.vector))) { __set_bit(e->fields.vector, (unsigned long *)eoi_exit_bitmap); - if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG) - __set_bit(e->fields.vector, - (unsigned long *)tmr); } } } diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index a5cdfc0..652d5c5 100644 --- a/arch/x86/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h @@ -114,7 +114,6 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, struct kvm_lapic_irq *irq, unsigned long *dest_map); int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); -void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, - u32 *tmr); +void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); #endif diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 07284ef..f42d8e4 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -552,15 +552,6 @@ static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) __clear_bit(KVM_APIC_PV_EOI_PENDING, >arch.apic_attention); } -void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr) -{ - struct kvm_lapic *apic = vcpu->arch.apic; - int i; - - for (i = 0; i < 8; i++) - apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]); -} - static void apic_update_ppr(struct kvm_lapic *apic) { u32 tpr, isrv, ppr, old_ppr; @@ -765,6 +756,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, case APIC_DM_LOWEST: vcpu->arch.apic_arb_prio++; case APIC_DM_FIXED: + if (unlikely(trig_mode && !level)) + break; + /* FIXME add logic for vcpu on reset */ if (unlikely(!apic_enabled(apic))) break; @@ -774,6 +768,13 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, if (dest_map) __set_bit(vcpu->vcpu_id, dest_map); + if (apic_test_vector(vector, apic->regs + APIC_TMR) != !!trig_mode) { + if (trig_mode) + apic_set_vector(vector, apic->regs + APIC_TMR); + else + apic_clear_vector(vector, apic->regs + APIC_TMR); + } + if (kvm_x86_ops->deliver_posted_interrupt) kvm_x86_ops->deliver_posted_interrupt(vcpu, vector); else { diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index b5e88db..20013c9 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -57,7 +57,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); void kvm_apic_set_version(struct kvm_vcpu *vcpu); -void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr); void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 dest); int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5a64850..7969de2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6228,18 +6228,15 @@ static void process_smi(struct kvm_vcpu *vcpu) static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) { u64 eoi_exit_bitmap[4]; - u32 tmr[8]; if (!kvm_
[Devel] [PATCH rh7 v1] kvm fail: TMR for ioapic level interrupts
https://jira.sw.ru/browse/PSBM-41387 kvm-unit-tests results: before: /usr/libexec/qemu-kvm -enable-kvm -device pc-testdev -device isa-debug-exit, iobase=0xf4,iosize=0x4 -vnc none -serial stdio -device pci-testdev -kernel /root/kvm-unit-tests/x86/ioapic.flat enabling apic paging enabled cr0 = 80010011 cr3 = 7fff000 cr4 = 20 x2apic enabled ... FAIL: TMR for ioapic level interrupts (expected false) PASS: TMR for ioapic level interrupts (expected true) FAIL: TMR for ioapic edge interrupts (expected true) after: /usr/libexec/qemu-kvm -enable-kvm -device pc-testdev -device isa-debug-exit, iobase=0xf4,iosize=0x4 -vnc none -serial stdio -device pci-testdev -kernel /root/kvm-unit-tests/x86/ioapic.flat enabling apic paging enabled cr0 = 80010011 cr3 = 7fff000 cr4 = 20 x2apic enabled ... PASS: TMR for ioapic level interrupts (expected false) PASS: TMR for ioapic level interrupts (expected true) PASS: TMR for ioapic edge interrupts (expected true) Paolo Bonzini (1): KVM: x86: set TMR when the interrupt is accepted arch/x86/kvm/ioapic.c | 6 +- arch/x86/kvm/ioapic.h | 3 +-- arch/x86/kvm/lapic.c | 19 ++- arch/x86/kvm/lapic.h | 1 - arch/x86/kvm/x86.c| 5 + 5 files changed, 13 insertions(+), 21 deletions(-) -- 1.9.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 1/2] fs/fuse: move FUSE_SUPER_MAGIC to magic.h
Let's define it only once. Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- drivers/block/ploop/dev.c | 1 - drivers/block/ploop/io_kaio.c | 3 --- fs/fuse/inode.c | 2 -- include/uapi/linux/magic.h| 1 + 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 533ddc965af2..0e72656ec8f9 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -3880,7 +3880,6 @@ static int ploop_truncate(struct ploop_device * plo, unsigned long arg) return err; } -#define FUSE_SUPER_MAGIC 0x65735546 #define IS_PSTORAGE(sb) (sb->s_magic == FUSE_SUPER_MAGIC && \ (!strcmp(sb->s_subtype, "pstorage") || \ !strcmp(sb->s_subtype, "vstorage"))) diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c index c7312c54595e..48baa447ef91 100644 --- a/drivers/block/ploop/io_kaio.c +++ b/drivers/block/ploop/io_kaio.c @@ -17,9 +17,6 @@ #include -/* from fs/inode/fuse.c */ -#define FUSE_SUPER_MAGIC 0x65735546 - #define KAIO_PREALLOC (128 * 1024 * 1024) /* 128 MB */ #define KAIO_MAX_PAGES_PER_REQ 32/* 128 KB */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index f89bda719c71..ed5451a1eb7a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -51,8 +51,6 @@ MODULE_PARM_DESC(max_user_congthresh, "Global limit for the maximum congestion threshold an " "unprivileged user can set"); -#define FUSE_SUPER_MAGIC 0x65735546 - #define FUSE_DEFAULT_BLKSIZE 512 /** Maximum number of outstanding background requests */ diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index 599c96d6d03d..e0698ec4536b 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -32,6 +32,7 @@ #define EFIVARFS_MAGIC 0xde5e81e4 #define HOSTFS_SUPER_MAGIC 0x00c0ffee #define OVERLAYFS_SUPER_MAGIC 0x794c7630 +#define FUSE_SUPER_MAGIC 0x65735546 #define MINIX_SUPER_MAGIC 0x137F /* minix v1 fs, 14 char names */ #define MINIX_SUPER_MAGIC2 0x138F /* minix v1 fs, 30 char names */ -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 0/2] kpcs_probe: check fuse_conn args
https://jira.sw.ru/browse/HCI-52 Pavel Butsykin (2): fs/fuse: move FUSE_SUPER_MAGIC to magic.h fs/fuse kio_pcs: check fuse_conn args drivers/block/ploop/dev.c | 5 - drivers/block/ploop/io_kaio.c | 3 --- fs/fuse/inode.c| 2 -- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 23 +-- include/linux/fs.h | 5 + include/uapi/linux/magic.h | 1 + 6 files changed, 23 insertions(+), 16 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/2] fs/fuse kio_pcs: check fuse_conn args
Allow initialization of kdirect only for vstorage/pstorage. Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- drivers/block/ploop/dev.c | 4 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 23 +-- include/linux/fs.h | 5 + 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 0e72656ec8f9..c6094144c7a5 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -3880,10 +3880,6 @@ static int ploop_truncate(struct ploop_device * plo, unsigned long arg) return err; } -#define IS_PSTORAGE(sb) (sb->s_magic == FUSE_SUPER_MAGIC && \ -(!strcmp(sb->s_subtype, "pstorage") || \ - !strcmp(sb->s_subtype, "vstorage"))) - static int ploop_bd_full(struct backing_dev_info *bdi, long long nr, int root) { struct ploop_device *plo = bdi->congested_data; diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index b8503d55e246..4b9c4a304571 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -144,13 +144,24 @@ void kpcs_conn_abort(struct fuse_conn *fc) } static int kpcs_probe(struct fuse_conn *fc, char *name) - { - printk("%s TODO IMPLEMENT check fuse_conn args here!\n", __FUNCTION__); - if (!strncmp(name, kio_pcs_ops.name, FUSE_KIO_NAME)) - return 1; + if (strncmp(name, kio_pcs_ops.name, FUSE_KIO_NAME)) { + printk(KERN_ERR "FUSE: kio_pcs: invalid kio_ops name: %s\n", name); + return 0; + } - return 0; + if (!(fc->flags & FUSE_KDIRECT_IO)) { + printk(KERN_ERR "FUSE: kio_pcs: kdirect is not enabled\n"); + return 0; + } + + if (!IS_PSTORAGE(fc->sb)) { + printk(KERN_ERR "FUSE: kio_pcs: kdirect is only available for" + "pstorage/vstorage fuse mount\n"); + return 0; + } + + return 1; } @@ -1202,7 +1213,7 @@ err: static struct fuse_kio_ops kio_pcs_ops = { .name = "pcs", .owner = THIS_MODULE, - .probe = kpcs_probe, /*TODO: check sb->dev name */ + .probe = kpcs_probe, .conn_init = kpcs_conn_init, .conn_fini = kpcs_conn_fini, diff --git a/include/linux/fs.h b/include/linux/fs.h index a1dc3521f979..21770550b6c1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1713,6 +1713,11 @@ struct super_block { struct list_lru s_inode_lru cacheline_aligned_in_smp; }; +#define IS_PSTORAGE(sb) ((sb)->s_magic == FUSE_SUPER_MAGIC && \ +(sb)->s_subtype && \ +(!strcmp((sb)->s_subtype, "pstorage") || \ + !strcmp((sb)->s_subtype, "vstorage"))) + extern const unsigned super_block_wrapper_version; struct super_block_wrapper { struct super_block sb; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 2/2] fs/fuse kio_pcs: check fuse_conn args
On 17.05.2018 13:05, Kirill Tkhai wrote: Hi, Pasha, On 17.05.2018 12:40, Pavel Butsykin wrote: Allow initialization of kdirect only for vstorage/pstorage. Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- drivers/block/ploop/dev.c | 4 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 23 +-- include/linux/fs.h | 5 + 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 0e72656ec8f9..c6094144c7a5 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -3880,10 +3880,6 @@ static int ploop_truncate(struct ploop_device * plo, unsigned long arg) return err; } -#define IS_PSTORAGE(sb) (sb->s_magic == FUSE_SUPER_MAGIC && \ -(!strcmp(sb->s_subtype, "pstorage") || \ - !strcmp(sb->s_subtype, "vstorage"))) - static int ploop_bd_full(struct backing_dev_info *bdi, long long nr, int root) { struct ploop_device *plo = bdi->congested_data; diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index b8503d55e246..4b9c4a304571 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -144,13 +144,24 @@ void kpcs_conn_abort(struct fuse_conn *fc) } static int kpcs_probe(struct fuse_conn *fc, char *name) - { - printk("%s TODO IMPLEMENT check fuse_conn args here!\n", __FUNCTION__); - if (!strncmp(name, kio_pcs_ops.name, FUSE_KIO_NAME)) - return 1; + if (strncmp(name, kio_pcs_ops.name, FUSE_KIO_NAME)) { + printk(KERN_ERR "FUSE: kio_pcs: invalid kio_ops name: %s\n", name); Despite there was printk() without error level modifier (which is not correct), and printk(KERN_ERR) is better, let's follow the modern Linux kernel style, which anyway will be requested in case of submitting patches to mainstream. pr_err() is more likely to use for such the printing (see the rest of pr_* in printk.h). ok, thanks. + return 0; + } - return 0; + if (!(fc->flags & FUSE_KDIRECT_IO)) { + printk(KERN_ERR "FUSE: kio_pcs: kdirect is not enabled\n"); + return 0; + } I don't think this is needed, since we already check for this bit in fuse_fill_super() before call of fuse_kio_get(). But I'm not insist on this. And what is the meaning of this check: "!strncmp(name, kio_pcs_ops.name, FUSE_KIO_NAME)" ? We also already have this check. I assumed this can protect against possible mistakes in the future. + + if (!IS_PSTORAGE(fc->sb)) { + printk(KERN_ERR "FUSE: kio_pcs: kdirect is only available for" + "pstorage/vstorage fuse mount\n"); + return 0; + } + + return 1; } @@ -1202,7 +1213,7 @@ err: static struct fuse_kio_ops kio_pcs_ops = { .name = "pcs", .owner = THIS_MODULE, - .probe = kpcs_probe, /*TODO: check sb->dev name */ + .probe = kpcs_probe, .conn_init = kpcs_conn_init, .conn_fini = kpcs_conn_fini, diff --git a/include/linux/fs.h b/include/linux/fs.h index a1dc3521f979..21770550b6c1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1713,6 +1713,11 @@ struct super_block { struct list_lru s_inode_lru cacheline_aligned_in_smp; }; +#define IS_PSTORAGE(sb) ((sb)->s_magic == FUSE_SUPER_MAGIC && \ +(sb)->s_subtype && \ +(!strcmp((sb)->s_subtype, "pstorage") || \ + !strcmp((sb)->s_subtype, "vstorage"))) + extern const unsigned super_block_wrapper_version; struct super_block_wrapper { struct super_block sb; Thanks, Kirill ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 0/2] kpcs_probe: check fuse_conn args
https://jira.sw.ru/browse/HCI-52 Changes from v1: - drop the extra checks in kpcs_probe() - replace printk(KERN_ERR) on pr_err() Pavel Butsykin (2): fs/fuse: move FUSE_SUPER_MAGIC to magic.h fs/fuse kio_pcs: check fuse_conn args drivers/block/ploop/dev.c | 5 - drivers/block/ploop/io_kaio.c | 3 --- fs/fuse/inode.c| 2 -- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 9 - include/linux/fs.h | 5 + include/uapi/linux/magic.h | 1 + 6 files changed, 10 insertions(+), 15 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 1/2] fs/fuse: move FUSE_SUPER_MAGIC to magic.h
Let's define it only once. Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- drivers/block/ploop/dev.c | 1 - drivers/block/ploop/io_kaio.c | 3 --- fs/fuse/inode.c | 2 -- include/uapi/linux/magic.h| 1 + 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 533ddc965af2..0e72656ec8f9 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -3880,7 +3880,6 @@ static int ploop_truncate(struct ploop_device * plo, unsigned long arg) return err; } -#define FUSE_SUPER_MAGIC 0x65735546 #define IS_PSTORAGE(sb) (sb->s_magic == FUSE_SUPER_MAGIC && \ (!strcmp(sb->s_subtype, "pstorage") || \ !strcmp(sb->s_subtype, "vstorage"))) diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c index c7312c54595e..48baa447ef91 100644 --- a/drivers/block/ploop/io_kaio.c +++ b/drivers/block/ploop/io_kaio.c @@ -17,9 +17,6 @@ #include -/* from fs/inode/fuse.c */ -#define FUSE_SUPER_MAGIC 0x65735546 - #define KAIO_PREALLOC (128 * 1024 * 1024) /* 128 MB */ #define KAIO_MAX_PAGES_PER_REQ 32/* 128 KB */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index f89bda719c71..ed5451a1eb7a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -51,8 +51,6 @@ MODULE_PARM_DESC(max_user_congthresh, "Global limit for the maximum congestion threshold an " "unprivileged user can set"); -#define FUSE_SUPER_MAGIC 0x65735546 - #define FUSE_DEFAULT_BLKSIZE 512 /** Maximum number of outstanding background requests */ diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index 599c96d6d03d..e0698ec4536b 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -32,6 +32,7 @@ #define EFIVARFS_MAGIC 0xde5e81e4 #define HOSTFS_SUPER_MAGIC 0x00c0ffee #define OVERLAYFS_SUPER_MAGIC 0x794c7630 +#define FUSE_SUPER_MAGIC 0x65735546 #define MINIX_SUPER_MAGIC 0x137F /* minix v1 fs, 14 char names */ #define MINIX_SUPER_MAGIC2 0x138F /* minix v1 fs, 30 char names */ -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 2/2] fs/fuse kio_pcs: check fuse_conn args
Allow initialization of kdirect only for vstorage/pstorage. Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- drivers/block/ploop/dev.c | 4 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 9 - include/linux/fs.h | 5 + 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 0e72656ec8f9..c6094144c7a5 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -3880,10 +3880,6 @@ static int ploop_truncate(struct ploop_device * plo, unsigned long arg) return err; } -#define IS_PSTORAGE(sb) (sb->s_magic == FUSE_SUPER_MAGIC && \ -(!strcmp(sb->s_subtype, "pstorage") || \ - !strcmp(sb->s_subtype, "vstorage"))) - static int ploop_bd_full(struct backing_dev_info *bdi, long long nr, int root) { struct ploop_device *plo = bdi->congested_data; diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index b8503d55e246..3c8ab64c5fc1 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -144,16 +144,15 @@ void kpcs_conn_abort(struct fuse_conn *fc) } static int kpcs_probe(struct fuse_conn *fc, char *name) - { - printk("%s TODO IMPLEMENT check fuse_conn args here!\n", __FUNCTION__); - if (!strncmp(name, kio_pcs_ops.name, FUSE_KIO_NAME)) + if (IS_PSTORAGE(fc->sb)) return 1; + pr_err("FUSE: kio_pcs: kdirect is only available for" + "pstorage/vstorage fuse mount\n"); return 0; } - static int fuse_pcs_getfileinfo(struct fuse_conn *fc, struct file *file, struct pcs_mds_fileinfo *info) { @@ -1202,7 +1201,7 @@ err: static struct fuse_kio_ops kio_pcs_ops = { .name = "pcs", .owner = THIS_MODULE, - .probe = kpcs_probe, /*TODO: check sb->dev name */ + .probe = kpcs_probe, .conn_init = kpcs_conn_init, .conn_fini = kpcs_conn_fini, diff --git a/include/linux/fs.h b/include/linux/fs.h index a1dc3521f979..21770550b6c1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1713,6 +1713,11 @@ struct super_block { struct list_lru s_inode_lru cacheline_aligned_in_smp; }; +#define IS_PSTORAGE(sb) ((sb)->s_magic == FUSE_SUPER_MAGIC && \ +(sb)->s_subtype && \ +(!strcmp((sb)->s_subtype, "pstorage") || \ + !strcmp((sb)->s_subtype, "vstorage"))) + extern const unsigned super_block_wrapper_version; struct super_block_wrapper { struct super_block sb; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse: set FATTR_FH flag on mtime file flush
On 05.06.2018 12:53, Kirill Tkhai wrote: On 04.06.2018 16:57, Pavel Butsykin wrote: If setattr request is for a file, FATTR_FH flag should be set. In fuse_flush_mtime() that is clearly missed. This fix is present in commit 1e18bda, but it wasn't backported because the commit has a lot of unrelated changes. So this patch can be safely dropped in case of moving to a newer kernel. #VSTOR-10676 Signed-off-by: Pavel Butsykin --- fs/fuse/dir.c| 6 +- fs/fuse/file.c | 4 ++-- fs/fuse/fuse_i.h | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 0ae0344be3c5..b04023bf230a 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1690,7 +1690,7 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req, /* * Flush inode->i_mtime to the server */ -int fuse_flush_mtime(struct file *file, bool nofail) +int fuse_flush_mtime(struct file *file, struct fuse_file *ff, bool nofail) { struct inode *inode = file->f_mapping->host; struct fuse_inode *fi = get_fuse_inode(inode); @@ -1715,6 +1715,10 @@ int fuse_flush_mtime(struct file *file, bool nofail) inarg.mtime = inode->i_mtime.tv_sec; inarg.mtimensec = inode->i_mtime.tv_nsec; + if (ff) { + inarg.valid |= FATTR_FH; + inarg.fh = ff->fh; + } fuse_setattr_fill(fc, req, inode, , ); fuse_request_send(fc, req); err = req->out.h.error; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 53e81bdca6ed..ddfb41af54ec 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -458,7 +458,7 @@ static int fuse_release(struct inode *inode, struct file *file) if (test_bit(FUSE_I_MTIME_UPDATED, _fuse_inode(inode)->state)) - fuse_flush_mtime(file, true); + fuse_flush_mtime(file, ff, true); fuse_release_common(file, FUSE_RELEASE); @@ -724,7 +724,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, if (!datasync && test_bit(FUSE_I_MTIME_UPDATED, _fuse_inode(inode)->state)) { - err = fuse_flush_mtime(file, false); + err = fuse_flush_mtime(file, isdir ? NULL : ff, false); Everything looks OK for me, and the only thing I want to ask you is the reason we ignore ff in case of directory. Why we should do this? Because FATTR_FH flag indicates that request belongs to a file. Correspondingly, this flag should be set for a directory. if (err) goto out; } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index f704fd17905b..939835f585b1 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1074,7 +1074,7 @@ int fuse_dev_release(struct inode *inode, struct file *file); bool fuse_write_update_size(struct inode *inode, loff_t pos); -int fuse_flush_mtime(struct file *file, bool nofail); +int fuse_flush_mtime(struct file *file, struct fuse_file *ff, bool nofail); int fuse_do_setattr(struct inode *inode, struct iattr *attr, struct file *file); ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 3/4] fs/fuse: export fuse_release_ff() and fuse_write_file()
This allows to use these functions in pcs_fuse_kdirect module and needed for next patch. Signed-off-by: Pavel Butsykin --- fs/fuse/file.c | 5 +++-- fs/fuse/fuse_i.h | 4 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index f9a0da25a9df..a8badb889975 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1142,6 +1142,7 @@ void fuse_release_ff(struct inode *inode, struct fuse_file *ff) } } } +EXPORT_SYMBOL_GPL(fuse_release_ff); static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req) { @@ -2002,8 +2003,7 @@ static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_req *req) fuse_writepage_free(fc, req); } -static struct fuse_file *fuse_write_file(struct fuse_conn *fc, -struct fuse_inode *fi) +struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi) { struct fuse_file *ff = NULL; @@ -2016,6 +2016,7 @@ static struct fuse_file *fuse_write_file(struct fuse_conn *fc, return ff; } +EXPORT_SYMBOL_GPL(fuse_write_file); static int tree_insert(struct rb_root *root, struct fuse_req *ins_req) { diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 939835f585b1..20295250070a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1091,4 +1091,8 @@ void fuse_stat_account(struct fuse_conn * fc, int op, ktime_t val); int fuse_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, __u64 start, __u64 len); +struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi); + +void fuse_release_ff(struct inode *inode, struct fuse_file *ff); + #endif /* _FS_FUSE_I_H */ -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 0/4] fuse_kdirect: fsync hungs after unlink fixes
#VSTOR-10635 Changes from v1: - separate patch for moving pcs_ireq_queue_fail() (1) - add zeroing of di->size.required (2) - move export fuse_release_ff/()fuse_write_file() in a separate patch (3) Pavel Butsykin (4): fs/fuse kio_pcs: move pcs_ireq_queue_fail fs/fuse kio_pcs: handle error of submit_size_grow() fs/fuse: export node_ff func fs/fuse kio_pcs: pass the file handle for FUSE_SETATTR request fs/fuse/file.c | 5 +++-- fs/fuse/fuse_i.h | 4 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 23 ++- fs/fuse/kio/pcs/pcs_map.c | 34 -- fs/fuse/kio/pcs/pcs_req.c | 31 +++ fs/fuse/kio/pcs/pcs_req.h | 2 ++ 6 files changed, 62 insertions(+), 37 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 2/4] fs/fuse kio_pcs: handle error of submit_size_grow()
Before continuing write requests, we need to check the procedure size grow was successful. If the size attribute of a file failed to increase, it makes no sense to continue to push write requests because they will not be able to succeed until the file size will match. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index a4064904f963..cd6497080070 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -648,6 +648,7 @@ static void fuse_size_grow_work(struct work_struct *w) struct inode *inode = >inode->inode; struct pcs_int_request* ireq, *next; unsigned long long size = 0; + int err; LIST_HEAD(to_submit); spin_lock(>lock); @@ -667,7 +668,19 @@ static void fuse_size_grow_work(struct work_struct *w) } di->size.required = size; spin_unlock(>lock); - submit_size_grow(inode, size); + + err = submit_size_grow(inode, size); + if (err) { + LIST_HEAD(to_fail); + + spin_lock(>lock); + di->size.required = 0; + list_splice_tail_init(>size.grow_queue, _fail); + spin_unlock(>lock); + + pcs_ireq_queue_fail(_fail, err); + return; + } spin_lock(>lock); BUG_ON(di->size.shrink); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 4/4] fs/fuse kio_pcs: pass the file handle for FUSE_SETATTR request
Add to pass the file handle (if it is) for FUSE_SETATTR request inside submit_size_grow(). Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 8 1 file changed, 8 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index cd6497080070..af82b043f786 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -602,6 +602,7 @@ void ireq_destroy(struct pcs_int_request *ireq) static int submit_size_grow(struct inode *inode, unsigned long long size) { struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff; struct fuse_setattr_in inarg; struct fuse_attr_out outarg; struct fuse_req *req; @@ -624,6 +625,11 @@ static int submit_size_grow(struct inode *inode, unsigned long long size) inarg.valid |= FATTR_SIZE; inarg.size = size; + ff = fuse_write_file(fc, get_fuse_inode(inode)); + if (ff) { + inarg.valid |= FATTR_FH; + inarg.fh = ff->fh; + } req->io_inode = inode; req->in.h.opcode = FUSE_SETATTR; req->in.h.nodeid = get_node_id(inode); @@ -635,7 +641,9 @@ static int submit_size_grow(struct inode *inode, unsigned long long size) req->out.args[0].value = fuse_request_send(fc, req); + err = req->out.h.error; + fuse_release_ff(inode, ff); fuse_put_request(fc, req); return err; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 1/4] fs/fuse kio_pcs: move pcs_ireq_queue_fail()
The pcs internal request queue may be waiting not only for mapping ioctl's, but also for FUSE_SETATTR ioctl within fuse_size_grow_work(). Thus, pcs_ireq_queue_fail() looks like a common interface to complete with an error all pending ireq's. This patch moves pcs_ireq_queue_fail() from pcs_map.c to pcs_req.c and make it exported. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_map.c | 34 -- fs/fuse/kio/pcs/pcs_req.c | 31 +++ fs/fuse/kio/pcs/pcs_req.h | 2 ++ 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 9a05e247fe47..f20db1d5b3f9 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -36,8 +36,6 @@ static struct pcs_cs_list *cs_link_to_cs_list(struct pcs_cs_link *csl) return cs_list; } -static void pcs_ireq_queue_fail(struct list_head *queue, int error); - abs_time_t get_real_time_ms(void) { struct timespec tv = current_kernel_time(); @@ -151,7 +149,6 @@ static void pcs_map_reset(struct pcs_map_entry * m) { m->state &= ~(PCS_MAP_READABLE|PCS_MAP_WRITEABLE); } -static void pcs_ireq_queue_fail(struct list_head *queue, int error); static void map_sync_work_add(struct pcs_map_entry *m, unsigned long timeout); static void map_sync_work_del(struct pcs_map_entry *m); @@ -758,37 +755,6 @@ unlock: BUG_ON(cs->is_dead); } -noinline static void pcs_ireq_queue_fail(struct list_head *queue, int error) -{ - while (!list_empty(queue)) { - struct pcs_int_request *ireq = list_first_entry(queue, struct pcs_int_request, list); - - list_del_init(>list); - - pcs_set_local_error(>error, error); - - if (ireq->type == PCS_IREQ_TRUNCATE) { - ireq_on_error(ireq); - - if (!(ireq->flags & IREQ_F_FATAL)) { - if (ireq_is_timed_out(ireq)) { - pcs_log(LOG_ERR, "timeout while truncate(%d) request on \"" DENTRY_FMT "\" last err=%u", - ireq->type, DENTRY_ARGS(ireq->dentry), ireq->error.value); - BUG(); - } - pcs_clear_error(>error); - - TRACE("requeue truncate(%d) %llu@" DENTRY_FMT "\n", ireq->type, - (unsigned long long)ireq->truncreq.offset, DENTRY_ARGS(ireq->dentry)); - - ireq_delay(ireq); - continue; - } - } - ireq_complete(ireq); - } -} - void transfer_sync_data(struct pcs_cs_list * new_cs_list, struct pcs_cs_list * old_cs_list) { int i, k; diff --git a/fs/fuse/kio/pcs/pcs_req.c b/fs/fuse/kio/pcs/pcs_req.c index a05f1e43c94c..9516768c47d4 100644 --- a/fs/fuse/kio/pcs/pcs_req.c +++ b/fs/fuse/kio/pcs/pcs_req.c @@ -121,3 +121,34 @@ void ireq_handle_hole(struct pcs_int_request *ireq) ireq_complete(ireq); } + +noinline void pcs_ireq_queue_fail(struct list_head *queue, int error) +{ + while (!list_empty(queue)) { + struct pcs_int_request *ireq = list_first_entry(queue, struct pcs_int_request, list); + + list_del_init(>list); + + pcs_set_local_error(>error, error); + + if (ireq->type == PCS_IREQ_TRUNCATE) { + ireq_on_error(ireq); + + if (!(ireq->flags & IREQ_F_FATAL)) { + if (ireq_is_timed_out(ireq)) { + pcs_log(LOG_ERR, "timeout while truncate(%d) request on \"" DENTRY_FMT "\" last err=%u", + ireq->type, DENTRY_ARGS(ireq->dentry), ireq->error.value); + BUG(); + } + pcs_clear_error(>error); + + TRACE("requeue truncate(%d) %llu@" DENTRY_FMT "\n", ireq->type, + (unsigned long long)ireq->truncreq.offset, DENTRY_ARGS(ireq->dentry)); + + ireq_delay(ireq); + continue; + } + } + ireq_complete(ireq); + } +} diff --git a/fs/fuse/kio/pcs/pcs_req.h b/fs/fuse/kio/pcs/pcs_req.h index 6f49018e3988..557e8e476856 100644 --- a/fs/fuse/kio/pcs/pcs_req.h +++ b/fs/fuse/kio/pcs/pcs_req.h @@ -332,4 +332,6 @@ void ireq_handle_hole(struct pcs_int_request *ireq); void pcs_process_ireq(struct pcs_int_request *ireq); +void pcs_ireq_queue_fail(struct li
[Devel] [PATCH 1/2] fs/fuse kio_pcs: handle error of submit_size_grow()
Before continuing write requests, we need to check the procedure size grow was successful. If the size attribute of a file failed to increase, it makes no sense to continue to push write requests because they will not be able to succeed until the file size will match. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 14 +- fs/fuse/kio/pcs/pcs_map.c | 34 -- fs/fuse/kio/pcs/pcs_req.c | 31 +++ fs/fuse/kio/pcs/pcs_req.h | 2 ++ 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index cf97a5ce0e50..1a6776f7977a 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -654,6 +654,7 @@ static void fuse_size_grow_work(struct work_struct *w) struct inode *inode = >inode->inode; struct pcs_int_request* ireq, *next; unsigned long long size = 0; + int err; LIST_HEAD(to_submit); spin_lock(>lock); @@ -673,7 +674,18 @@ static void fuse_size_grow_work(struct work_struct *w) } di->size.required = size; spin_unlock(>lock); - submit_size_grow(inode, size); + + err = submit_size_grow(inode, size); + if (err) { + LIST_HEAD(to_fail); + + spin_lock(>lock); + list_splice_tail_init(>size.grow_queue, _fail); + spin_unlock(>lock); + + pcs_ireq_queue_fail(_fail, err); + return; + } spin_lock(>lock); BUG_ON(di->size.shrink); diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 90e311f7e995..78e773536bb4 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -26,8 +26,6 @@ */ #define MAP_BATCH 16 -static void pcs_ireq_queue_fail(struct list_head *queue, int error); - abs_time_t get_real_time_ms(void) { struct timespec tv = current_kernel_time(); @@ -138,7 +136,6 @@ static void pcs_map_reset(struct pcs_map_entry * m) { m->state &= ~(PCS_MAP_READABLE|PCS_MAP_WRITEABLE); } -static void pcs_ireq_queue_fail(struct list_head *queue, int error); static void map_sync_work_add(struct pcs_map_entry *m, unsigned long timeout); static void map_sync_work_del(struct pcs_map_entry *m); @@ -724,37 +721,6 @@ void pcs_map_notify_addr_change(struct pcs_cs * cs) } } -noinline static void pcs_ireq_queue_fail(struct list_head *queue, int error) -{ - while (!list_empty(queue)) { - struct pcs_int_request *ireq = list_first_entry(queue, struct pcs_int_request, list); - - list_del_init(>list); - - pcs_set_local_error(>error, error); - - if (ireq->type == PCS_IREQ_TRUNCATE) { - ireq_on_error(ireq); - - if (!(ireq->flags & IREQ_F_FATAL)) { - if (ireq_is_timed_out(ireq)) { - pcs_log(LOG_ERR, "timeout while truncate(%d) request on \"" DENTRY_FMT "\" last err=%u", - ireq->type, DENTRY_ARGS(ireq->dentry), ireq->error.value); - BUG(); - } - pcs_clear_error(>error); - - TRACE("requeue truncate(%d) %llu@" DENTRY_FMT "\n", ireq->type, - (unsigned long long)ireq->truncreq.offset, DENTRY_ARGS(ireq->dentry)); - - ireq_delay(ireq); - continue; - } - } - ireq_complete(ireq); - } -} - void transfer_sync_data(struct pcs_cs_list * new_cs_list, struct pcs_cs_list * old_cs_list) { int i, k; diff --git a/fs/fuse/kio/pcs/pcs_req.c b/fs/fuse/kio/pcs/pcs_req.c index a05f1e43c94c..9516768c47d4 100644 --- a/fs/fuse/kio/pcs/pcs_req.c +++ b/fs/fuse/kio/pcs/pcs_req.c @@ -121,3 +121,34 @@ void ireq_handle_hole(struct pcs_int_request *ireq) ireq_complete(ireq); } + +noinline void pcs_ireq_queue_fail(struct list_head *queue, int error) +{ + while (!list_empty(queue)) { + struct pcs_int_request *ireq = list_first_entry(queue, struct pcs_int_request, list); + + list_del_init(>list); + + pcs_set_local_error(>error, error); + + if (ireq->type == PCS_IREQ_TRUNCATE) { + ireq_on_error(ireq); + + if (!(ireq->flags & IREQ_F_FATAL)) { + if (ireq_is_timed_out(ireq)) { + pcs_log(LOG_ERR, "timeout while truncate(%d) requ
[Devel] [PATCH 0/2] fuse_kdirect: fsync hungs after unlink fixes
#VSTOR-10635 Pavel Butsykin (2): fs/fuse kio_pcs: handle error of submit_size_grow() fs/fuse kio_pcs: pass the file handle for FUSE_SETATTR request fs/fuse/file.c | 5 +++-- fs/fuse/fuse_i.h | 4 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 22 +- fs/fuse/kio/pcs/pcs_map.c | 34 -- fs/fuse/kio/pcs/pcs_req.c | 31 +++ fs/fuse/kio/pcs/pcs_req.h | 2 ++ 6 files changed, 61 insertions(+), 37 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/2] fs/fuse kio_pcs: pass the file handle for FUSE_SETATTR request
Add to pass the file handle (if it is) for FUSE_SETATTR request inside submit_size_grow(). Signed-off-by: Pavel Butsykin --- fs/fuse/file.c | 5 +++-- fs/fuse/fuse_i.h | 4 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 8 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index ddfb41af54ec..9ae260a10490 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1137,6 +1137,7 @@ void fuse_release_ff(struct inode *inode, struct fuse_file *ff) } } } +EXPORT_SYMBOL_GPL(fuse_release_ff); static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req) { @@ -1997,8 +1998,7 @@ static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_req *req) fuse_writepage_free(fc, req); } -static struct fuse_file *fuse_write_file(struct fuse_conn *fc, -struct fuse_inode *fi) +struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi) { struct fuse_file *ff = NULL; @@ -2011,6 +2011,7 @@ static struct fuse_file *fuse_write_file(struct fuse_conn *fc, return ff; } +EXPORT_SYMBOL_GPL(fuse_write_file); static int tree_insert(struct rb_root *root, struct fuse_req *ins_req) { diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 939835f585b1..20295250070a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1091,4 +1091,8 @@ void fuse_stat_account(struct fuse_conn * fc, int op, ktime_t val); int fuse_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, __u64 start, __u64 len); +struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi); + +void fuse_release_ff(struct inode *inode, struct fuse_file *ff); + #endif /* _FS_FUSE_I_H */ diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 1a6776f7977a..4f8b0133ca5b 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -608,6 +608,7 @@ void ireq_destroy(struct pcs_int_request *ireq) static int submit_size_grow(struct inode *inode, unsigned long long size) { struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff; struct fuse_setattr_in inarg; struct fuse_attr_out outarg; struct fuse_req *req; @@ -630,6 +631,11 @@ static int submit_size_grow(struct inode *inode, unsigned long long size) inarg.valid |= FATTR_SIZE; inarg.size = size; + ff = fuse_write_file(fc, get_fuse_inode(inode)); + if (ff) { + inarg.valid |= FATTR_FH; + inarg.fh = ff->fh; + } req->io_inode = inode; req->in.h.opcode = FUSE_SETATTR; req->in.h.nodeid = get_node_id(inode); @@ -641,7 +647,9 @@ static int submit_size_grow(struct inode *inode, unsigned long long size) req->out.args[0].value = fuse_request_send(fc, req); + err = req->out.h.error; + fuse_release_ff(inode, ff); fuse_put_request(fc, req); return err; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH V2] fs/fuse: disable optimization fuse and kio_pcs in debug kernel
Signed-off-by: Pavel Butsykin --- configs/kernel-3.10.0-x86_64-debug.config | 2 ++ fs/fuse/Kconfig | 6 ++ fs/fuse/Makefile | 22 ++ 3 files changed, 30 insertions(+) diff --git a/configs/kernel-3.10.0-x86_64-debug.config b/configs/kernel-3.10.0-x86_64-debug.config index b31047705216..6c9c28203443 100644 --- a/configs/kernel-3.10.0-x86_64-debug.config +++ b/configs/kernel-3.10.0-x86_64-debug.config @@ -6100,6 +6100,8 @@ CONFIG_FUSE_KIO_NOOP=m CONFIG_FUSE_KIO_NULLIO=m CONFIG_FUSE_KIO_PCS=m +CONFIG_FUSE_KIO_DEBUG=y + # # User resources # diff --git a/fs/fuse/Kconfig b/fs/fuse/Kconfig index 433a39957c9d..7b61c6fe2d8d 100644 --- a/fs/fuse/Kconfig +++ b/fs/fuse/Kconfig @@ -45,3 +45,9 @@ config FUSE_KIO_PCS depends on FUSE_FS help This FUSE extension allows to forward io requests directly to PCS + +config FUSE_KIO_DEBUG + bool "Disable optimization for fuse kdirect PCS" + depends on DEBUG_KERNEL && FUSE_FS + help + Say Y if you want to disable optimization for fuse and fuse_kio_pcs modules. diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index cdefac9c4fbe..6d02013ed27a 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -2,6 +2,28 @@ # Makefile for the FUSE filesystem. # +ifdef CONFIG_FUSE_KIO_DEBUG +CFLAGS_fuse.o := -O0 +CFLAGS_cuse.o := -O0 +CFLAGS_dev.o := -O0 +CFLAGS_dir.o := -O0 +CFLAGS_file.o := -O0 +CFLAGS_inode.o := -O0 +CFLAGS_control.o := -O0 + +CFLAGS_kio_noop.o := -O0 +CFLAGS_kio_nullio.o := -O0 +CFLAGS_pcs_fuse_kdirect.o := -O0 +CFLAGS_pcs_sock_io.o := -O0 +CFLAGS_pcs_rpc.o := -O0 +CFLAGS_pcs_req.o := -O0 +CFLAGS_pcs_map.o := -O0 +CFLAGS_pcs_cluster.o := -O0 +CFLAGS_pcs_cluster_core.o := -O0 +CFLAGS_pcs_cs.o := -O0 +CFLAGS_fuse_io.o := -O0 +endif + obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH V2] fs/fuse: disable optimization fuse and kio_pcs in debug kernel
On 08.06.2018 14:58, Kirill Tkhai wrote: Please, always write description why we need this. This is very useful during kernel rebase. OK, I suggest the following commit message: Disabling code optimization for fuse/fuse_kio_pcs will be useful at the time of stabilization of these modules. After the stabilization of fuse/fuse_kio_pcs, this patch can be reverted. On 08.06.2018 13:01, Pavel Butsykin wrote: Signed-off-by: Pavel Butsykin Reviewed-by: Kirill Tkhai --- configs/kernel-3.10.0-x86_64-debug.config | 2 ++ fs/fuse/Kconfig | 6 ++ fs/fuse/Makefile | 22 ++ 3 files changed, 30 insertions(+) diff --git a/configs/kernel-3.10.0-x86_64-debug.config b/configs/kernel-3.10.0-x86_64-debug.config index b31047705216..6c9c28203443 100644 --- a/configs/kernel-3.10.0-x86_64-debug.config +++ b/configs/kernel-3.10.0-x86_64-debug.config @@ -6100,6 +6100,8 @@ CONFIG_FUSE_KIO_NOOP=m CONFIG_FUSE_KIO_NULLIO=m CONFIG_FUSE_KIO_PCS=m +CONFIG_FUSE_KIO_DEBUG=y + # # User resources # diff --git a/fs/fuse/Kconfig b/fs/fuse/Kconfig index 433a39957c9d..7b61c6fe2d8d 100644 --- a/fs/fuse/Kconfig +++ b/fs/fuse/Kconfig @@ -45,3 +45,9 @@ config FUSE_KIO_PCS depends on FUSE_FS help This FUSE extension allows to forward io requests directly to PCS + +config FUSE_KIO_DEBUG + bool "Disable optimization for fuse kdirect PCS" + depends on DEBUG_KERNEL && FUSE_FS + help + Say Y if you want to disable optimization for fuse and fuse_kio_pcs modules. diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index cdefac9c4fbe..6d02013ed27a 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -2,6 +2,28 @@ # Makefile for the FUSE filesystem. # +ifdef CONFIG_FUSE_KIO_DEBUG +CFLAGS_fuse.o := -O0 +CFLAGS_cuse.o := -O0 +CFLAGS_dev.o := -O0 +CFLAGS_dir.o := -O0 +CFLAGS_file.o := -O0 +CFLAGS_inode.o := -O0 +CFLAGS_control.o := -O0 + +CFLAGS_kio_noop.o := -O0 +CFLAGS_kio_nullio.o := -O0 +CFLAGS_pcs_fuse_kdirect.o := -O0 +CFLAGS_pcs_sock_io.o := -O0 +CFLAGS_pcs_rpc.o := -O0 +CFLAGS_pcs_req.o := -O0 +CFLAGS_pcs_map.o := -O0 +CFLAGS_pcs_cluster.o := -O0 +CFLAGS_pcs_cluster_core.o := -O0 +CFLAGS_pcs_cs.o := -O0 +CFLAGS_fuse_io.o := -O0 +endif + obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse: disable optimization fuse and kio_pcs in debug kernel
Signed-off-by: Pavel Butsykin --- configs/kernel-3.10.0-x86_64-debug.config | 2 ++ fs/fuse/Kconfig | 6 ++ fs/fuse/Makefile | 22 ++ 3 files changed, 30 insertions(+) diff --git a/configs/kernel-3.10.0-x86_64-debug.config b/configs/kernel-3.10.0-x86_64-debug.config index b31047705216..6c9c28203443 100644 --- a/configs/kernel-3.10.0-x86_64-debug.config +++ b/configs/kernel-3.10.0-x86_64-debug.config @@ -6100,6 +6100,8 @@ CONFIG_FUSE_KIO_NOOP=m CONFIG_FUSE_KIO_NULLIO=m CONFIG_FUSE_KIO_PCS=m +CONFIG_FUSE_KIO_DEBUG=y + # # User resources # diff --git a/fs/fuse/Kconfig b/fs/fuse/Kconfig index 433a39957c9d..7b61c6fe2d8d 100644 --- a/fs/fuse/Kconfig +++ b/fs/fuse/Kconfig @@ -45,3 +45,9 @@ config FUSE_KIO_PCS depends on FUSE_FS help This FUSE extension allows to forward io requests directly to PCS + +config FUSE_KIO_DEBUG + bool "Disable optimization for fuse kdirect PCS" + depends on DEBUG_KERNEL && FUSE_FS + help + Say Y if you want to disable optimization for fuse and fuse_kio_pcs modules. diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index cdefac9c4fbe..6d02013ed27a 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -2,6 +2,28 @@ # Makefile for the FUSE filesystem. # +ifdef CONFIG_FUSE_KIO_DEBUG +CFLAGS_fuse.o := -DDEBUG -O0 +CFLAGS_cuse.o := -DDEBUG -O0 +CFLAGS_dev.o := -DDEBUG -O0 +CFLAGS_dir.o := -DDEBUG -O0 +CFLAGS_file.o := -DDEBUG -O0 +CFLAGS_inode.o := -DDEBUG -O0 +CFLAGS_control.o := -DDEBUG -O0 + +CFLAGS_kio_noop.o := -DDEBUG -O0 +CFLAGS_kio_nullio.o := -DDEBUG -O0 +CFLAGS_pcs_fuse_kdirect.o := -DDEBUG -O0 +CFLAGS_pcs_sock_io.o := -DDEBUG -O0 +CFLAGS_pcs_rpc.o := -DDEBUG -O0 +CFLAGS_pcs_req.o := -DDEBUG -O0 +CFLAGS_pcs_map.o := -DDEBUG -O0 +CFLAGS_pcs_cluster.o := -DDEBUG -O0 +CFLAGS_pcs_cluster_core.o := -DDEBUG -O0 +CFLAGS_pcs_cs.o := -DDEBUG -O0 +CFLAGS_fuse_io.o := -DDEBUG -O0 +endif + obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse: disable optimization fuse and kio_pcs in debug kernel
On 08.06.2018 12:41, Kirill Tkhai wrote: On 08.06.2018 12:34, Pavel Butsykin wrote: Signed-off-by: Pavel Butsykin --- configs/kernel-3.10.0-x86_64-debug.config | 2 ++ fs/fuse/Kconfig | 6 ++ fs/fuse/Makefile | 22 ++ 3 files changed, 30 insertions(+) diff --git a/configs/kernel-3.10.0-x86_64-debug.config b/configs/kernel-3.10.0-x86_64-debug.config index b31047705216..6c9c28203443 100644 --- a/configs/kernel-3.10.0-x86_64-debug.config +++ b/configs/kernel-3.10.0-x86_64-debug.config @@ -6100,6 +6100,8 @@ CONFIG_FUSE_KIO_NOOP=m CONFIG_FUSE_KIO_NULLIO=m CONFIG_FUSE_KIO_PCS=m +CONFIG_FUSE_KIO_DEBUG=y + # # User resources # diff --git a/fs/fuse/Kconfig b/fs/fuse/Kconfig index 433a39957c9d..7b61c6fe2d8d 100644 --- a/fs/fuse/Kconfig +++ b/fs/fuse/Kconfig @@ -45,3 +45,9 @@ config FUSE_KIO_PCS depends on FUSE_FS help This FUSE extension allows to forward io requests directly to PCS + +config FUSE_KIO_DEBUG + bool "Disable optimization for fuse kdirect PCS" + depends on DEBUG_KERNEL && FUSE_FS + help + Say Y if you want to disable optimization for fuse and fuse_kio_pcs modules. diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index cdefac9c4fbe..6d02013ed27a 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -2,6 +2,28 @@ # Makefile for the FUSE filesystem. # +ifdef CONFIG_FUSE_KIO_DEBUG +CFLAGS_fuse.o := -DDEBUG -O0 What for this #define DEBUG is needed? Is it for printk() or something else? Yes, DEBUG here seems superfluous. +CFLAGS_cuse.o := -DDEBUG -O0 +CFLAGS_dev.o := -DDEBUG -O0 +CFLAGS_dir.o := -DDEBUG -O0 +CFLAGS_file.o := -DDEBUG -O0 +CFLAGS_inode.o := -DDEBUG -O0 +CFLAGS_control.o := -DDEBUG -O0 + +CFLAGS_kio_noop.o := -DDEBUG -O0 +CFLAGS_kio_nullio.o := -DDEBUG -O0 +CFLAGS_pcs_fuse_kdirect.o := -DDEBUG -O0 +CFLAGS_pcs_sock_io.o := -DDEBUG -O0 +CFLAGS_pcs_rpc.o := -DDEBUG -O0 +CFLAGS_pcs_req.o := -DDEBUG -O0 +CFLAGS_pcs_map.o := -DDEBUG -O0 +CFLAGS_pcs_cluster.o := -DDEBUG -O0 +CFLAGS_pcs_cluster_core.o := -DDEBUG -O0 +CFLAGS_pcs_cs.o := -DDEBUG -O0 +CFLAGS_fuse_io.o := -DDEBUG -O0 +endif + obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 1/2] fs/fuse kio_pcs: handle error of submit_size_grow()
On 07.06.2018 17:40, Pavel Butsykin wrote: Before continuing write requests, we need to check the procedure size grow was successful. If the size attribute of a file failed to increase, it makes no sense to continue to push write requests because they will not be able to succeed until the file size will match. Alexey, I wonder whether we should abort pending requests for all errors or just for fatal? for which errors we can retry FUSE_SETATTR request? Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 14 +- fs/fuse/kio/pcs/pcs_map.c | 34 -- fs/fuse/kio/pcs/pcs_req.c | 31 +++ fs/fuse/kio/pcs/pcs_req.h | 2 ++ 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index cf97a5ce0e50..1a6776f7977a 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -654,6 +654,7 @@ static void fuse_size_grow_work(struct work_struct *w) struct inode *inode = >inode->inode; struct pcs_int_request* ireq, *next; unsigned long long size = 0; + int err; LIST_HEAD(to_submit); spin_lock(>lock); @@ -673,7 +674,18 @@ static void fuse_size_grow_work(struct work_struct *w) } di->size.required = size; spin_unlock(>lock); - submit_size_grow(inode, size); + + err = submit_size_grow(inode, size); + if (err) { + LIST_HEAD(to_fail); + + spin_lock(>lock); + list_splice_tail_init(>size.grow_queue, _fail); + spin_unlock(>lock); + + pcs_ireq_queue_fail(_fail, err); + return; + } spin_lock(>lock); BUG_ON(di->size.shrink); diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 90e311f7e995..78e773536bb4 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -26,8 +26,6 @@ */ #define MAP_BATCH 16 -static void pcs_ireq_queue_fail(struct list_head *queue, int error); - abs_time_t get_real_time_ms(void) { struct timespec tv = current_kernel_time(); @@ -138,7 +136,6 @@ static void pcs_map_reset(struct pcs_map_entry * m) { m->state &= ~(PCS_MAP_READABLE|PCS_MAP_WRITEABLE); } -static void pcs_ireq_queue_fail(struct list_head *queue, int error); static void map_sync_work_add(struct pcs_map_entry *m, unsigned long timeout); static void map_sync_work_del(struct pcs_map_entry *m); @@ -724,37 +721,6 @@ void pcs_map_notify_addr_change(struct pcs_cs * cs) } } -noinline static void pcs_ireq_queue_fail(struct list_head *queue, int error) -{ - while (!list_empty(queue)) { - struct pcs_int_request *ireq = list_first_entry(queue, struct pcs_int_request, list); - - list_del_init(>list); - - pcs_set_local_error(>error, error); - - if (ireq->type == PCS_IREQ_TRUNCATE) { - ireq_on_error(ireq); - - if (!(ireq->flags & IREQ_F_FATAL)) { - if (ireq_is_timed_out(ireq)) { - pcs_log(LOG_ERR, "timeout while truncate(%d) request on \"" DENTRY_FMT "\" last err=%u", - ireq->type, DENTRY_ARGS(ireq->dentry), ireq->error.value); - BUG(); - } - pcs_clear_error(>error); - - TRACE("requeue truncate(%d) %llu@" DENTRY_FMT "\n", ireq->type, - (unsigned long long)ireq->truncreq.offset, DENTRY_ARGS(ireq->dentry)); - - ireq_delay(ireq); - continue; - } - } - ireq_complete(ireq); - } -} - void transfer_sync_data(struct pcs_cs_list * new_cs_list, struct pcs_cs_list * old_cs_list) { int i, k; diff --git a/fs/fuse/kio/pcs/pcs_req.c b/fs/fuse/kio/pcs/pcs_req.c index a05f1e43c94c..9516768c47d4 100644 --- a/fs/fuse/kio/pcs/pcs_req.c +++ b/fs/fuse/kio/pcs/pcs_req.c @@ -121,3 +121,34 @@ void ireq_handle_hole(struct pcs_int_request *ireq) ireq_complete(ireq); } + +noinline void pcs_ireq_queue_fail(struct list_head *queue, int error) +{ + while (!list_empty(queue)) { + struct pcs_int_request *ireq = list_first_entry(queue, struct pcs_int_request, list); + + list_del_init(>list); + + pcs_set_local_error(>error, error); + + if (ireq->type == PCS_IREQ_TRUNCATE) { + ireq_on_error(ireq); + + if (!(ireq->flags & IREQ_
[Devel] [PATCH] fs/fuse: fix debug build "CFLAGS was changed"
build error: Makefile.build:49: *** CFLAGS was changed in "./fs/fuse/Makefile". Fix it to use ccflags-y. Stop. See (Documentation/kbuild/makefiles.txt, section 3.7) for details. --- fs/fuse/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index 54dfe9f64feb..3eb06648da2c 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -3,7 +3,7 @@ # ifdef CONFIG_FUSE_KIO_DEBUG - CFLAGS := -O0 + ccflags-y := -O0 endif obj-$(CONFIG_FUSE_FS) += fuse.o -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio_pcs: some cleanup ireq_on_error_()
Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_cluster.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_cluster.c b/fs/fuse/kio/pcs/pcs_cluster.c index 24ec8a5f39a3..5441a357b87d 100644 --- a/fs/fuse/kio/pcs/pcs_cluster.c +++ b/fs/fuse/kio/pcs/pcs_cluster.c @@ -486,11 +486,8 @@ static void ireq_on_error_(struct pcs_int_request *ireq) case PCS_ERR_LEASE_EXPIRED: case PCS_ERR_INTEGRITY_FAIL: { /* TODO: tag ireq->dentry with EIO here */ - goto fatal; } case PCS_ERR_CSD_LACKING: - goto fatal; - break; case PCS_ERR_INV_PARAMS: case PCS_ERR_NOT_FOUND: case PCS_ERR_NON_EMPTY_DIR: @@ -498,9 +495,9 @@ static void ireq_on_error_(struct pcs_int_request *ireq) case PCS_ERR_IS_DIR: case PCS_ERR_NO_STORAGE: case PCS_ERR_UNAVAIL: -fatal: - printk(KERN_INFO "%s fatal error:%d nodeid:%llu", __func__, - ireq->error.value, ireq->dentry->inode->nodeid); + pr_info("%s fatal error:%d ireq->type:%d nodeid:%llu", + __func__, ireq->error.value, ireq->type, + ireq->dentry->inode->nodeid); ireq->flags |= IREQ_F_FATAL; break; case PCS_ERR_LEASE_CONFLICT: @@ -508,7 +505,6 @@ fatal: break; default: break; - ; } } -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio_pcs: remove s_subtype check
The s_subtype field is initialized after calling vfs_kern_mount(), so we can't check s_subtype inside vfs_kern_mount(). Instead of s_subtype we can check dev_name, but this leads to an unjustified modification of common fuse. Given that s_subtype/dev_name check doesn't protect from the possibility to mount fuse whith kpcs on any device except vstorage/pstorage, we can remove this check. Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 61378f0d9a58..930ddff1b680 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -142,12 +142,7 @@ void kpcs_conn_abort(struct fuse_conn *fc) static int kpcs_probe(struct fuse_conn *fc, char *name) { - if (IS_PSTORAGE(fc->sb)) - return 1; - - pr_err("FUSE: kio_pcs: kdirect is only available for" - "pstorage/vstorage fuse mount\n"); - return 0; + return 1; } static int fuse_pcs_getfileinfo(struct fuse_conn *fc, struct file *file, -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse: set FATTR_FH flag on mtime file flush
If setattr request is for a file, FATTR_FH flag should be set. In fuse_flush_mtime() that is clearly missed. This fix is present in commit 1e18bda, but it wasn't backported because the commit has a lot of unrelated changes. So this patch can be safely dropped in case of moving to a newer kernel. #VSTOR-10676 Signed-off-by: Pavel Butsykin --- fs/fuse/dir.c| 6 +- fs/fuse/file.c | 4 ++-- fs/fuse/fuse_i.h | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 0ae0344be3c5..b04023bf230a 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1690,7 +1690,7 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req, /* * Flush inode->i_mtime to the server */ -int fuse_flush_mtime(struct file *file, bool nofail) +int fuse_flush_mtime(struct file *file, struct fuse_file *ff, bool nofail) { struct inode *inode = file->f_mapping->host; struct fuse_inode *fi = get_fuse_inode(inode); @@ -1715,6 +1715,10 @@ int fuse_flush_mtime(struct file *file, bool nofail) inarg.mtime = inode->i_mtime.tv_sec; inarg.mtimensec = inode->i_mtime.tv_nsec; + if (ff) { + inarg.valid |= FATTR_FH; + inarg.fh = ff->fh; + } fuse_setattr_fill(fc, req, inode, , ); fuse_request_send(fc, req); err = req->out.h.error; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 53e81bdca6ed..ddfb41af54ec 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -458,7 +458,7 @@ static int fuse_release(struct inode *inode, struct file *file) if (test_bit(FUSE_I_MTIME_UPDATED, _fuse_inode(inode)->state)) - fuse_flush_mtime(file, true); + fuse_flush_mtime(file, ff, true); fuse_release_common(file, FUSE_RELEASE); @@ -724,7 +724,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, if (!datasync && test_bit(FUSE_I_MTIME_UPDATED, _fuse_inode(inode)->state)) { - err = fuse_flush_mtime(file, false); + err = fuse_flush_mtime(file, isdir ? NULL : ff, false); if (err) goto out; } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index f704fd17905b..939835f585b1 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1074,7 +1074,7 @@ int fuse_dev_release(struct inode *inode, struct file *file); bool fuse_write_update_size(struct inode *inode, loff_t pos); -int fuse_flush_mtime(struct file *file, bool nofail); +int fuse_flush_mtime(struct file *file, struct fuse_file *ff, bool nofail); int fuse_do_setattr(struct inode *inode, struct iattr *attr, struct file *file); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 1/2] fuse kio: Do not try to populate fuse_inode::private on second open
On 11.10.2018 18:00, Kirill Tkhai wrote: > Introduce flag to mark files served by userspace. > It helps kio to understand it's not needed to send > a request to userspace, when private is NULL. > Introducing some special value to encode inodes, > served in userspace, (for example ~0UL), does not > look better, since it makes !fi->private checks > more difficult (also we have a lot free bits > in inode flags). > > Synchronization is "caller owns inode->i_mutex". > > Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin > --- > fs/fuse/fuse_i.h |3 +++ > fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 11 +-- > 2 files changed, 12 insertions(+), 2 deletions(-) > > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h > index 69dfd0c318fe..d7dd571c08f6 100644 > --- a/fs/fuse/fuse_i.h > +++ b/fs/fuse/fuse_i.h > @@ -147,6 +147,9 @@ enum { > FUSE_I_SIZE_UNSTABLE, > /** i_mtime has been updated locally; a flush to userspace needed */ > FUSE_I_MTIME_UPDATED, > + > + /** kdirect open try has already made */ > + FUSE_I_KIO_OPEN_TRY_MADE, > }; > > struct fuse_conn; > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index 14bed318d139..f221001519c3 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -359,7 +359,7 @@ int kpcs_file_open(struct fuse_conn *fc, struct file > *file, struct inode *inode) > struct fuse_inode *fi = get_fuse_inode(inode); > struct pcs_dentry_info *di = fi->private; > struct pcs_mds_fileinfo info; > - int ret; > + int ret = 0; > > if (!S_ISREG(inode->i_mode)) > return 0; > @@ -378,7 +378,14 @@ int kpcs_file_open(struct fuse_conn *fc, struct file > *file, struct inode *inode) > spin_unlock(>lock); > return 0; > } > - return kpcs_do_file_open(fc, file, inode); > + > + if (!test_bit(FUSE_I_KIO_OPEN_TRY_MADE, >state)) { > + ret = kpcs_do_file_open(fc, file, inode); > + if (!ret) > + set_bit(FUSE_I_KIO_OPEN_TRY_MADE, >state); > + } > + > + return ret; > } > > void kpcs_inode_release(struct fuse_inode *fi) > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 2/2] fuse kio: Differ fuse_pcs_kdirect_claim_op() return values
On 11.10.2018 18:00, Kirill Tkhai wrote: > Fail open in case of fuse_get_req() was failed, > and leave it successful in case of vstorage-mount > said we can't claim file by kio (e.g., file will > be served by userspace). > > Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c |4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index f221001519c3..d56cbc542542 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -293,7 +293,7 @@ static int fuse_pcs_kdirect_claim_op(struct fuse_conn > *fc, struct file *file, > if (req->out.h.error || outarg->result) { > TRACE("h.err:%d result:%d\n", > req->out.h.error, outarg->result); > - err = req->out.h.error ? req->out.h.error : outarg->result; > + err = -EOPNOTSUPP; > } > > fuse_put_request(fc, req); > @@ -347,7 +347,7 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct > file *file, struct ino > pcs_mapping_deinit(>mapping); > kfree(di); > /* Claim error means we cannot claim, just that */ > - return 0; > + return (ret == -EOPNOTSUPP ? 0: ret); > } > /* TODO: Propper initialization of dentry should be here!!! */ > fi->private = di; > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Fix deadlock at pcs_fuse_submit() error path
On 17.10.2018 16:57, Kirill Tkhai wrote: > request_end() takes fc->lock, so we in case of error we bump > into deadlock: > > Call Trace: >[] _raw_spin_lock+0x75/0xc0 >[] spin_lock+0x18/0x1b [fuse] >[] request_end+0x265/0x72b [fuse] >[] pcs_fuse_submit+0x9fb/0xaa3 [fuse_kio_pcs] >[] kpcs_req_send+0x793/0xa60 [fuse_kio_pcs] >[] flush_bg_queue+0x14f/0x283 [fuse] >[] fuse_request_send_background_locked+0x50b/0x512 [fuse] >[] fuse_request_send_background+0x369/0x43f [fuse] >[] fuse_send_readpages+0x372/0x3b5 [fuse] >[] fuse_readpages+0x28c/0x2f0 [fuse] >[] __do_page_cache_readahead+0x518/0x6d0 > > Fix this by unlocking fc->lock before request_end() call. Note, > that it may look strange to have two same lk parameters in > pcs_fuse_submit(pfc, req, lk, lk), but the current design > interprets requests submitted with locked lk as async and > we keep this logic. > > Generally, I feel we need to improve design in a thing > of queueing requests and locking, but we need more > inverstigation and thinking here, so let's delay this > to next VZ update. > > https://pmc.acronis.com/browse/VSTOR-16246 > > Signed-off-by: Kirill Tkhai > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 10 +++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index b286a956a751..61415e029c45 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -883,7 +883,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r) > return ret; > } > > -static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req > *req, int async) > +static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req > *req, bool async, bool lk) > { > struct pcs_fuse_req *r = pcs_req_from_fuse(req); > struct fuse_inode *fi = get_fuse_inode(req->io_inode); > @@ -963,7 +963,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster > *pfc, struct fuse_req *req, > error: > DTRACE("do fuse_request_end req:%p op:%d err:%d\n", >req, > r->req.in.h.opcode, r->req.out.h.error); > > + if (lk) > + spin_unlock(>fc->lock); We can't unlock fc->lock inside fuse_request_send_background_locked(), because it breaks compatibility with fuse_set_nowrite(). We must ensure that no one pending requests should not be between fuse_set_nowrite() and fuse_release_nowrite(). But since fc unlock inside fuse_request_send_background_locked() this promise can be broken. > request_end(pfc->fc, >req); > + if (lk) > + spin_lock(>fc->lock); > return; > > submit: > @@ -1027,7 +1031,7 @@ static void _pcs_shrink_end(struct fuse_conn *fc, > struct fuse_req *req) > > TRACE("resubmit %p\n", >req); > list_del_init(>list); > - pcs_fuse_submit(pfc, >req, 1); > + pcs_fuse_submit(pfc, >req, true, false); > } > } > > @@ -1174,7 +1178,7 @@ static int kpcs_req_send(struct fuse_conn* fc, struct > fuse_req *req, bool bg, bo > } > __clear_bit(FR_PENDING, >flags); > > - pcs_fuse_submit(pfc, req, lk); > + pcs_fuse_submit(pfc, req, lk, lk); > if (!bg) > wait_event(req->waitq, > test_bit(FR_FINISHED, >flags) && !req->end); > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Fix deadlock at pcs_fuse_submit() error path
On 17.10.2018 18:43, Kirill Tkhai wrote: > On 17.10.2018 18:06, Pavel Butsykin wrote: >> >> >> On 17.10.2018 16:57, Kirill Tkhai wrote: >>> request_end() takes fc->lock, so we in case of error we bump >>> into deadlock: >>> >>> Call Trace: >>> [] _raw_spin_lock+0x75/0xc0 >>> [] spin_lock+0x18/0x1b [fuse] >>> [] request_end+0x265/0x72b [fuse] >>> [] pcs_fuse_submit+0x9fb/0xaa3 [fuse_kio_pcs] >>> [] kpcs_req_send+0x793/0xa60 [fuse_kio_pcs] >>> [] flush_bg_queue+0x14f/0x283 [fuse] >>> [] fuse_request_send_background_locked+0x50b/0x512 >>> [fuse] >>> [] fuse_request_send_background+0x369/0x43f [fuse] >>> [] fuse_send_readpages+0x372/0x3b5 [fuse] >>> [] fuse_readpages+0x28c/0x2f0 [fuse] >>> [] __do_page_cache_readahead+0x518/0x6d0 >>> >>> Fix this by unlocking fc->lock before request_end() call. Note, >>> that it may look strange to have two same lk parameters in >>> pcs_fuse_submit(pfc, req, lk, lk), but the current design >>> interprets requests submitted with locked lk as async and >>> we keep this logic. >>> >>> Generally, I feel we need to improve design in a thing >>> of queueing requests and locking, but we need more >>> inverstigation and thinking here, so let's delay this >>> to next VZ update. >>> >>> https://pmc.acronis.com/browse/VSTOR-16246 >>> >>> Signed-off-by: Kirill Tkhai >>> --- >>>fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 10 +++--- >>>1 file changed, 7 insertions(+), 3 deletions(-) >>> >>> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> index b286a956a751..61415e029c45 100644 >>> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> @@ -883,7 +883,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r) >>> return ret; >>>} >>> >>> -static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req >>> *req, int async) >>> +static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req >>> *req, bool async, bool lk) >>>{ >>> struct pcs_fuse_req *r = pcs_req_from_fuse(req); >>> struct fuse_inode *fi = get_fuse_inode(req->io_inode); >>> @@ -963,7 +963,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster >>> *pfc, struct fuse_req *req, >>>error: >>> DTRACE("do fuse_request_end req:%p op:%d err:%d\n", >req, >>> r->req.in.h.opcode, r->req.out.h.error); >>> >>> + if (lk) >>> + spin_unlock(>fc->lock); >> >> We can't unlock fc->lock inside fuse_request_send_background_locked(), >> because it breaks compatibility with fuse_set_nowrite(). We must >> ensure that no one pending requests should not be between >> fuse_set_nowrite() and fuse_release_nowrite(). But since fc unlock >> inside fuse_request_send_background_locked() this promise can be broken. > > No, this is not true, and this does not introduce new races. > fuse_set_nowrite() does not really wait for all pending requests, Not all pending requests, but at least all write pending requests. > since parallel kpcs_req_send() is possible after fuse_set_nowrite() > released the lock. There is no protection. This is what about I say Look at fuse_do_setattr(), with unlock inside fuse_request_send_background_locked() it's just breaks down the protection against parallel execution setattr size with writes reqs. > we need to redesign this thing. Also, keep in mind, that failing > a request with request_end() is legitimate outside the lock, and > this is just ordinary behavior we already have. The problem is not this, the problem is that while one thread will set 'nowrite' another thread will be executed in flush_bg_queue() and can pass fuse_set_nowrite()(thanks to fc unlock inside req_send()) and a couple of write requests from fc->bg_queue. > The change I did is similar to unlocking fc->lock after iteration > on some req, and it's definitely safe in current terms. If you > can see new races introduced, just try to draw functions calls > to verify that. cpu0: int fuse_do_setattr(struct inode *inode, struct iattr *attr, struct file *file) { ... void fuse_set_nowrite(struct inode *inode) { struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_inode *fi = get_fuse_inode(inode); BUG_ON(!mutex_is_loc
Re: [Devel] [PATCH] fuse kio: Fix deadlock at pcs_fuse_submit() error path
On 18.10.2018 11:55, Pavel Butsykin wrote: > On 18.10.2018 11:35, Kirill Tkhai wrote: >> On 17.10.2018 19:22, Pavel Butsykin wrote: >>> On 17.10.2018 18:43, Kirill Tkhai wrote: >>>> On 17.10.2018 18:06, Pavel Butsykin wrote: >>>>> >>>>> >>>>> On 17.10.2018 16:57, Kirill Tkhai wrote: >>>>>> request_end() takes fc->lock, so we in case of error we bump >>>>>> into deadlock: >>>>>> >>>>>> Call Trace: >>>>>> [] _raw_spin_lock+0x75/0xc0 >>>>>> [] spin_lock+0x18/0x1b [fuse] >>>>>> [] request_end+0x265/0x72b [fuse] >>>>>> [] pcs_fuse_submit+0x9fb/0xaa3 [fuse_kio_pcs] >>>>>> [] kpcs_req_send+0x793/0xa60 [fuse_kio_pcs] >>>>>> [] flush_bg_queue+0x14f/0x283 [fuse] >>>>>> [] >>>>>> fuse_request_send_background_locked+0x50b/0x512 [fuse] >>>>>> [] fuse_request_send_background+0x369/0x43f >>>>>> [fuse] >>>>>> [] fuse_send_readpages+0x372/0x3b5 [fuse] >>>>>> [] fuse_readpages+0x28c/0x2f0 [fuse] >>>>>> [] __do_page_cache_readahead+0x518/0x6d0 >>>>>> >>>>>> Fix this by unlocking fc->lock before request_end() call. Note, >>>>>> that it may look strange to have two same lk parameters in >>>>>> pcs_fuse_submit(pfc, req, lk, lk), but the current design >>>>>> interprets requests submitted with locked lk as async and >>>>>> we keep this logic. >>>>>> >>>>>> Generally, I feel we need to improve design in a thing >>>>>> of queueing requests and locking, but we need more >>>>>> inverstigation and thinking here, so let's delay this >>>>>> to next VZ update. >>>>>> >>>>>> https://pmc.acronis.com/browse/VSTOR-16246 >>>>>> >>>>>> Signed-off-by: Kirill Tkhai >>>>>> --- >>>>>> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 10 +++--- >>>>>> 1 file changed, 7 insertions(+), 3 deletions(-) >>>>>> >>>>>> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>>> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>>> index b286a956a751..61415e029c45 100644 >>>>>> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>>> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>>> @@ -883,7 +883,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r) >>>>>> return ret; >>>>>> } >>>>>> >>>>>> -static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct >>>>>> fuse_req *req, int async) >>>>>> +static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct >>>>>> fuse_req *req, bool async, bool lk) >>>>>> { >>>>>> struct pcs_fuse_req *r = pcs_req_from_fuse(req); >>>>>> struct fuse_inode *fi = get_fuse_inode(req->io_inode); >>>>>> @@ -963,7 +963,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster >>>>>> *pfc, struct fuse_req *req, >>>>>> error: >>>>>> DTRACE("do fuse_request_end req:%p op:%d err:%d\n", >req, >>>>>> r->req.in.h.opcode, r->req.out.h.error); >>>>>> >>>>>> +if (lk) >>>>>> +spin_unlock(>fc->lock); >>>>> >>>>> We can't unlock fc->lock inside fuse_request_send_background_locked(), >>>>> because it breaks compatibility with fuse_set_nowrite(). We must >>>>> ensure that no one pending requests should not be between >>>>> fuse_set_nowrite() and fuse_release_nowrite(). But since fc unlock >>>>> inside fuse_request_send_background_locked() this promise can be broken. >>>> >>>> No, this is not true, and this does not introduce new races. >>>> fuse_set_nowrite() does not really wait for all pending requests, >>> >>> Not all pending requests, but at least all write pending requests. >>> >>>> since parallel kpcs_req_send() is possible after fuse_set_nowrite() >>>> released the lock. There is no protection. This is what about I say >>> >>> Loo
Re: [Devel] [PATCH] fuse kio: Fix deadlock at pcs_fuse_submit() error path
On 18.10.2018 11:35, Kirill Tkhai wrote: > On 17.10.2018 19:22, Pavel Butsykin wrote: >> On 17.10.2018 18:43, Kirill Tkhai wrote: >>> On 17.10.2018 18:06, Pavel Butsykin wrote: >>>> >>>> >>>> On 17.10.2018 16:57, Kirill Tkhai wrote: >>>>> request_end() takes fc->lock, so we in case of error we bump >>>>> into deadlock: >>>>> >>>>> Call Trace: >>>>> [] _raw_spin_lock+0x75/0xc0 >>>>> [] spin_lock+0x18/0x1b [fuse] >>>>> [] request_end+0x265/0x72b [fuse] >>>>> [] pcs_fuse_submit+0x9fb/0xaa3 [fuse_kio_pcs] >>>>> [] kpcs_req_send+0x793/0xa60 [fuse_kio_pcs] >>>>> [] flush_bg_queue+0x14f/0x283 [fuse] >>>>> [] fuse_request_send_background_locked+0x50b/0x512 >>>>> [fuse] >>>>> [] fuse_request_send_background+0x369/0x43f [fuse] >>>>> [] fuse_send_readpages+0x372/0x3b5 [fuse] >>>>> [] fuse_readpages+0x28c/0x2f0 [fuse] >>>>> [] __do_page_cache_readahead+0x518/0x6d0 >>>>> >>>>> Fix this by unlocking fc->lock before request_end() call. Note, >>>>> that it may look strange to have two same lk parameters in >>>>> pcs_fuse_submit(pfc, req, lk, lk), but the current design >>>>> interprets requests submitted with locked lk as async and >>>>> we keep this logic. >>>>> >>>>> Generally, I feel we need to improve design in a thing >>>>> of queueing requests and locking, but we need more >>>>> inverstigation and thinking here, so let's delay this >>>>> to next VZ update. >>>>> >>>>> https://pmc.acronis.com/browse/VSTOR-16246 >>>>> >>>>> Signed-off-by: Kirill Tkhai >>>>> --- >>>>> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 10 +++--- >>>>> 1 file changed, 7 insertions(+), 3 deletions(-) >>>>> >>>>> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> index b286a956a751..61415e029c45 100644 >>>>> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> @@ -883,7 +883,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r) >>>>> return ret; >>>>> } >>>>> >>>>> -static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct >>>>> fuse_req *req, int async) >>>>> +static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct >>>>> fuse_req *req, bool async, bool lk) >>>>> { >>>>> struct pcs_fuse_req *r = pcs_req_from_fuse(req); >>>>> struct fuse_inode *fi = get_fuse_inode(req->io_inode); >>>>> @@ -963,7 +963,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster >>>>> *pfc, struct fuse_req *req, >>>>> error: >>>>> DTRACE("do fuse_request_end req:%p op:%d err:%d\n", >req, >>>>> r->req.in.h.opcode, r->req.out.h.error); >>>>> >>>>> + if (lk) >>>>> + spin_unlock(>fc->lock); >>>> >>>> We can't unlock fc->lock inside fuse_request_send_background_locked(), >>>> because it breaks compatibility with fuse_set_nowrite(). We must >>>> ensure that no one pending requests should not be between >>>> fuse_set_nowrite() and fuse_release_nowrite(). But since fc unlock >>>> inside fuse_request_send_background_locked() this promise can be broken. >>> >>> No, this is not true, and this does not introduce new races. >>> fuse_set_nowrite() does not really wait for all pending requests, >> >> Not all pending requests, but at least all write pending requests. >> >>> since parallel kpcs_req_send() is possible after fuse_set_nowrite() >>> released the lock. There is no protection. This is what about I say >> >> Look at fuse_do_setattr(), with unlock inside >> fuse_request_send_background_locked() it's just breaks down the >> protection against parallel execution setattr size with writes reqs. >> >>> we need to redesign this thing. Also, keep in mind, that failing >>> a request with request_end() is legitimate outside the lock, and >>> this is just ordinary behavior we already have. &
Re: [Devel] [PATCH] fuse kio: Fix deadlock at pcs_fuse_submit() error path
On 17.10.2018 16:57, Kirill Tkhai wrote: > request_end() takes fc->lock, so we in case of error we bump > into deadlock: > > Call Trace: >[] _raw_spin_lock+0x75/0xc0 >[] spin_lock+0x18/0x1b [fuse] >[] request_end+0x265/0x72b [fuse] >[] pcs_fuse_submit+0x9fb/0xaa3 [fuse_kio_pcs] >[] kpcs_req_send+0x793/0xa60 [fuse_kio_pcs] >[] flush_bg_queue+0x14f/0x283 [fuse] >[] fuse_request_send_background_locked+0x50b/0x512 [fuse] >[] fuse_request_send_background+0x369/0x43f [fuse] >[] fuse_send_readpages+0x372/0x3b5 [fuse] >[] fuse_readpages+0x28c/0x2f0 [fuse] >[] __do_page_cache_readahead+0x518/0x6d0 > > Fix this by unlocking fc->lock before request_end() call. Note, > that it may look strange to have two same lk parameters in > pcs_fuse_submit(pfc, req, lk, lk), but the current design > interprets requests submitted with locked lk as async and > we keep this logic. > > Generally, I feel we need to improve design in a thing > of queueing requests and locking, but we need more > inverstigation and thinking here, so let's delay this > to next VZ update. > > https://pmc.acronis.com/browse/VSTOR-16246 > > Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 10 +++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index b286a956a751..61415e029c45 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -883,7 +883,7 @@ static int pcs_fuse_prep_rw(struct pcs_fuse_req *r) > return ret; > } > > -static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req > *req, int async) > +static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req > *req, bool async, bool lk) > { > struct pcs_fuse_req *r = pcs_req_from_fuse(req); > struct fuse_inode *fi = get_fuse_inode(req->io_inode); > @@ -963,7 +963,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster > *pfc, struct fuse_req *req, > error: > DTRACE("do fuse_request_end req:%p op:%d err:%d\n", >req, > r->req.in.h.opcode, r->req.out.h.error); > > + if (lk) > + spin_unlock(>fc->lock); > request_end(pfc->fc, >req); > + if (lk) > + spin_lock(>fc->lock); > return; > > submit: > @@ -1027,7 +1031,7 @@ static void _pcs_shrink_end(struct fuse_conn *fc, > struct fuse_req *req) > > TRACE("resubmit %p\n", >req); > list_del_init(>list); > - pcs_fuse_submit(pfc, >req, 1); > + pcs_fuse_submit(pfc, >req, true, false); > } > } > > @@ -1174,7 +1178,7 @@ static int kpcs_req_send(struct fuse_conn* fc, struct > fuse_req *req, bool bg, bo > } > __clear_bit(FR_PENDING, >flags); > > - pcs_fuse_submit(pfc, req, lk); > + pcs_fuse_submit(pfc, req, lk, lk); > if (!bg) > wait_event(req->waitq, > test_bit(FR_FINISHED, >flags) && !req->end); > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH RHEL7 COMMIT] fuse kio: Use __maybe_unused
On 16.10.2018 18:04, Konstantin Khorenko wrote: > The commit is pushed to "branch-rh7-3.10.0-862.14.4.vz7.72.x-ovz" and will > appear at https://src.openvz.org/scm/ovz/vzkernel.git > after rh7-3.10.0-862.14.4.vz7.72.9 > --> > commit b7f9b4aaa9c9828f40c79d496cfe4dc3e9c04db4 > Author: Kirill Tkhai > Date: Tue Oct 16 18:04:29 2018 +0300 > > fuse kio: Use __maybe_unused > > Signed-off-by: Kirill Tkhai > Reviewed-by: Pavel Butsykin > > = > Patchset description: > > Order pcs_rpc and pcs_sockio destruction and close leaked socket > > https://pmc.acronis.com/browse/VSTOR-15305 > > Ploop can asynchronously unmap regions by sending IOCB_CMD_UNMAP_ITER, > but this > command isn't quite correctly interpreted in Fuse. Moreover, in > Fast-path mode, > fallocate(FALLOC_FL_PUNCH_HOLE|FALLOC_FL_ZERO_RANGE) falls to fuse user > daemon > and it can lead to data corruption. > > Let's fix it. Konstantin, you messed up the Patchset description :) > > Kirill Tkhai (9): >fuse kio: Use __maybe_unused >fuse kio: Use sio eof instead of parent to determ abort >fuse kio: Reorder callback assignment >fuse kio: Add pcs_cleanup_wq >fuse kio: Destroy rpc in work func >fuse kio: Introduce pcs_sk_kick_queue() >fuse kio: Dereference sk_user_data under rcu >fuse kio: Fix rpc socket leak on rpc_abort() >fuse kio: Hold pcs_rpc counter till sio may be freed > --- > fs/fuse/kio/pcs/pcs_sock_io.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c > index 0cf392fb4703..18b66f99e018 100644 > --- a/fs/fuse/kio/pcs/pcs_sock_io.c > +++ b/fs/fuse/kio/pcs/pcs_sock_io.c > @@ -212,7 +212,6 @@ static void pcs_sockio_recv(struct pcs_sockio *sio) > u32 msg_size; > unsigned long loop_timeout = jiffies + PCS_SIO_SLICE; > > - (void)ep; > TRACE("ENTER:" PEER_FMT " sio:%p cur_msg:%p\n", PEER_ARGS(ep), sio, > sio->current_msg); > > while(!test_bit(PCS_IOCONN_BF_DEAD, >flags)) { > @@ -316,14 +315,13 @@ static void pcs_sockio_recv(struct pcs_sockio *sio) > > static void pcs_sockio_send(struct pcs_sockio *sio) > { > + struct pcs_rpc *ep __maybe_unused = sio->parent; > struct pcs_ioconn* conn = >ioconn; > struct iov_iter *it = >write_iter; > unsigned long loop_timeout = jiffies + PCS_SIO_SLICE; > struct pcs_msg * msg; > int done = 0; > int count = 0; > - struct pcs_rpc *ep = sio->parent; > - (void)ep; > > while (!list_empty(>write_queue)) { > msg = list_first_entry(>write_queue, struct pcs_msg, list); > > ___ > Devel mailing list > Devel@openvz.org > https://lists.openvz.org/mailman/listinfo/devel > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Add comment about why we need to wait pending read requests
On 23.10.2018 13:01, Kirill Tkhai wrote: > Signed-off-by: Kirill Tkhai > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c |7 ++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index 3940d6c255ba..9b45fcbf8941 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -1081,7 +1081,12 @@ static void pcs_kio_setattr_handle(struct fuse_inode > *fi, struct fuse_req *req) > r->end = req->end; > if (di->size.op == PCS_SIZE_SHRINK) { > BUG_ON(!mutex_is_locked(>io_inode->i_mutex)); > - /* wait for aio reads in flight */ > + /* > + * Wait for already submitted aio reads. Further reads > + * (including already queued to bg_queue) will be stopped > + * by wait_shrink(), and they will be processed from > + * _pcs_shrink_end(). > + */ Why do we have to wait already submitted aio reads ? > inode_dio_wait(req->io_inode); > /* >* Writebackcache was flushed already so it is safe to > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Unexport pcs_ioconn_close() and pcs_ioconn_unregister()
On 23.10.2018 11:35, Kirill Tkhai wrote: > They are used only in the file they are declared. > > Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin > --- > fs/fuse/kio/pcs/pcs_sock_io.c |4 ++-- > fs/fuse/kio/pcs/pcs_sock_io.h |5 - > 2 files changed, 2 insertions(+), 7 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c > index 04b63b58dad6..ede71c255084 100644 > --- a/fs/fuse/kio/pcs/pcs_sock_io.c > +++ b/fs/fuse/kio/pcs/pcs_sock_io.c > @@ -42,13 +42,13 @@ void sio_push(struct pcs_sockio * sio) > caseB: kernelspace want to close socket and have to somehow > notify about this to userspace (NEW API REQUIRED) > static void pcs_restore_sockets(struct pcs_ioconn *ioconn); > -void pcs_ioconn_unregister(struct pcs_ioconn *ioconn) > +static void pcs_ioconn_unregister(struct pcs_ioconn *ioconn) > { > if (!test_bit(PCS_IOCONN_BF_DEAD, >flags)) > set_bit(PCS_IOCONN_BF_DEAD, >flags); > } > > -void pcs_ioconn_close(struct pcs_ioconn *ioconn) > +static void pcs_ioconn_close(struct pcs_ioconn *ioconn) > { > kernel_sock_shutdown(ioconn->socket, SHUT_RDWR); > } > diff --git a/fs/fuse/kio/pcs/pcs_sock_io.h b/fs/fuse/kio/pcs/pcs_sock_io.h > index 30771170b84c..7795212045c2 100644 > --- a/fs/fuse/kio/pcs/pcs_sock_io.h > +++ b/fs/fuse/kio/pcs/pcs_sock_io.h > @@ -231,9 +231,4 @@ struct bufqueue; > */ > struct pcs_msg* bufqueue_as_pcs_output_msg(struct bufqueue *bq, u32 size); > > - > -void pcs_ioconn_unregister(struct pcs_ioconn *ioconn); > -void pcs_ioconn_close(struct pcs_ioconn *ioconn); > - > - > #endif /* _PCS_SOCK_IO_H_ */ > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Add comment about why we need to wait pending read requests
On 23.10.2018 13:19, Kirill Tkhai wrote: > On 23.10.2018 13:15, Pavel Butsykin wrote: >> >> >> On 23.10.2018 13:01, Kirill Tkhai wrote: >>> Signed-off-by: Kirill Tkhai >>> --- >>>fs/fuse/kio/pcs/pcs_fuse_kdirect.c |7 ++- >>>1 file changed, 6 insertions(+), 1 deletion(-) >>> >>> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> index 3940d6c255ba..9b45fcbf8941 100644 >>> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> @@ -1081,7 +1081,12 @@ static void pcs_kio_setattr_handle(struct fuse_inode >>> *fi, struct fuse_req *req) >>> r->end = req->end; >>> if (di->size.op == PCS_SIZE_SHRINK) { >>> BUG_ON(!mutex_is_locked(>io_inode->i_mutex)); >>> - /* wait for aio reads in flight */ >>> + /* >>> +* Wait for already submitted aio reads. Further reads >>> +* (including already queued to bg_queue) will be stopped >>> +* by wait_shrink(), and they will be processed from >>> +* _pcs_shrink_end(). >>> +*/ >> >> Why do we have to wait already submitted aio reads ? > > Because there could be grow requests. This place is broken, I'm fixing that > at the moment. > One-dimensional size.op is not enough to drive race between grow and shrink, > we need to > convert PCS_SIZE_* into bit fields like it used to be before. > I don't understand. There are no chances to races between grow and shrink, because the shrink is protected from simultaneous execution with write requests at the fuse level. No write requests - no grows. >>> inode_dio_wait(req->io_inode); >>> /* >>> * Writebackcache was flushed already so it is safe to >>> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Add comment about why we need to wait pending read requests
On 23.10.2018 16:38, Kirill Tkhai wrote: > On 23.10.2018 16:08, Pavel Butsykin wrote: >> >> >> On 23.10.2018 13:19, Kirill Tkhai wrote: >>> On 23.10.2018 13:15, Pavel Butsykin wrote: >>>> >>>> >>>> On 23.10.2018 13:01, Kirill Tkhai wrote: >>>>> Signed-off-by: Kirill Tkhai >>>>> --- >>>>> fs/fuse/kio/pcs/pcs_fuse_kdirect.c |7 ++- >>>>> 1 file changed, 6 insertions(+), 1 deletion(-) >>>>> >>>>> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> index 3940d6c255ba..9b45fcbf8941 100644 >>>>> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>>>> @@ -1081,7 +1081,12 @@ static void pcs_kio_setattr_handle(struct >>>>> fuse_inode *fi, struct fuse_req *req) >>>>> r->end = req->end; >>>>> if (di->size.op == PCS_SIZE_SHRINK) { >>>>> BUG_ON(!mutex_is_locked(>io_inode->i_mutex)); >>>>> - /* wait for aio reads in flight */ >>>>> + /* >>>>> + * Wait for already submitted aio reads. Further reads >>>>> + * (including already queued to bg_queue) will be stopped >>>>> + * by wait_shrink(), and they will be processed from >>>>> + * _pcs_shrink_end(). >>>>> + */ >>>> >>>> Why do we have to wait already submitted aio reads ? >>> >>> Because there could be grow requests. This place is broken, I'm fixing that >>> at the moment. >>> One-dimensional size.op is not enough to drive race between grow and >>> shrink, we need to >>> convert PCS_SIZE_* into bit fields like it used to be before. >>> >> >> I don't understand. There are no chances to races between grow and >> shrink, because the shrink is protected from simultaneous execution with >> write requests at the fuse level. No write requests - no grows. > > Not exactly. Currently we have fallocate requests, which may spawn a grow > operation. > Even FALLOC_FL_KEEP_SIZE may do that -- then inode mutex is not held. So, the > question > is not so easy, what is correct, and which is place should be fixed. > So, we have two places where possible fallocate without mutex: 1. static size_t fuse_send_unmap(struct fuse_req *req, struct fuse_io_priv *io, loff_t pos, size_t count, fl_owner_t owner) { .. inarg->mode = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE; req->in.h.opcode = FUSE_FALLOCATE; .. if (io->async) return fuse_async_req_send(fc, req, count, io); fuse_request_send(fc, req); return count; } It's definitely a mistake, we should protect this fallocate from simultaneous execution with shrink. 2. static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, loff_t length) { ... bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || (mode & (FALLOC_FL_PUNCH_HOLE|FALLOC_FL_ZERO_RANGE)); /* Return error if mode is not supported */ if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) return -EOPNOTSUPP; ... So, fallocate without mutex only possible if (mode & FALLOC_FL_KEEP_SIZE) == FALLOC_FL_KEEP_SIZE. Hmm, what does it mean ? Looks like it will be the same as FALLOC_FL_ZERO_RANGE|FALLOC_FL_KEEP_SIZE. I wonder, Do we need to handle such fallocate for vstorage at all? It seems that NO, it's just PCS_IREQ_NOOP. Alexey? >>>>> inode_dio_wait(req->io_inode); >>>>> /* >>>>>* Writebackcache was flushed already so it is safe to >>>>> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 1/3] fuse: Fix parse_fuse_opt() return values wrong interpretation
On 30.10.2018 11:55, Kirill Tkhai wrote: > This function returns not 0 in case of success, and 0 in case > of failure. So, error values like -EPERM are interpreted as > success, which is wrong. Fix that. > Note, that fuse has generic EINVAL return value for all types > of unacceptable parameters. > > Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin > --- > fs/fuse/inode.c |8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c > index ca9a146d39fa..0695b79c4c50 100644 > --- a/fs/fuse/inode.c > +++ b/fs/fuse/inode.c > @@ -688,19 +688,19 @@ static int parse_fuse_opt(char *opt, struct > fuse_mount_data *d, int is_bdev) > > case OPT_WBCACHE: > if (!ve_is_super(get_exec_env()) && !fuse_ve_odirect) > - return -EPERM; > + return 0; > d->writeback_cache = 1; > break; > > case OPT_ODIRECT: > if (!ve_is_super(get_exec_env()) && !fuse_ve_odirect) > - return -EPERM; > + return 0; > d->flags |= FUSE_ODIRECT; > break; > > case OPT_UMOUNT_WAIT: > if (!ve_is_super(get_exec_env()) && !fuse_ve_odirect) > - return -EPERM; > + return 0; > d->flags |= FUSE_UMOUNT_WAIT; > break; > > @@ -711,7 +711,7 @@ static int parse_fuse_opt(char *opt, struct > fuse_mount_data *d, int is_bdev) > char *name; > name = match_strdup([0]); > if (!name) > - return 1; > + return 0; > > strncpy(d->kio_name, name, FUSE_KIO_NAME); > d->flags |= FUSE_KDIRECT_IO; > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 2/3] fuse: Prohibit kio engine from containers
On 30.10.2018 11:55, Kirill Tkhai wrote: > Currently we have several BUG_ON() ported from userspace, > and they may fire in case of it's used malicious daemon > instead of original vstorage-mount. So, just prohibit > mounting with kio from inside container. > > https://pmc.acronis.com/browse/VSTOR-16325 > > Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin > --- > fs/fuse/inode.c |2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c > index 0695b79c4c50..34e52262d37e 100644 > --- a/fs/fuse/inode.c > +++ b/fs/fuse/inode.c > @@ -709,6 +709,8 @@ static int parse_fuse_opt(char *opt, struct > fuse_mount_data *d, int is_bdev) > break; > case OPT_KIO_NAME: { > char *name; > + if (!ve_is_super(get_exec_env())) > + return 0; > name = match_strdup([0]); > if (!name) > return 0; > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 3/3] fuse: Switch unused engines off in Kconfig
On 30.10.2018 11:55, Kirill Tkhai wrote: > We do not test and do not use these engines. They were > needed on initial stage of development, but now their > time is over. > > It's not safe to distribute untested (and never used) > debug modules in production, so this patch disables > them by default. Some time later, if there is no at least > a single using of them in any purpose, we'll completely > drop them. > > https://pmc.acronis.com/browse/VSTOR-16325 > > Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin > --- > configs/kernel-3.10.0-x86_64-debug.config |4 ++-- > configs/kernel-3.10.0-x86_64-minimal.config |4 ++-- > configs/kernel-3.10.0-x86_64.config |4 ++-- > fs/fuse/Kconfig |2 ++ > 4 files changed, 8 insertions(+), 6 deletions(-) > > diff --git a/configs/kernel-3.10.0-x86_64-debug.config > b/configs/kernel-3.10.0-x86_64-debug.config > index 9ff450667838..758f7618abc1 100644 > --- a/configs/kernel-3.10.0-x86_64-debug.config > +++ b/configs/kernel-3.10.0-x86_64-debug.config > @@ -6430,8 +6430,8 @@ CONFIG_NETFILTER_XT_MATCH_WDOG_TMO=m > > CONFIG_VE_IP_NF_VZPRIVNET=m > > -CONFIG_FUSE_KIO_NOOP=m > -CONFIG_FUSE_KIO_NULLIO=m > +# CONFIG_FUSE_KIO_NOOP is not set > +# CONFIG_FUSE_KIO_NULLIO is not set > CONFIG_FUSE_KIO_PCS=m > > CONFIG_FUSE_KIO_DEBUG=y > diff --git a/configs/kernel-3.10.0-x86_64-minimal.config > b/configs/kernel-3.10.0-x86_64-minimal.config > index 4a5211f1dc47..037821b0dea5 100644 > --- a/configs/kernel-3.10.0-x86_64-minimal.config > +++ b/configs/kernel-3.10.0-x86_64-minimal.config > @@ -3682,8 +3682,8 @@ CONFIG_QUOTACTL_COMPAT=y > CONFIG_AUTOFS4_FS=y > CONFIG_FUSE_FS=y > # CONFIG_CUSE is not set > -CONFIG_FUSE_KIO_NOOP=y > -CONFIG_FUSE_KIO_NULLIO=y > +# CONFIG_FUSE_KIO_NOOP is not set > +# CONFIG_FUSE_KIO_NULLIO is not set > CONFIG_FUSE_KIO_PCS=y > # CONFIG_FUSE_KIO_DEBUG is not set > CONFIG_OVERLAY_FS=y > diff --git a/configs/kernel-3.10.0-x86_64.config > b/configs/kernel-3.10.0-x86_64.config > index bdc91d414de6..8b5e2ade38f3 100644 > --- a/configs/kernel-3.10.0-x86_64.config > +++ b/configs/kernel-3.10.0-x86_64.config > @@ -6401,8 +6401,8 @@ CONFIG_NETFILTER_XT_MATCH_WDOG_TMO=m > > CONFIG_VE_IP_NF_VZPRIVNET=m > > -CONFIG_FUSE_KIO_NOOP=m > -CONFIG_FUSE_KIO_NULLIO=m > +# CONFIG_FUSE_KIO_NOOP is not set > +# CONFIG_FUSE_KIO_NULLIO is not set > CONFIG_FUSE_KIO_PCS=m > > # CONFIG_FUSE_KIO_DEBUG is not set > diff --git a/fs/fuse/Kconfig b/fs/fuse/Kconfig > index b7fc9e8be4a2..8ecc12182e6a 100644 > --- a/fs/fuse/Kconfig > +++ b/fs/fuse/Kconfig > @@ -29,6 +29,7 @@ config CUSE > config FUSE_KIO_NOOP > tristate "Enable kdirect noop io engine" > depends on FUSE_FS > + default n > help > This FUSE extension allows to handle io requests directly inside > kernel > > @@ -37,6 +38,7 @@ config FUSE_KIO_NOOP > config FUSE_KIO_NULLIO > tristate "Enable kdirect null io io engine" > depends on FUSE_FS > + default n > help > This FUSE extension allows to handle io requests directly inside > kernel > > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Fix deadlock in kpcs_req_send()
On 09.10.2018 19:04, Kirill Tkhai wrote: spin_lock(>lock); flush_bg_queue() fc->kio.op->req_send(fc, req, true, true) pcs_kio_classify_req() request_end() spin_lock(>lock); ===> Deadlock Also, pcs_kio_setattr_handle() may sleep. [This should go on top of "[PATCH RFC] fs/fuse kio_pcs: fix double free of synchronous requests"] https://pmc.acronis.com/browse/VSTOR-15924 Signed-off-by: Kirill Tkhai Reviewed-by: Pavel Butsykin Actually FUSE_SETATTR can't be async, but extra precaution won't hurt.. --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index c967b99ae116..06e254cc3ef9 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -1035,9 +1035,6 @@ static void pcs_kio_setattr_handle(struct fuse_inode *fi, struct fuse_req *req) struct fuse_setattr_in *inarg = (void*) req->in.args[0].value; struct pcs_dentry_info *di; - if (!(inarg->valid & FATTR_SIZE)) - return; - BUG_ON(!fi); di = pcs_inode_from_fuse(fi); @@ -1063,7 +1060,7 @@ static void pcs_kio_setattr_handle(struct fuse_inode *fi, struct fuse_req *req) req->end = _pcs_grow_end; } -static int pcs_kio_classify_req(struct fuse_conn *fc, struct fuse_req *req) +static int pcs_kio_classify_req(struct fuse_conn *fc, struct fuse_req *req, bool lk) { struct fuse_inode *fi = get_fuse_inode(req->io_inode); @@ -1074,12 +1071,20 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, struct fuse_req *req) case FUSE_FLUSH: case FUSE_FALLOCATE: break; - case FUSE_SETATTR: + case FUSE_SETATTR: { + struct fuse_setattr_in const *inarg = req->in.args[0].value; + if (unlikely(!fi || !fi->private)) goto fail; - + if (!(inarg->valid & FATTR_SIZE)) + return 1; + if (lk) + spin_unlock(>lock); pcs_kio_setattr_handle(fi, req); + if (lk) + spin_lock(>lock); return 1; + } case FUSE_IOCTL: { struct fuse_ioctl_in const *inarg = req->in.args[0].value; @@ -1119,14 +1124,18 @@ static int kpcs_req_send(struct fuse_conn* fc, struct fuse_req *req, bool bg, bo TRACE(" Enter req:%p op:%d end:%p bg:%d lk:%d\n", req, req->in.h.opcode, req->end, bg, lk); - ret = pcs_kio_classify_req(fc, req); + ret = pcs_kio_classify_req(fc, req, lk); if (ret) { if (ret < 0) { if (!bg) atomic_inc(>count); __clear_bit(FR_PENDING, >flags); req->out.h.error = ret; + if (lk) + spin_unlock(>lock); request_end(fc, req); + if (lk) + spin_lock(>lock); return 0; } return 1; ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fuse kio: Return possibility to handle files served in userspace
On 10.10.2018 19:43, Kirill Tkhai wrote: > Fallback to old behavior, when !fi->private files are > served in userspace. > > https://pmc.acronis.com/browse/VSTOR-15947 > > Signed-off-by: Kirill Tkhai Acked-by: Pavel Butsykin > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c |8 ++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index cd059b28d940..14bed318d139 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -1073,8 +1073,10 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, > struct fuse_req *req, bool > case FUSE_SETATTR: { > struct fuse_setattr_in const *inarg = req->in.args[0].value; > > - if (unlikely(!fi || !fi->private)) > + if (unlikely(!fi)) > goto fail; > + if (!fi->private) > + return 1; > if (!(inarg->valid & FATTR_SIZE)) > return 1; > if (lk) > @@ -1096,8 +1098,10 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, > struct fuse_req *req, bool > return 1; > } > > - if (unlikely(!fi || !fi->private)) > + if (unlikely(!fi)) > goto fail; > + if (!fi->private) > + return 1; > > return 0; > > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: invalidate files for kio
Make fuse_invalidate_files() work for kio. This is necessary to maintain vstorage revoke in FPath mode. To do this, let's add a list of inflight kio requests to be able to handle this list in fuse_invalidate_files(). The list will also be useful to implement the full-featured .vstorage.info and fuse_abort_conn() for kio. #VSTOR-19620 Signed-off-by: Pavel Butsykin --- fs/fuse/fuse_i.h | 4 fs/fuse/inode.c| 8 ++-- fs/fuse/kio/pcs/fuse_io.c | 5 + fs/fuse/kio/pcs/pcs_cluster.c | 2 ++ fs/fuse/kio/pcs/pcs_cluster.h | 1 + fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 16 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 4c27bfa0e74d..0914940d6735 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -528,6 +528,7 @@ struct fuse_kio_ops { int (*file_open)(struct fuse_conn *fc, struct file *file, struct inode *inode); void (*inode_release)(struct fuse_inode *fi); + void (*kill_requests)(struct fuse_conn *fc, struct inode *inode); }; int fuse_register_kio(struct fuse_kio_ops *ops); @@ -1107,4 +1108,7 @@ struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi); void fuse_release_ff(struct inode *inode, struct fuse_file *ff); +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, + struct list_head *req_list); + #endif /* _FS_FUSE_I_H */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 34e52262d37e..cb275ff21991 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -369,8 +369,8 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid, return 0; } -static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, - struct list_head *req_list) +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, + struct list_head *req_list) { struct fuse_req *req; @@ -393,6 +393,7 @@ static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, req->num_pages = 0; } } +EXPORT_SYMBOL_GPL(fuse_kill_requests); int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid) { @@ -442,6 +443,9 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid) } fuse_kill_requests(fc, inode, >main_iq.pending); fuse_kill_requests(fc, inode, >bg_queue); + if (fc->kio.op && fc->kio.op->kill_requests) + fc->kio.op->kill_requests(fc, inode); + wake_up(>page_waitq); /* readpage[s] can wait on fuse wb */ spin_unlock(>lock); diff --git a/fs/fuse/kio/pcs/fuse_io.c b/fs/fuse/kio/pcs/fuse_io.c index 61a2e7f1eac6..00a72c878efb 100644 --- a/fs/fuse/kio/pcs/fuse_io.c +++ b/fs/fuse/kio/pcs/fuse_io.c @@ -205,6 +205,7 @@ static void prepare_io_(struct pcs_fuse_req *r, unsigned short type, off_t offse static void ioreq_complete(pcs_api_iorequest_t *ioreq) { struct pcs_fuse_req *r = ioreq->datasource; + struct fuse_conn *fc = cl_from_req(r)->fc; BUG_ON(ioreq != >exec.io.req); @@ -217,6 +218,10 @@ static void ioreq_complete(pcs_api_iorequest_t *ioreq) r->req.out.h.error = 0; } + spin_lock(>lock); + list_del_init(>req.list); + spin_unlock(>lock); + switch (ioreq->type) { case PCS_REQ_T_READ: on_read_done(r, ioreq->size); diff --git a/fs/fuse/kio/pcs/pcs_cluster.c b/fs/fuse/kio/pcs/pcs_cluster.c index 5df263f01f98..6b8f38db5c40 100644 --- a/fs/fuse/kio/pcs/pcs_cluster.c +++ b/fs/fuse/kio/pcs/pcs_cluster.c @@ -608,6 +608,8 @@ int pcs_cluster_init(struct pcs_fuse_cluster *pfc, struct workqueue_struct *wq, pfc->cc.op.ireq_on_error = ireq_on_error_; pfc->cc.op.ireq_check_redo = ireq_check_redo_; + INIT_LIST_HEAD(>kio_queue); + return 0; } diff --git a/fs/fuse/kio/pcs/pcs_cluster.h b/fs/fuse/kio/pcs/pcs_cluster.h index 9c537cb43b30..8a3ae3244b80 100644 --- a/fs/fuse/kio/pcs/pcs_cluster.h +++ b/fs/fuse/kio/pcs/pcs_cluster.h @@ -32,6 +32,7 @@ struct pcs_fuse_req { struct pcs_fuse_cluster { struct pcs_cluster_core cc; struct fuse_conn *fc; + struct list_head kio_queue; }; struct pcs_fuse_work { diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index cdd4fe578128..1ca27b80b002 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -983,6 +983,12 @@ error: return; submit: + if (!lk) + spin_lock(>fc->lock); + list_add_tail(>list, >kio_queue); + if (!lk) + spin_unlock(>fc->lock); + if (async) pcs_cc_submit(ireq->cc, ireq);
Re: [Devel] [PATCH] fs/fuse kio: invalidate files for kio
I agree fc->lock is evil, but fc->lock is not a necessary condition for implementation kio queue, so let's look at my second try. On 18.01.2019 18:00, Alexey Kuznetsov wrote: > Hello! > > Huh? We were going to get rid of fc->lock and definitely are not going > to add new ones. > It is exactly why it was not made in the first place. > > On Fri, Jan 18, 2019 at 4:44 PM Pavel Butsykin > wrote: >> >> Make fuse_invalidate_files() work for kio. This is necessary to maintain >> vstorage revoke in FPath mode. To do this, let's add a list of inflight kio >> requests to be able to handle this list in fuse_invalidate_files(). The list >> will also be useful to implement the full-featured .vstorage.info and >> fuse_abort_conn() for kio. >> >> #VSTOR-19620 >> >> Signed-off-by: Pavel Butsykin >> --- >> fs/fuse/fuse_i.h | 4 >> fs/fuse/inode.c| 8 ++-- >> fs/fuse/kio/pcs/fuse_io.c | 5 + >> fs/fuse/kio/pcs/pcs_cluster.c | 2 ++ >> fs/fuse/kio/pcs/pcs_cluster.h | 1 + >> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 16 >> 6 files changed, 34 insertions(+), 2 deletions(-) >> >> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h >> index 4c27bfa0e74d..0914940d6735 100644 >> --- a/fs/fuse/fuse_i.h >> +++ b/fs/fuse/fuse_i.h >> @@ -528,6 +528,7 @@ struct fuse_kio_ops { >> int (*file_open)(struct fuse_conn *fc, struct file *file, >>struct inode *inode); >> void (*inode_release)(struct fuse_inode *fi); >> + void (*kill_requests)(struct fuse_conn *fc, struct inode *inode); >> >> }; >> int fuse_register_kio(struct fuse_kio_ops *ops); >> @@ -1107,4 +1108,7 @@ struct fuse_file *fuse_write_file(struct fuse_conn >> *fc, struct fuse_inode *fi); >> >> void fuse_release_ff(struct inode *inode, struct fuse_file *ff); >> >> +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, >> + struct list_head *req_list); >> + >> #endif /* _FS_FUSE_I_H */ >> diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c >> index 34e52262d37e..cb275ff21991 100644 >> --- a/fs/fuse/inode.c >> +++ b/fs/fuse/inode.c >> @@ -369,8 +369,8 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 >> nodeid, >> return 0; >> } >> >> -static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, >> - struct list_head *req_list) >> +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, >> + struct list_head *req_list) >> { >> struct fuse_req *req; >> >> @@ -393,6 +393,7 @@ static void fuse_kill_requests(struct fuse_conn *fc, >> struct inode *inode, >> req->num_pages = 0; >> } >> } >> +EXPORT_SYMBOL_GPL(fuse_kill_requests); >> >> int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid) >> { >> @@ -442,6 +443,9 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 >> nodeid) >> } >> fuse_kill_requests(fc, inode, >main_iq.pending); >> fuse_kill_requests(fc, inode, >bg_queue); >> + if (fc->kio.op && fc->kio.op->kill_requests) >> + fc->kio.op->kill_requests(fc, inode); >> + >> wake_up(>page_waitq); /* readpage[s] can wait on fuse >> wb */ >> spin_unlock(>lock); >> >> diff --git a/fs/fuse/kio/pcs/fuse_io.c b/fs/fuse/kio/pcs/fuse_io.c >> index 61a2e7f1eac6..00a72c878efb 100644 >> --- a/fs/fuse/kio/pcs/fuse_io.c >> +++ b/fs/fuse/kio/pcs/fuse_io.c >> @@ -205,6 +205,7 @@ static void prepare_io_(struct pcs_fuse_req *r, unsigned >> short type, off_t offse >> static void ioreq_complete(pcs_api_iorequest_t *ioreq) >> { >> struct pcs_fuse_req *r = ioreq->datasource; >> + struct fuse_conn *fc = cl_from_req(r)->fc; >> >> BUG_ON(ioreq != >exec.io.req); >> >> @@ -217,6 +218,10 @@ static void ioreq_complete(pcs_api_iorequest_t *ioreq) >> r->req.out.h.error = 0; >> } >> >> + spin_lock(>lock); >> + list_del_init(>req.list); >> + spin_unlock(>lock); >> + >> switch (ioreq->type) { >> case PCS_REQ_T_READ: >> on_read_done(r, ioreq->size); >>
Re: [Devel] [PATCH] fs/fuse kio: invalidate files for kio
Good, Thanks! By the way, is there any response to "Prevent background write requests increase inode size" ? On 21.01.2019 19:29, Kirill Tkhai wrote: > JFI: I submitted to mainstream patches for breaking fc->lock dependence: > > https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git/log/?h=for-next > > I'm going to backport them to us next week. > > On 21.01.2019 19:27, Pavel Butsykin wrote: >> I agree fc->lock is evil, but fc->lock is not a necessary condition for >> implementation kio queue, so let's look at my second try. >> >> On 18.01.2019 18:00, Alexey Kuznetsov wrote: >>> Hello! >>> >>> Huh? We were going to get rid of fc->lock and definitely are not going >>> to add new ones. >>> It is exactly why it was not made in the first place. >>> >>> On Fri, Jan 18, 2019 at 4:44 PM Pavel Butsykin >>> wrote: >>>> >>>> Make fuse_invalidate_files() work for kio. This is necessary to maintain >>>> vstorage revoke in FPath mode. To do this, let's add a list of inflight kio >>>> requests to be able to handle this list in fuse_invalidate_files(). The >>>> list >>>> will also be useful to implement the full-featured .vstorage.info and >>>> fuse_abort_conn() for kio. >>>> >>>> #VSTOR-19620 >>>> >>>> Signed-off-by: Pavel Butsykin >>>> --- >>>>fs/fuse/fuse_i.h | 4 >>>>fs/fuse/inode.c| 8 ++-- >>>>fs/fuse/kio/pcs/fuse_io.c | 5 + >>>>fs/fuse/kio/pcs/pcs_cluster.c | 2 ++ >>>>fs/fuse/kio/pcs/pcs_cluster.h | 1 + >>>>fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 16 >>>>6 files changed, 34 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h >>>> index 4c27bfa0e74d..0914940d6735 100644 >>>> --- a/fs/fuse/fuse_i.h >>>> +++ b/fs/fuse/fuse_i.h >>>> @@ -528,6 +528,7 @@ struct fuse_kio_ops { >>>> int (*file_open)(struct fuse_conn *fc, struct file *file, >>>> struct inode *inode); >>>> void (*inode_release)(struct fuse_inode *fi); >>>> + void (*kill_requests)(struct fuse_conn *fc, struct inode *inode); >>>> >>>>}; >>>>int fuse_register_kio(struct fuse_kio_ops *ops); >>>> @@ -1107,4 +1108,7 @@ struct fuse_file *fuse_write_file(struct fuse_conn >>>> *fc, struct fuse_inode *fi); >>>> >>>>void fuse_release_ff(struct inode *inode, struct fuse_file *ff); >>>> >>>> +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, >>>> + struct list_head *req_list); >>>> + >>>>#endif /* _FS_FUSE_I_H */ >>>> diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c >>>> index 34e52262d37e..cb275ff21991 100644 >>>> --- a/fs/fuse/inode.c >>>> +++ b/fs/fuse/inode.c >>>> @@ -369,8 +369,8 @@ int fuse_reverse_inval_inode(struct super_block *sb, >>>> u64 nodeid, >>>> return 0; >>>>} >>>> >>>> -static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, >>>> - struct list_head *req_list) >>>> +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, >>>> + struct list_head *req_list) >>>>{ >>>> struct fuse_req *req; >>>> >>>> @@ -393,6 +393,7 @@ static void fuse_kill_requests(struct fuse_conn *fc, >>>> struct inode *inode, >>>> req->num_pages = 0; >>>> } >>>>} >>>> +EXPORT_SYMBOL_GPL(fuse_kill_requests); >>>> >>>>int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid) >>>>{ >>>> @@ -442,6 +443,9 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 >>>> nodeid) >>>> } >>>> fuse_kill_requests(fc, inode, >main_iq.pending); >>>> fuse_kill_requests(fc, inode, >bg_queue); >>>> + if (fc->kio.op && fc->kio.op->kill_requests) >>>> + fc->kio.op->kill_requests(fc, inode); >>>> + >>>> wake_u
[Devel] [PATCH v2] fs/fuse kio: invalidate files for kio
Make fuse_invalidate_files() work for kio. This is necessary to maintain vstorage revoke in FPath mode. To do this, let's add a list of inflight kio requests to be able to handle this list in fuse_invalidate_files(). The list will also be useful to implement the full-featured .vstorage.info and fuse_abort_conn() for kio. #VSTOR-19620 Signed-off-by: Pavel Butsykin --- fs/fuse/fuse_i.h | 4 fs/fuse/inode.c| 8 ++-- fs/fuse/kio/pcs/fuse_io.c | 5 + fs/fuse/kio/pcs/pcs_client_types.h | 2 ++ fs/fuse/kio/pcs/pcs_cluster.h | 7 +++ fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 27 +++ 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 4c27bfa0e74d..0914940d6735 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -528,6 +528,7 @@ struct fuse_kio_ops { int (*file_open)(struct fuse_conn *fc, struct file *file, struct inode *inode); void (*inode_release)(struct fuse_inode *fi); + void (*kill_requests)(struct fuse_conn *fc, struct inode *inode); }; int fuse_register_kio(struct fuse_kio_ops *ops); @@ -1107,4 +1108,7 @@ struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi); void fuse_release_ff(struct inode *inode, struct fuse_file *ff); +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, + struct list_head *req_list); + #endif /* _FS_FUSE_I_H */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 34e52262d37e..cb275ff21991 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -369,8 +369,8 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid, return 0; } -static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, - struct list_head *req_list) +void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, + struct list_head *req_list) { struct fuse_req *req; @@ -393,6 +393,7 @@ static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode, req->num_pages = 0; } } +EXPORT_SYMBOL_GPL(fuse_kill_requests); int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid) { @@ -442,6 +443,9 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid) } fuse_kill_requests(fc, inode, >main_iq.pending); fuse_kill_requests(fc, inode, >bg_queue); + if (fc->kio.op && fc->kio.op->kill_requests) + fc->kio.op->kill_requests(fc, inode); + wake_up(>page_waitq); /* readpage[s] can wait on fuse wb */ spin_unlock(>lock); diff --git a/fs/fuse/kio/pcs/fuse_io.c b/fs/fuse/kio/pcs/fuse_io.c index 61a2e7f1eac6..219f4e3423af 100644 --- a/fs/fuse/kio/pcs/fuse_io.c +++ b/fs/fuse/kio/pcs/fuse_io.c @@ -205,6 +205,7 @@ static void prepare_io_(struct pcs_fuse_req *r, unsigned short type, off_t offse static void ioreq_complete(pcs_api_iorequest_t *ioreq) { struct pcs_fuse_req *r = ioreq->datasource; + struct pcs_dentry_info *di = get_pcs_inode(r->req.io_inode); BUG_ON(ioreq != >exec.io.req); @@ -217,6 +218,10 @@ static void ioreq_complete(pcs_api_iorequest_t *ioreq) r->req.out.h.error = 0; } + spin_lock(>kq_lock); + list_del_init(>req.list); + spin_unlock(>kq_lock); + switch (ioreq->type) { case PCS_REQ_T_READ: on_read_done(r, ioreq->size); diff --git a/fs/fuse/kio/pcs/pcs_client_types.h b/fs/fuse/kio/pcs/pcs_client_types.h index 9ddce5cff3f5..1be32cbbf285 100644 --- a/fs/fuse/kio/pcs/pcs_client_types.h +++ b/fs/fuse/kio/pcs/pcs_client_types.h @@ -68,6 +68,8 @@ struct pcs_dentry_info { size_op_t op; } size; struct fuse_inode *inode; + struct list_headkq; + spinlock_t kq_lock; }; static inline void pcs_clear_fileinfo(struct pcs_dentry_info *i) diff --git a/fs/fuse/kio/pcs/pcs_cluster.h b/fs/fuse/kio/pcs/pcs_cluster.h index 9c537cb43b30..73af9359706e 100644 --- a/fs/fuse/kio/pcs/pcs_cluster.h +++ b/fs/fuse/kio/pcs/pcs_cluster.h @@ -78,6 +78,13 @@ static inline struct pcs_dentry_info *pcs_inode_from_fuse(struct fuse_inode *fi) return (struct pcs_dentry_info *)fi->private; } +static inline struct pcs_dentry_info *get_pcs_inode(struct inode *inode) +{ + struct fuse_inode *fi = get_fuse_inode(inode); + + return pcs_inode_from_fuse(fi); +} + static inline struct pcs_fuse_cluster *cl_from_req(struct pcs_fuse_req *r) { return pcs_cluster_from_cc(r->exec.ireq.cc); diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index cdd4fe578128..da4b5fba03fb 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
Re: [Devel] [PATCH] fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send
23.01.2019 16:55, Kirill Tkhai пишет: > On 23.01.2019 14:49, Pavel Butsykin wrote: >> Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to execute new >> requests. But in case of kio requests it doesn't work because the status >> check >> is located behind kio.op->req_send(). To fix this let's move the status check >> before kio.op->req_send(). >> >> Note: We can drop hunk with req->end(fc, req) in __fuse_request_send() >> because >> it was only needed to clenup kio setattr request after >> pcs_kio_setattr_handle(). >> >> Signed-off-by: Pavel Butsykin > Why is this safe? > > After you move the check out of fc->lock, it becomes racy, and > fuse_invalidate_files() > may become work not as expected. test_bit is atomic operation. Which type of race do you mean? >> --- >> fs/fuse/dev.c | 40 +++- >> 1 file changed, 23 insertions(+), 17 deletions(-) >> >> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c >> index dc21886ee55d..dcbed5d4932c 100644 >> --- a/fs/fuse/dev.c >> +++ b/fs/fuse/dev.c >> @@ -538,6 +538,11 @@ static void __fuse_request_send(struct fuse_conn *fc, >> struct fuse_req *req, >> >> BUG_ON(test_bit(FR_BACKGROUND, >flags)); >> >> +if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state)) { >> +req->out.h.error = -EIO; >> +return; >> +} >> + >> if (fc->kio.op && !fc->kio.op->req_send(fc, req, false, false)) >> return; >> >> @@ -547,11 +552,6 @@ static void __fuse_request_send(struct fuse_conn *fc, >> struct fuse_req *req, >> req->out.h.error = -ENOTCONN; >> if (req->end) >> req->end(fc, req); >> -} else if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state)) { >> -spin_unlock(>waitq.lock); >> -req->out.h.error = -EIO; >> -if (req->end) >> -req->end(fc, req); >> } else { >> req->in.h.unique = fuse_get_unique(fiq); >> queue_request(fiq, req); >> @@ -627,20 +627,26 @@ void fuse_request_send_background(struct fuse_conn >> *fc, struct fuse_req *req) >> { >> BUG_ON(!req->end); >> >> -if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, false)) >> -return; >> - >> -spin_lock(>lock); >> if (req->page_cache && req->ff && >> test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff->ff_state)) { >> -BUG_ON(req->in.h.opcode != FUSE_READ); >> -req->out.h.error = -EIO; >> -__clear_bit(FR_BACKGROUND, >flags); >> -__clear_bit(FR_PENDING, >flags); >> -list_del_init(>list); >> -spin_unlock(>lock); >> -request_end(fc, req); >> -} else if (fc->connected) { >> +BUG_ON(req->in.h.opcode != FUSE_READ); >> +req->out.h.error = -EIO; >> +__clear_bit(FR_BACKGROUND, >flags); >> +__clear_bit(FR_PENDING, >flags); >> + >> +spin_lock(>lock); >> +list_del_init(>list); >> +spin_unlock(>lock); >> + >> +request_end(fc, req); >> +return; >> +} >> + >> +if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, false)) >> +return; >> + >> +spin_lock(>lock); >> +if (fc->connected) { >> fuse_request_send_background_locked(fc, req); >> spin_unlock(>lock); >> } else { >> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send
Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to execute new requests. But in case of kio requests it doesn't work because the status check is located behind kio.op->req_send(). To fix this let's move the status check before kio.op->req_send(). Note: We can drop hunk with req->end(fc, req) in __fuse_request_send() because it was only needed to clenup kio setattr request after pcs_kio_setattr_handle(). Signed-off-by: Pavel Butsykin --- fs/fuse/dev.c | 40 +++- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index dc21886ee55d..dcbed5d4932c 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -538,6 +538,11 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req, BUG_ON(test_bit(FR_BACKGROUND, >flags)); + if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state)) { + req->out.h.error = -EIO; + return; + } + if (fc->kio.op && !fc->kio.op->req_send(fc, req, false, false)) return; @@ -547,11 +552,6 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req, req->out.h.error = -ENOTCONN; if (req->end) req->end(fc, req); - } else if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state)) { - spin_unlock(>waitq.lock); - req->out.h.error = -EIO; - if (req->end) - req->end(fc, req); } else { req->in.h.unique = fuse_get_unique(fiq); queue_request(fiq, req); @@ -627,20 +627,26 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) { BUG_ON(!req->end); - if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, false)) - return; - - spin_lock(>lock); if (req->page_cache && req->ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff->ff_state)) { - BUG_ON(req->in.h.opcode != FUSE_READ); - req->out.h.error = -EIO; - __clear_bit(FR_BACKGROUND, >flags); - __clear_bit(FR_PENDING, >flags); - list_del_init(>list); - spin_unlock(>lock); - request_end(fc, req); - } else if (fc->connected) { + BUG_ON(req->in.h.opcode != FUSE_READ); + req->out.h.error = -EIO; + __clear_bit(FR_BACKGROUND, >flags); + __clear_bit(FR_PENDING, >flags); + + spin_lock(>lock); + list_del_init(>list); + spin_unlock(>lock); + + request_end(fc, req); + return; + } + + if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, false)) + return; + + spin_lock(>lock); + if (fc->connected) { fuse_request_send_background_locked(fc, req); spin_unlock(>lock); } else { -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: fix mapping dereference in a dead map
MAP_ARGS() contains reference to struct pcs_map_entry::mapping, which can be NULL if map is dead. #VSTOR-19267 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_map.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 817c7d6a9379..ad31d1222da3 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -1175,7 +1175,8 @@ void pcs_map_complete(struct pcs_map_entry *m, struct pcs_ioc_getmap *omap) return; error: - TRACE(" map error: %d for " MAP_FMT "\n", error.value, MAP_ARGS(m)); + TRACE("map error: %d, m:%p, index:%lu, state:%x\n", error.value, m, + m->index, m->state); BUG_ON(!pcs_if_error()); m->state &= ~PCS_MAP_RESOLVING; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2] fs/fuse kio: deny unavailable ioctl's in kio
There are some ioctl's that were made to service the kio module, and they should not be available to user app. Also there are two ioctls PCS_IOC_NOCSUMONREAD and PCS_IOC_NOWRITEDELAY that must be handled in kio, otherwise they are meaningless. So let's return -EOPNOTSUPP unless we implement them in kio. Signed-off-by: Pavel Butsykin --- fs/fuse/fuse_i.h | 2 ++ fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 27 --- fs/fuse/kio/pcs/pcs_ioctl.h| 5 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index d7dd571c08f6..4c27bfa0e74d 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -301,6 +301,7 @@ struct fuse_io_priv { * FR_FINISHED:request is finished * FR_PRIVATE: request is on private list * FR_NONBLOCKING: non-blocking request (only needed for KIO) + * FR_KIO_INTERNAL:request initiated by KIO */ enum fuse_req_flag { FR_ISREPLY, @@ -315,6 +316,7 @@ enum fuse_req_flag { FR_FINISHED, FR_PRIVATE, FR_NONBLOCKING, + FR_KIO_INTERNAL, }; /** diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 89866370a341..cdd4fe578128 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -156,6 +156,7 @@ int kpcs_conn_init(struct fuse_conn *fc) } __set_bit(FR_BACKGROUND, >flags); + __set_bit(FR_KIO_INTERNAL, >flags); memset(>misc.ioctl, 0, sizeof(req->misc.ioctl)); /* filehandle and nodeid are null, but this is OK */ inarg = >misc.ioctl.in; @@ -218,6 +219,7 @@ static int fuse_pcs_getfileinfo(struct fuse_conn *fc, struct file *file, if (IS_ERR(req)) return PTR_ERR(req); + __set_bit(FR_KIO_INTERNAL, >flags); memset(>misc.ioctl, 0, sizeof(req->misc.ioctl)); inarg = >misc.ioctl.in; outarg = >misc.ioctl.out; @@ -269,6 +271,7 @@ static int fuse_pcs_kdirect_claim_op(struct fuse_conn *fc, struct file *file, if (IS_ERR(req)) return PTR_ERR(req); + __set_bit(FR_KIO_INTERNAL, >flags); memset(>misc.ioctl, 0, sizeof(req->misc.ioctl)); inarg = >misc.ioctl.in; outarg = >misc.ioctl.out; @@ -470,6 +473,7 @@ int fuse_map_resolve(struct pcs_map_entry *m, int direction) return PTR_ERR(req); } + __set_bit(FR_KIO_INTERNAL, >flags); memset(>misc.ioctl, 0, sizeof(req->misc.ioctl)); inarg = >misc.ioctl.in; outarg = >misc.ioctl.out; @@ -601,6 +605,7 @@ int fuse_pcs_csconn_send(struct fuse_conn *fc, struct pcs_rpc *ep, int flags) return PTR_ERR(req); } + __set_bit(FR_KIO_INTERNAL, >flags); memset(>misc.ioctl, 0, sizeof(req->misc.ioctl)); inarg = >misc.ioctl.in; outarg = >misc.ioctl.out; @@ -1084,6 +1089,9 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, struct fuse_req *req, bool { struct fuse_inode *fi = get_fuse_inode(req->io_inode); + if (test_bit(FR_KIO_INTERNAL, >flags)) + return 1; + switch (req->in.h.opcode) { case FUSE_READ: case FUSE_WRITE: @@ -1110,9 +1118,22 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, struct fuse_req *req, bool case FUSE_IOCTL: { struct fuse_ioctl_in const *inarg = req->in.args[0].value; - if (inarg->cmd != FS_IOC_FIEMAP) - return 1; - + switch (inarg->cmd) { + case FS_IOC_FIEMAP: + break; + case PCS_IOC_NOCSUMONREAD: + case PCS_IOC_NOWRITEDELAY: + return -EOPNOTSUPP; + case PCS_IOC_INIT_KDIRECT: + case PCS_IOC_CSCONN: + case PCS_IOC_GETFILEINFO: + case PCS_IOC_KDIRECT_CLAIM: + case PCS_IOC_KDIRECT_RELEASE: + case PCS_IOC_GETMAP: + return -EPERM; + default: + return 1; + } break; } default: diff --git a/fs/fuse/kio/pcs/pcs_ioctl.h b/fs/fuse/kio/pcs/pcs_ioctl.h index 5cf40e35f881..8fe1aca9ef12 100644 --- a/fs/fuse/kio/pcs/pcs_ioctl.h +++ b/fs/fuse/kio/pcs/pcs_ioctl.h @@ -78,6 +78,11 @@ struct pcs_ioc_csconn #define PCS_IOC_CS_REOPEN (PCS_IOC_CS_OPEN|PCS_IOC_CS_CLOSE) }; +#define PCS_IOC_NOCSUMONREAD _IOW('V',3,u32) +# define PCS_IOC_NOCSUMONREAD_DATA 1 +# define PCS_IOC_NOCSUMONREAD_METADATA 2 +#define PCS_IOC_NOWRITEDELAY _IOW('V',4,u32) + #define PCS_IOC_INIT_KDIRECT _IOR('V',32, struct pcs_ioc_init_kdirect) #define PCS_IOC_CSCONN _IOR('V',33
[Devel] [PATCH] fs/fuse kio: missed cleanup for interrupted shrink request
In the case when shrink request was interrupted we need cleanup di->size.op and resubmit pending read requests by analogy with this patch: "fs/fuse kio: missed clean di->size.op in failed shrink request" Also if the request has already gone to userspace, this request cannot be interrupted in order to avoid racing with request_end(). But it's still possible race with req->end callback, so let's also fix the wait condition. #VSTOR-19074 Signed-off-by: Pavel Butsykin --- fs/fuse/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 6fcbb117aa9c..dc21886ee55d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -517,6 +517,8 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) spin_unlock(>waitq.lock); __fuse_put_request(req); req->out.h.error = -EINTR; + if (req->end) + req->end(fc, req); return; } spin_unlock(>waitq.lock); @@ -526,7 +528,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) * Either request is already in userspace, or it was forced. * Wait it out. */ - wait_event(req->waitq, test_bit(FR_FINISHED, >flags)); + wait_event(req->waitq, test_bit(FR_FINISHED, >flags) && !req->end); } static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req, -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: satisfy pure FALLOC_FL_KEEP_SIZE immediately
Fallocate without mutex lock can race with setattr size request, as a result, may be various problems, including incorrectly changed file size. At the same time pure FALLOC_FL_KEEP_SIZE for vstorage is just nope, so we can immediately complete fallocate with mode == FALLOC_FL_KEEP_SIZE. Also move mutex_is_locked, since all other mode combinations either have to be under mutex or not valid. #VSTOR-19317 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index de54fedeb5e4..89866370a341 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -924,9 +924,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req, if (inarg->offset >= di->fileinfo.attr.size) inarg->mode &= ~FALLOC_FL_ZERO_RANGE; + if (inarg->mode == FALLOC_FL_KEEP_SIZE) + break; /* NOPE */ + + WARN_ON_ONCE(!mutex_is_locked(>inode.i_mutex)); if (inarg->mode & (FALLOC_FL_ZERO_RANGE|FALLOC_FL_PUNCH_HOLE)) { - WARN_ON_ONCE(!mutex_is_locked(>inode.i_mutex)); - if ((inarg->offset & (PAGE_SIZE - 1)) || (inarg->length & (PAGE_SIZE - 1))) { r->req.out.h.error = -EINVAL; goto error; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 1/2] fs/fuse kio: backport immediate-write attribute handle
This patch provides support PCS_FATTR_IMMEDIATE_WRITE attribute for KIO module. #VSTOR-19324 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_cs.c | 3 ++- fs/fuse/kio/pcs/pcs_prot_types.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c index 00cd1ae99850..1a2e64270b9e 100644 --- a/fs/fuse/kio/pcs/pcs_cs.c +++ b/fs/fuse/kio/pcs/pcs_cs.c @@ -515,7 +515,8 @@ void pcs_cs_submit(struct pcs_cs *cs, struct pcs_int_request *ireq) ioh->hdr.type = PCS_CS_READ_REQ; break; case PCS_REQ_T_WRITE: - ioh->hdr.type = PCS_CS_WRITE_REQ; + ioh->hdr.type = (ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) ? + PCS_CS_WRITE_SYNC_REQ : PCS_CS_WRITE_REQ; ioh->hdr.len += ireq->iochunk.size; break; case PCS_REQ_T_WRITE_HOLE: diff --git a/fs/fuse/kio/pcs/pcs_prot_types.h b/fs/fuse/kio/pcs/pcs_prot_types.h index 9db4516824aa..bba1f1dc76e3 100644 --- a/fs/fuse/kio/pcs/pcs_prot_types.h +++ b/fs/fuse/kio/pcs/pcs_prot_types.h @@ -417,6 +417,9 @@ enum /* Don't cache content on the client */ PCS_FATTR_NO_CLNT_CACHE = 0x1000, + /* Disable delayed writes for files in the directory */ + PCS_FATTR_IMMEDIATE_WRITE = 0x4000, + /* The following attributes are being inherited from the parent directory */ PCS_FATTR_INHERITABLE_MASK = 0xff00, }; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/2] fs/fuse kio: add support PCS_CS_IO_SYNC flag
In case PCS_FATTR_IMMEDIATE_WRITE attribute is set, all write operations must be synchronous, although now it's not and there is only PCS_CS_WRITE_SYNC_REQ for PCS_REQ_T_WRITE. Adding PCS_CS_IO_SYNC flag makes it possible to handle any write request synchronously. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_cs.c | 3 +++ fs/fuse/kio/pcs/pcs_cs_prot.h | 4 2 files changed, 7 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c index 1a2e64270b9e..60e2dc545cc5 100644 --- a/fs/fuse/kio/pcs/pcs_cs.c +++ b/fs/fuse/kio/pcs/pcs_cs.c @@ -541,6 +541,9 @@ void pcs_cs_submit(struct pcs_cs *cs, struct pcs_int_request *ireq) if (ireq->flags & IREQ_F_SEQ) ioh->sync.misc = PCS_CS_IO_SEQ; + if (ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) + ioh->sync.misc |= PCS_CS_IO_SYNC; + msg->size = ioh->hdr.len; msg->rpc = NULL; pcs_clear_error(>error); diff --git a/fs/fuse/kio/pcs/pcs_cs_prot.h b/fs/fuse/kio/pcs/pcs_cs_prot.h index 7de7dd1bea6b..8ca6cbabf741 100644 --- a/fs/fuse/kio/pcs/pcs_cs_prot.h +++ b/fs/fuse/kio/pcs/pcs_cs_prot.h @@ -24,6 +24,10 @@ struct pcs_cs_sync_data */ #define PCS_CS_IO_CACHED (1ULL<<63) /* Resp: result is read from cache or written ahead to journal */ #define PCS_CS_IO_SEQ (1ULL<<62) /* Req: request is part of sequential flow */ +#define PCS_CS_IO_SYNC (1ULL<<60) /* Req: Write operations will be performed synchronously. +* This means that at the req completion time, the output +* data will be transferred to disk. +*/ #define PCS_CS_RESET_TS_RECV(sdata, ts)do { (sdata)->misc = ((u64)ts & 0xFULL); } while (0) #define PCS_CS_SET_TS_RECV(sdata, ts) do { (sdata)->misc = ((sdata)->misc & ~0xFULL) | ((u64)ts & 0xFULL); } while (0) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 0/2] backport immediate-write attribute for Fast-path
#VSTOR-19324 Pavel Butsykin (2): fs/fuse kio: backport immediate-write attribute handle fs/fuse kio: add support PCS_CS_IO_SYNC flag fs/fuse/kio/pcs/pcs_cs.c | 6 +- fs/fuse/kio/pcs/pcs_cs_prot.h| 4 fs/fuse/kio/pcs/pcs_prot_types.h | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse kio: satisfy pure FALLOC_FL_KEEP_SIZE immediately
On 25.12.2018 12:28, Kirill Tkhai wrote: > On 24.12.2018 15:54, Pavel Butsykin wrote: >> Fallocate without mutex lock can race with setattr size request, as a result, >> may be various problems, including incorrectly changed file size. At the same >> time pure FALLOC_FL_KEEP_SIZE for vstorage is just nope, so we can >> immediately > > man 2 fallocate: > >"Specifying the FALLOC_FL_ZERO_RANGE flag (available since Linux 3.15) in > mode zeros space in the byte range starting at offset and > continuing for len bytes. Within the specified range, blocks are > preallocated for the regions that span the holes in the file. > After a successful call, subsequent reads from this range will return > zeros". Yes, FALLOC_FL_ZERO_RANGE | FALLOC_FL_ZERO_RANGE mode combinations should always be under mutex, so we can just move my check before: if (inarg->offset >= di->fileinfo.attr.size) inarg->mode &= ~FALLOC_FL_ZERO_RANGE; > So, this patch makes pcs_fuse_kdirect() complete a request without error > and without content changing, while userspace thinks the range was zeroed. > It's wrong. > >> complete fallocate with mode == FALLOC_FL_KEEP_SIZE. Also move >> mutex_is_locked, >> since all other mode combinations either have to be under mutex or not valid. >> >> #VSTOR-19317 >> >> Signed-off-by: Pavel Butsykin >> --- >> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 6 -- >> 1 file changed, 4 insertions(+), 2 deletions(-) >> >> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> index de54fedeb5e4..89866370a341 100644 >> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> @@ -924,9 +924,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster >> *pfc, struct fuse_req *req, >> if (inarg->offset >= di->fileinfo.attr.size) >> inarg->mode &= ~FALLOC_FL_ZERO_RANGE; >> >> +if (inarg->mode == FALLOC_FL_KEEP_SIZE) >> +break; /* NOPE */ > > This is untidy to add new branch, which makes further "if (inarg->mode & > FALLOC_FL_KEEP_SIZE)" > check a dead code. Why? mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE won't pass my check, but will pass the check "if (inarg->mode & FALLOC_FL_KEEP_SIZE)", it's not a dead code. >> + >> +WARN_ON_ONCE(!mutex_is_locked(>inode.i_mutex)); >> if (inarg->mode & (FALLOC_FL_ZERO_RANGE|FALLOC_FL_PUNCH_HOLE)) { >> -WARN_ON_ONCE(!mutex_is_locked(>inode.i_mutex)); >> - >> if ((inarg->offset & (PAGE_SIZE - 1)) || (inarg->length >> & (PAGE_SIZE - 1))) { >> r->req.out.h.error = -EINVAL; >> goto error; >> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse kio: satisfy pure FALLOC_FL_KEEP_SIZE immediately
On 25.12.2018 12:28, Kirill Tkhai wrote: > On 24.12.2018 15:54, Pavel Butsykin wrote: >> Fallocate without mutex lock can race with setattr size request, as a result, >> may be various problems, including incorrectly changed file size. At the same >> time pure FALLOC_FL_KEEP_SIZE for vstorage is just nope, so we can >> immediately > > man 2 fallocate: > >"Specifying the FALLOC_FL_ZERO_RANGE flag (available since Linux 3.15) in > mode zeros space in the byte range starting at offset and > continuing for len bytes. Within the specified range, blocks are > preallocated for the regions that span the holes in the file. > After a successful call, subsequent reads from this range will return > zeros". > > So, this patch makes pcs_fuse_kdirect() complete a request without error > and without content changing, while userspace thinks the range was zeroed. > It's wrong. I don't quite understand what case you're considering, which breaks after my patch. fallocate with mode = FALLOC_FL_KEEP_SIZE|FALLOC_FL_ZERO_RANGE and offset > file_size, should have no effect on the file. >> complete fallocate with mode == FALLOC_FL_KEEP_SIZE. Also move >> mutex_is_locked, >> since all other mode combinations either have to be under mutex or not valid. >> >> #VSTOR-19317 >> >> Signed-off-by: Pavel Butsykin >> --- >> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 6 -- >> 1 file changed, 4 insertions(+), 2 deletions(-) >> >> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> index de54fedeb5e4..89866370a341 100644 >> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> @@ -924,9 +924,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster >> *pfc, struct fuse_req *req, >> if (inarg->offset >= di->fileinfo.attr.size) >> inarg->mode &= ~FALLOC_FL_ZERO_RANGE; >> >> +if (inarg->mode == FALLOC_FL_KEEP_SIZE) >> +break; /* NOPE */ > > This is untidy to add new branch, which makes further "if (inarg->mode & > FALLOC_FL_KEEP_SIZE)" > check a dead code. > >> + >> +WARN_ON_ONCE(!mutex_is_locked(>inode.i_mutex)); >> if (inarg->mode & (FALLOC_FL_ZERO_RANGE|FALLOC_FL_PUNCH_HOLE)) { >> -WARN_ON_ONCE(!mutex_is_locked(>inode.i_mutex)); >> - >> if ((inarg->offset & (PAGE_SIZE - 1)) || (inarg->length >> & (PAGE_SIZE - 1))) { >> r->req.out.h.error = -EINVAL; >> goto error; >> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse kio: deny unavailable ioctl's in kio
pls ignore this. On 25.12.2018 18:11, Pavel Butsykin wrote: > There are some ioctl's that were made to service the kio module, and they > should not be available to user app. > > Also there are two ioctls PCS_IOC_NOCSUMONREAD and PCS_IOC_NOWRITEDELAY that > must be handled in kio, otherwise they are meaningless. So let's return > -EOPNOTSUPP unless we implement them in kio. > > #VSTOR-19332 > > Signed-off-by: Pavel Butsykin > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 19 --- > fs/fuse/kio/pcs/pcs_ioctl.h| 5 + > 2 files changed, 21 insertions(+), 3 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index 89866370a341..13acd2e172f3 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -1110,9 +1110,22 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, > struct fuse_req *req, bool > case FUSE_IOCTL: { > struct fuse_ioctl_in const *inarg = req->in.args[0].value; > > - if (inarg->cmd != FS_IOC_FIEMAP) > - return 1; > - > + switch (inarg->cmd) { > + case FS_IOC_FIEMAP: > + break; > + case PCS_IOC_NOCSUMONREAD: > + case PCS_IOC_NOWRITEDELAY: > + return -EOPNOTSUPP; > + case PCS_IOC_INIT_KDIRECT: > + case PCS_IOC_CSCONN: > + case PCS_IOC_GETFILEINFO: > + case PCS_IOC_KDIRECT_CLAIM: > + case PCS_IOC_KDIRECT_RELEASE: > + case PCS_IOC_GETMAP: > + return -EPERM; > + default: > + return 1; > + } > break; > } > default: > diff --git a/fs/fuse/kio/pcs/pcs_ioctl.h b/fs/fuse/kio/pcs/pcs_ioctl.h > index 5cf40e35f881..d6c02ae66977 100644 > --- a/fs/fuse/kio/pcs/pcs_ioctl.h > +++ b/fs/fuse/kio/pcs/pcs_ioctl.h > @@ -78,6 +78,11 @@ struct pcs_ioc_csconn > #define PCS_IOC_CS_REOPEN (PCS_IOC_CS_OPEN|PCS_IOC_CS_CLOSE) > }; > > +#define PCS_IOC_NOCSUMONREAD _IOW('V',3,u32) > +# define PCS_IOC_NOCSUMONREAD_DATA 1 > +# define PCS_IOC_NOCSUMONREAD_METADATA 2 > +#define PCS_IOC_NOWRITEDELAY _IOW('V',4,u32) > + > #define PCS_IOC_INIT_KDIRECT_IOR('V',32, struct > pcs_ioc_init_kdirect) > #define PCS_IOC_CSCONN _IOR('V',33, struct pcs_ioc_csconn) > #define PCS_IOC_GETFILEINFO _IOR('V',34, struct pcs_ioc_fileinfo) > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: deny unavailable ioctl's in kio
There are some ioctl's that were made to service the kio module, and they should not be available to user app. Also there are two ioctls PCS_IOC_NOCSUMONREAD and PCS_IOC_NOWRITEDELAY that must be handled in kio, otherwise they are meaningless. So let's return -EOPNOTSUPP unless we implement them in kio. #VSTOR-19332 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 19 --- fs/fuse/kio/pcs/pcs_ioctl.h| 5 + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 89866370a341..13acd2e172f3 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -1110,9 +1110,22 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, struct fuse_req *req, bool case FUSE_IOCTL: { struct fuse_ioctl_in const *inarg = req->in.args[0].value; - if (inarg->cmd != FS_IOC_FIEMAP) - return 1; - + switch (inarg->cmd) { + case FS_IOC_FIEMAP: + break; + case PCS_IOC_NOCSUMONREAD: + case PCS_IOC_NOWRITEDELAY: + return -EOPNOTSUPP; + case PCS_IOC_INIT_KDIRECT: + case PCS_IOC_CSCONN: + case PCS_IOC_GETFILEINFO: + case PCS_IOC_KDIRECT_CLAIM: + case PCS_IOC_KDIRECT_RELEASE: + case PCS_IOC_GETMAP: + return -EPERM; + default: + return 1; + } break; } default: diff --git a/fs/fuse/kio/pcs/pcs_ioctl.h b/fs/fuse/kio/pcs/pcs_ioctl.h index 5cf40e35f881..d6c02ae66977 100644 --- a/fs/fuse/kio/pcs/pcs_ioctl.h +++ b/fs/fuse/kio/pcs/pcs_ioctl.h @@ -78,6 +78,11 @@ struct pcs_ioc_csconn #define PCS_IOC_CS_REOPEN (PCS_IOC_CS_OPEN|PCS_IOC_CS_CLOSE) }; +#define PCS_IOC_NOCSUMONREAD _IOW('V',3,u32) +# define PCS_IOC_NOCSUMONREAD_DATA 1 +# define PCS_IOC_NOCSUMONREAD_METADATA 2 +#define PCS_IOC_NOWRITEDELAY _IOW('V',4,u32) + #define PCS_IOC_INIT_KDIRECT _IOR('V',32, struct pcs_ioc_init_kdirect) #define PCS_IOC_CSCONN _IOR('V',33, struct pcs_ioc_csconn) #define PCS_IOC_GETFILEINFO_IOR('V',34, struct pcs_ioc_fileinfo) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 0/3] Fuse KIO: clanup fuse ktrace messages
ping On 05.12.2018 21:03, Pavel Butsykin wrote: > #VSTOR-18383 > > Pavel Butsykin (3): >fs/fuse kio: bring fuse ktraces to a common view >fs/fuse kio: disable duplication FUSE_K* messages to debugfs by > default >fs/fuse kio: make it possible to enable TRACE/DTRACE in the release > kernel > > fs/fuse/kio/pcs/fuse_ktrace.h | 6 ++ > fs/fuse/kio/pcs/log.h | 10 +++--- > fs/fuse/kio/pcs/pcs_cs.c | 2 +- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 14 ++ > fs/fuse/kio/pcs/pcs_map.c | 2 +- > fs/fuse/kio/pcs/pcs_req.c | 2 +- > fs/fuse/kio/pcs/pcs_rpc.c | 10 +- > 7 files changed, 27 insertions(+), 19 deletions(-) > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: missed clean di->size.op in failed shrink request
The state di->size.op is set to PCS_SIZE_SHRINK in order to postpone all read requests during shrink request execution. But, if the shrink request fails in __fuse_request_send(), then di->size.op is never cleaned up and it remains PCS_SIZE_SHRINK forever, and pending read requests can remain hanging indefinitely. To fix this we can reuse req->end that actually _pcs_shrink_end() which already has everything we need to cleanup shrink request. There is no need to make a similar fix for ms since req->end callback is no where used for sync(no background) requests except kio. #VSTOR-18947 Signed-off-by: Pavel Butsykin --- fs/fuse/dev.c | 4 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ce75d218025b..6fcbb117aa9c 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -543,9 +543,13 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req, if (!fiq->connected) { spin_unlock(>waitq.lock); req->out.h.error = -ENOTCONN; + if (req->end) + req->end(fc, req); } else if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state)) { spin_unlock(>waitq.lock); req->out.h.error = -EIO; + if (req->end) + req->end(fc, req); } else { req->in.h.unique = fuse_get_unique(fiq); queue_request(fiq, req); diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 3b1d819792b2..de54fedeb5e4 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -992,8 +992,9 @@ static void kpcs_setattr_end(struct fuse_conn *fc, struct fuse_req *req) u64 old_size; BUG_ON(req->in.h.opcode != FUSE_SETATTR); - TRACE("update size: ino:%lu old_sz:%lld new:%lld\n", - req->io_inode->i_ino, di->fileinfo.attr.size, outarg->attr.size); + TRACE("update size: ino:%lu old_sz:%lld new:%lld, error: %d\n", + req->io_inode->i_ino, di->fileinfo.attr.size, outarg->attr.size, + req->out.h.error); if (req->out.h.error) goto fail; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] kio_pcs: Compact the logs and make eyes happy
On 04.12.2018 23:13, Pavel Emelianov wrote: > On 12/04/2018 10:28 PM, Pavel Emelyanov wrote: >> On 12/03/2018 05:20 PM, Pavel Butsykin wrote: >>> On 30.11.2018 19:44, Pavel Emelianov wrote: >>>> On 11/30/2018 05:57 PM, Pavel Butsykin wrote: >>>>> Hmm, __kfuse_trace() duplicates message to debugfs trace, without '\n' >>>> >>>> Yes, and AFAIS most of the existing messages already come w/o it. >>> >>> More likely logs without '\n' are present mainly for error cases, >>> perhaps this is why it wasn't noticed before. But yes, we have a mess >>> with logs. >>> >>> I propose to fix all FUSE_K* traces with '\n' and use >>> trace_printk("%s\n") for duplicating messages to debugsfs. But >>> duplicating messages to debugfs should be turned off by default (with >>> the ability to enable via sysfs), because write messages to debugfs >>> without user's permission.. it's looks a little impolite :) >> >> The issue is not in duplicating messages, but in \n creeping into >> user-space logs. But anyway, OK, equipping them all with \n-s sounds >> OK to me. > > Not any more. Please, look at this PR: > https://git.acronis.com/projects/STRG/repos/pstorage-core/pull-requests/765 > The proposal is to drop the LOG_NONL thing from textual logs. If done, then > messages coming with \n at the end will have double \n-s in text logs. Actually, we don't need to worry about merged messages in debugs, because __trace_puts() adds \n if it necessary: int __trace_puts(unsigned long ip, const char *str, int size) ... /* Add a newline if necessary */ if (entry->buf[size - 1] != '\n') { entry->buf[size] = '\n'; entry->buf[size + 1] = '\0'; } else entry->buf[size] = '\0'; I missed it in the beginning, sorry for that. Along with this, we can allow drop LOG_NONL options from usermode and this patch is OK for me, except for a small correction: void __kfuse_trace(struct fuse_conn * fc, unsigned long ip, const char * fmt, ...) ... - pr_debug("%s", buf); + pr_debug("%s\n", buf); >>>>> this messages will look weird. We need to fix __kfuse_trace() by adding >>>>> concatenation '\n' (or even drop duplication messages to debugsfs/dmesg, >>>>> as not a very useful thing). >>>>> >>>>> On 30.11.2018 17:35, Pavel Butsykin wrote: >>>>>> Would you like to fix all FUSE_KTRACE's in the kernel? I see a few more >>>>>> FUSE_KTRACE with '\n'. >>>>>> >>>>>> On 30.11.2018 17:23, Pavel Emelianov wrote: >>>>>>> After a recent (b)log (re)work it was noticed that some extra \n-s crept >>>>>>> into the classical log files. Indeed, the pstorage TRACE() call appends >>>>>>> a >>>>>>> \n at the end of each message and so does the kernel code. >>>>>>> >>>>>>> Sorry for inconvenience. >>>>>>> >>>>>>> https://pmc.acronis.com/browse/VSTOR-18383 >>>>>>> >>>>>>> Signed-off-by: Pavel Emelyanov >>>>>>> >>>>>>> --- >>>>>>> >>>>>>> diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c >>>>>>> index 4596454..34fa88c 100644 >>>>>>> --- a/fs/fuse/kio/pcs/pcs_map.c >>>>>>> +++ b/fs/fuse/kio/pcs/pcs_map.c >>>>>>> @@ -1946,7 +1946,7 @@ static int pcs_cslist_submit_read(struct >>>>>>> pcs_int_request *ireq, struct pcs_cs_li >>>>>>> WRITE_ONCE(csl->read_index, i); >>>>>>> WRITE_ONCE(csl->select_stamp, jiffies); >>>>>>> >>>>>>> - FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT >>>>>>> " to CS" NODE_FMT "; is_seq=%d\n", MAP_ARGS(ireq->iochunk.map), >>>>>>> + FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT >>>>>>> " to CS" NODE_FMT "; is_seq=%d", MAP_ARGS(ireq->iochunk.map), >>>>>>> NODE_ARGS(csl->cs[i].cslink.cs->id), is_seq); >>>>>>> pcs_flow_bind_cs(ireq->iochunk.flow, >>>>>>> csl->cs[i].cslink.cs); >>>>>>> } >>>>>>> >>>>>> >>>>>> ___ >>>>>> Devel mailing list >>>>>> Devel@openvz.org >>>>>> https://lists.openvz.org/mailman/listinfo/devel >>>>>> >>>> >> > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/3] fs/fuse kio: fix sreq and msg leak in prepare_map_flush_ireq()
Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_map.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 4bd18c5224ab..1e700dff2043 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -3016,6 +3016,8 @@ static int prepare_map_flush_ireq(struct pcs_map_entry *m, cslist_put(cslist); if (!valid_for_flush(m, timer_sync) || m->cs_list != cslist) { spin_unlock(>lock); + pcs_free_msg(msg); + ireq_destroy(sreq); return 0; } prepare_map_flush_msg(m, sreq, msg); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 1/3] fs/fuse kio: fix loss of FUSE_FSYNC/FUSE_FLUSH reqs
sorry, Not there XD pls, don't ignore this. On 03.12.2018 16:04, Pavel Butsykin wrote: > pls ignore this. > > On 03.12.2018 16:02, Pavel Butsykin wrote: >> Fast-Path can loss fsync/flush requests, because PCS_REQ_T_SYNC >> request set up >> PCS_MAP_FLUSHING flag, but never cleans it. Although initially >> PCS_MAP_FLUSHING >> flag was created for sync timer, so PCS_REQ_T_SYNC request should ignore >> everything related to PCS_REQ_T_SYNC flag. >> >> This patch adds timer_sync flag in prepare_map_flush_ireq() to ignore >> all sync >> timer stuff on PCS_REQ_T_SYNC way. >> >> Signed-off-by: Pavel Butsykin >> --- >> fs/fuse/kio/pcs/pcs_map.c | 27 --- >> 1 file changed, 16 insertions(+), 11 deletions(-) >> >> diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c >> index 459645417462..4bd18c5224ab 100644 >> --- a/fs/fuse/kio/pcs/pcs_map.c >> +++ b/fs/fuse/kio/pcs/pcs_map.c >> @@ -2959,20 +2959,24 @@ static void prepare_map_flush_msg(struct >> pcs_map_entry * m, struct pcs_int_reque >> msg->done = sync_done; >> } >> -static bool valid_for_flush(struct pcs_map_entry *m) >> +static bool valid_for_flush(struct pcs_map_entry *m, bool timer_sync) >> { >> - if (m->state & PCS_MAP_DEAD) >> - return false; >> + if (timer_sync) { >> + if (m->state & PCS_MAP_DEAD) >> + return false; >> + if (m->flags & PCS_MAP_FLUSHING) >> + return false; >> + } >> if (!(m->flags & PCS_MAP_DIRTY)) >> return false; >> - if (m->flags & PCS_MAP_FLUSHING) >> - return false; >> return true; >> } >> -static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct >> pcs_int_request **sreqp) >> +static int prepare_map_flush_ireq(struct pcs_map_entry *m, >> + struct pcs_int_request **sreqp, >> + bool timer_sync) >> { >> struct pcs_dentry_info *de; >> struct pcs_cs_list *cslist; >> @@ -2980,7 +2984,7 @@ static int prepare_map_flush_ireq(struct >> pcs_map_entry *m, struct pcs_int_reques >> struct pcs_msg * msg; >> spin_lock(>lock); >> - if (!valid_for_flush(m)) { >> + if (!valid_for_flush(m, timer_sync)) { >> spin_unlock(>lock); >> return 0; >> } >> @@ -3010,7 +3014,7 @@ static int prepare_map_flush_ireq(struct >> pcs_map_entry *m, struct pcs_int_reques >> /* All resources allocated, we need to recheck maps state again */ >> spin_lock(>lock); >> cslist_put(cslist); >> - if (!valid_for_flush(m) || m->cs_list != cslist) { >> + if (!valid_for_flush(m, timer_sync) || m->cs_list != cslist) { >> spin_unlock(>lock); >> return 0; >> } >> @@ -3025,7 +3029,8 @@ static int prepare_map_flush_ireq(struct >> pcs_map_entry *m, struct pcs_int_reques >> sreq->complete_cb = pcs_flushreq_complete; >> sreq->flushreq.msg = msg; >> FUSE_KTRACE(sreq->cc->fc, "timed FLUSH " MAP_FMT, MAP_ARGS(m)); >> - m->flags |= PCS_MAP_FLUSHING; >> + if (timer_sync) >> + m->flags |= PCS_MAP_FLUSHING; >> __pcs_map_get(m); >> spin_unlock(>lock); >> *sreqp = sreq; >> @@ -3047,7 +3052,7 @@ static void sync_timer_work(struct work_struct *w) >> struct pcs_int_request * sreq = NULL; >> int err; >> - err = prepare_map_flush_ireq(m, ); >> + err = prepare_map_flush_ireq(m, , true); >> if (err) { >> spin_lock(>lock); >> if (!(m->state & PCS_MAP_DEAD)) >> @@ -3125,7 +3130,7 @@ void map_inject_flush_req(struct pcs_int_request >> *ireq) >> break; >> if (!maps[i]) >> continue; >> - err = prepare_map_flush_ireq(maps[i], ); >> + err = prepare_map_flush_ireq(maps[i], , false); >> pcs_map_put(maps[i]); >> if (err) { >> pcs_set_local_error(>error, PCS_ERR_NOMEM); >> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 1/3] fs/fuse kio: fix loss of FUSE_FSYNC/FUSE_FLUSH reqs
pls ignore this. On 03.12.2018 16:02, Pavel Butsykin wrote: > Fast-Path can loss fsync/flush requests, because PCS_REQ_T_SYNC request set up > PCS_MAP_FLUSHING flag, but never cleans it. Although initially > PCS_MAP_FLUSHING > flag was created for sync timer, so PCS_REQ_T_SYNC request should ignore > everything related to PCS_REQ_T_SYNC flag. > > This patch adds timer_sync flag in prepare_map_flush_ireq() to ignore all sync > timer stuff on PCS_REQ_T_SYNC way. > > Signed-off-by: Pavel Butsykin > --- > fs/fuse/kio/pcs/pcs_map.c | 27 --- > 1 file changed, 16 insertions(+), 11 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c > index 459645417462..4bd18c5224ab 100644 > --- a/fs/fuse/kio/pcs/pcs_map.c > +++ b/fs/fuse/kio/pcs/pcs_map.c > @@ -2959,20 +2959,24 @@ static void prepare_map_flush_msg(struct > pcs_map_entry * m, struct pcs_int_reque > msg->done = sync_done; > } > > -static bool valid_for_flush(struct pcs_map_entry *m) > +static bool valid_for_flush(struct pcs_map_entry *m, bool timer_sync) > { > - if (m->state & PCS_MAP_DEAD) > - return false; > + if (timer_sync) { > + if (m->state & PCS_MAP_DEAD) > + return false; > > + if (m->flags & PCS_MAP_FLUSHING) > + return false; > + } > if (!(m->flags & PCS_MAP_DIRTY)) > return false; > - if (m->flags & PCS_MAP_FLUSHING) > - return false; > > return true; > } > > -static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct > pcs_int_request **sreqp) > +static int prepare_map_flush_ireq(struct pcs_map_entry *m, > + struct pcs_int_request **sreqp, > + bool timer_sync) > { > struct pcs_dentry_info *de; > struct pcs_cs_list *cslist; > @@ -2980,7 +2984,7 @@ static int prepare_map_flush_ireq(struct pcs_map_entry > *m, struct pcs_int_reques > struct pcs_msg * msg; > > spin_lock(>lock); > - if (!valid_for_flush(m)) { > + if (!valid_for_flush(m, timer_sync)) { > spin_unlock(>lock); > return 0; > } > @@ -3010,7 +3014,7 @@ static int prepare_map_flush_ireq(struct pcs_map_entry > *m, struct pcs_int_reques > /* All resources allocated, we need to recheck maps state again */ > spin_lock(>lock); > cslist_put(cslist); > - if (!valid_for_flush(m) || m->cs_list != cslist) { > + if (!valid_for_flush(m, timer_sync) || m->cs_list != cslist) { > spin_unlock(>lock); > return 0; > } > @@ -3025,7 +3029,8 @@ static int prepare_map_flush_ireq(struct pcs_map_entry > *m, struct pcs_int_reques > sreq->complete_cb = pcs_flushreq_complete; > sreq->flushreq.msg = msg; > FUSE_KTRACE(sreq->cc->fc, "timed FLUSH " MAP_FMT, MAP_ARGS(m)); > - m->flags |= PCS_MAP_FLUSHING; > + if (timer_sync) > + m->flags |= PCS_MAP_FLUSHING; > __pcs_map_get(m); > spin_unlock(>lock); > *sreqp = sreq; > @@ -3047,7 +3052,7 @@ static void sync_timer_work(struct work_struct *w) > struct pcs_int_request * sreq = NULL; > int err; > > - err = prepare_map_flush_ireq(m, ); > + err = prepare_map_flush_ireq(m, , true); > if (err) { > spin_lock(>lock); > if (!(m->state & PCS_MAP_DEAD)) > @@ -3125,7 +3130,7 @@ void map_inject_flush_req(struct pcs_int_request *ireq) > break; > if (!maps[i]) > continue; > - err = prepare_map_flush_ireq(maps[i], ); > + err = prepare_map_flush_ireq(maps[i], , false); > pcs_map_put(maps[i]); > if (err) { > pcs_set_local_error(>error, > PCS_ERR_NOMEM); > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] kio_pcs: Compact the logs and make eyes happy
On 30.11.2018 19:44, Pavel Emelianov wrote: > On 11/30/2018 05:57 PM, Pavel Butsykin wrote: >> Hmm, __kfuse_trace() duplicates message to debugfs trace, without '\n' > > Yes, and AFAIS most of the existing messages already come w/o it. More likely logs without '\n' are present mainly for error cases, perhaps this is why it wasn't noticed before. But yes, we have a mess with logs. I propose to fix all FUSE_K* traces with '\n' and use trace_printk("%s\n") for duplicating messages to debugsfs. But duplicating messages to debugfs should be turned off by default (with the ability to enable via sysfs), because write messages to debugfs without user's permission.. it's looks a little impolite :) >> this messages will look weird. We need to fix __kfuse_trace() by adding >> concatenation '\n' (or even drop duplication messages to debugsfs/dmesg, >> as not a very useful thing). >> >> On 30.11.2018 17:35, Pavel Butsykin wrote: >>> Would you like to fix all FUSE_KTRACE's in the kernel? I see a few more >>> FUSE_KTRACE with '\n'. >>> >>> On 30.11.2018 17:23, Pavel Emelianov wrote: >>>> After a recent (b)log (re)work it was noticed that some extra \n-s crept >>>> into the classical log files. Indeed, the pstorage TRACE() call appends a >>>> \n at the end of each message and so does the kernel code. >>>> >>>> Sorry for inconvenience. >>>> >>>> https://pmc.acronis.com/browse/VSTOR-18383 >>>> >>>> Signed-off-by: Pavel Emelyanov >>>> >>>> --- >>>> >>>> diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c >>>> index 4596454..34fa88c 100644 >>>> --- a/fs/fuse/kio/pcs/pcs_map.c >>>> +++ b/fs/fuse/kio/pcs/pcs_map.c >>>> @@ -1946,7 +1946,7 @@ static int pcs_cslist_submit_read(struct >>>> pcs_int_request *ireq, struct pcs_cs_li >>>>WRITE_ONCE(csl->read_index, i); >>>>WRITE_ONCE(csl->select_stamp, jiffies); >>>> >>>> - FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT " to CS" >>>> NODE_FMT "; is_seq=%d\n", MAP_ARGS(ireq->iochunk.map), >>>> + FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT " to CS" >>>> NODE_FMT "; is_seq=%d", MAP_ARGS(ireq->iochunk.map), >>>> NODE_ARGS(csl->cs[i].cslink.cs->id), is_seq); >>>>pcs_flow_bind_cs(ireq->iochunk.flow, >>>> csl->cs[i].cslink.cs); >>>>} >>>> >>> >>> ___ >>> Devel mailing list >>> Devel@openvz.org >>> https://lists.openvz.org/mailman/listinfo/devel >>> > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 1/3] fs/fuse kio: fix loss of FUSE_FSYNC/FUSE_FLUSH reqs
Fast-Path can loss fsync/flush requests, because PCS_REQ_T_SYNC request set up PCS_MAP_FLUSHING flag, but never cleans it. Although initially PCS_MAP_FLUSHING flag was created for sync timer, so PCS_REQ_T_SYNC request should ignore everything related to PCS_REQ_T_SYNC flag. This patch adds timer_sync flag in prepare_map_flush_ireq() to ignore all sync timer stuff on PCS_REQ_T_SYNC way. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_map.c | 27 --- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 459645417462..4bd18c5224ab 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -2959,20 +2959,24 @@ static void prepare_map_flush_msg(struct pcs_map_entry * m, struct pcs_int_reque msg->done = sync_done; } -static bool valid_for_flush(struct pcs_map_entry *m) +static bool valid_for_flush(struct pcs_map_entry *m, bool timer_sync) { - if (m->state & PCS_MAP_DEAD) - return false; + if (timer_sync) { + if (m->state & PCS_MAP_DEAD) + return false; + if (m->flags & PCS_MAP_FLUSHING) + return false; + } if (!(m->flags & PCS_MAP_DIRTY)) return false; - if (m->flags & PCS_MAP_FLUSHING) - return false; return true; } -static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_request **sreqp) +static int prepare_map_flush_ireq(struct pcs_map_entry *m, + struct pcs_int_request **sreqp, + bool timer_sync) { struct pcs_dentry_info *de; struct pcs_cs_list *cslist; @@ -2980,7 +2984,7 @@ static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_reques struct pcs_msg * msg; spin_lock(>lock); - if (!valid_for_flush(m)) { + if (!valid_for_flush(m, timer_sync)) { spin_unlock(>lock); return 0; } @@ -3010,7 +3014,7 @@ static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_reques /* All resources allocated, we need to recheck maps state again */ spin_lock(>lock); cslist_put(cslist); - if (!valid_for_flush(m) || m->cs_list != cslist) { + if (!valid_for_flush(m, timer_sync) || m->cs_list != cslist) { spin_unlock(>lock); return 0; } @@ -3025,7 +3029,8 @@ static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_reques sreq->complete_cb = pcs_flushreq_complete; sreq->flushreq.msg = msg; FUSE_KTRACE(sreq->cc->fc, "timed FLUSH " MAP_FMT, MAP_ARGS(m)); - m->flags |= PCS_MAP_FLUSHING; + if (timer_sync) + m->flags |= PCS_MAP_FLUSHING; __pcs_map_get(m); spin_unlock(>lock); *sreqp = sreq; @@ -3047,7 +3052,7 @@ static void sync_timer_work(struct work_struct *w) struct pcs_int_request * sreq = NULL; int err; - err = prepare_map_flush_ireq(m, ); + err = prepare_map_flush_ireq(m, , true); if (err) { spin_lock(>lock); if (!(m->state & PCS_MAP_DEAD)) @@ -3125,7 +3130,7 @@ void map_inject_flush_req(struct pcs_int_request *ireq) break; if (!maps[i]) continue; - err = prepare_map_flush_ireq(maps[i], ); + err = prepare_map_flush_ireq(maps[i], , false); pcs_map_put(maps[i]); if (err) { pcs_set_local_error(>error, PCS_ERR_NOMEM); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 3/3] fs/fuse kio: retry allocation PCS_IREQ_FLUSH request
If cslist has changed during request allocation, that is no reason not to run PCS_IREQ_FLUSH. In the case when cslist has changed let's re-allocate the request with new cslist and try it again to fix possible loss of fsync/flush request. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_map.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 1e700dff2043..817c7d6a9379 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -2983,6 +2983,7 @@ static int prepare_map_flush_ireq(struct pcs_map_entry *m, struct pcs_int_request *sreq; struct pcs_msg * msg; +retry: spin_lock(>lock); if (!valid_for_flush(m, timer_sync)) { spin_unlock(>lock); @@ -2998,7 +2999,6 @@ static int prepare_map_flush_ireq(struct pcs_map_entry *m, cslist = m->cs_list; cslist_get(cslist); - /* TODO: Need to grab reference to de? */ de = pcs_dentry_from_map(m); spin_unlock(>lock); @@ -3014,7 +3014,13 @@ static int prepare_map_flush_ireq(struct pcs_map_entry *m, /* All resources allocated, we need to recheck maps state again */ spin_lock(>lock); cslist_put(cslist); - if (!valid_for_flush(m, timer_sync) || m->cs_list != cslist) { + if (unlikely(m->cs_list != cslist)) { + spin_unlock(>lock); + pcs_free_msg(msg); + ireq_destroy(sreq); + goto retry; + } + if (!valid_for_flush(m, timer_sync)) { spin_unlock(>lock); pcs_free_msg(msg); ireq_destroy(sreq); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 0/3] Fuse KIO: fix fsync/flush loss
#VSTOR-18475 Pavel Butsykin (3): fs/fuse kio: fix loss of FUSE_FSYNC/FUSE_FLUSH reqs fs/fuse kio: fix sreq and msg leak in prepare_map_flush_ireq() fs/fuse kio: retry allocation PCS_IREQ_FLUSH request fs/fuse/kio/pcs/pcs_map.c | 37 + 1 file changed, 25 insertions(+), 12 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] kio_pcs: Compact the logs and make eyes happy
Would you like to fix all FUSE_KTRACE's in the kernel? I see a few more FUSE_KTRACE with '\n'. On 30.11.2018 17:23, Pavel Emelianov wrote: > After a recent (b)log (re)work it was noticed that some extra \n-s crept > into the classical log files. Indeed, the pstorage TRACE() call appends a > \n at the end of each message and so does the kernel code. > > Sorry for inconvenience. > > https://pmc.acronis.com/browse/VSTOR-18383 > > Signed-off-by: Pavel Emelyanov > > --- > > diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c > index 4596454..34fa88c 100644 > --- a/fs/fuse/kio/pcs/pcs_map.c > +++ b/fs/fuse/kio/pcs/pcs_map.c > @@ -1946,7 +1946,7 @@ static int pcs_cslist_submit_read(struct > pcs_int_request *ireq, struct pcs_cs_li > WRITE_ONCE(csl->read_index, i); > WRITE_ONCE(csl->select_stamp, jiffies); > > - FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT " to CS" > NODE_FMT "; is_seq=%d\n", MAP_ARGS(ireq->iochunk.map), > + FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT " to CS" > NODE_FMT "; is_seq=%d", MAP_ARGS(ireq->iochunk.map), > NODE_ARGS(csl->cs[i].cslink.cs->id), is_seq); > pcs_flow_bind_cs(ireq->iochunk.flow, csl->cs[i].cslink.cs); > } > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 1/3] fs/fuse kio: bring fuse ktraces to a common view
Since the fuse client adds \n to each message and allows only a single message view, let's bring these to a common view and remove all \n in FUSE_K* messages. https://pmc.acronis.com/browse/VSTOR-18383 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_cs.c | 2 +- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 2 +- fs/fuse/kio/pcs/pcs_map.c | 2 +- fs/fuse/kio/pcs/pcs_req.c | 2 +- fs/fuse/kio/pcs/pcs_rpc.c | 10 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c index 8ed1c8f91d99..659f05327009 100644 --- a/fs/fuse/kio/pcs/pcs_cs.c +++ b/fs/fuse/kio/pcs/pcs_cs.c @@ -703,7 +703,7 @@ static int cs_input(struct pcs_rpc *ep, struct pcs_msg *msg) msg->done(msg); return 0; default: - FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Unsupported message type %u\n", h->type); + FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Unsupported message type %u", h->type); return PCS_ERR_PROTOCOL; } } diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 3940d6c255ba..7bedb7f95486 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -1475,7 +1475,7 @@ void __kfuse_trace(struct fuse_conn * fc, unsigned long ip, const char * fmt, .. if (ip) __trace_puts(ip, buf, len); else - pr_debug("%s", buf); + pr_debug("%s\n", buf); } put_cpu(); } diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index ec00cf238b1c..aafd130ace28 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -1934,7 +1934,7 @@ static int pcs_cslist_submit_read(struct pcs_int_request *ireq, struct pcs_cs_li WRITE_ONCE(csl->read_index, i); WRITE_ONCE(csl->select_stamp, jiffies); - FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT " to CS" NODE_FMT "; is_seq=%d\n", MAP_ARGS(ireq->iochunk.map), + FUSE_KTRACE(ireq->cc->fc, "Selected read map " MAP_FMT " to CS" NODE_FMT "; is_seq=%d", MAP_ARGS(ireq->iochunk.map), NODE_ARGS(csl->cs[i].cslink.cs->id), is_seq); pcs_flow_bind_cs(ireq->iochunk.flow, csl->cs[i].cslink.cs); } diff --git a/fs/fuse/kio/pcs/pcs_req.c b/fs/fuse/kio/pcs/pcs_req.c index f60ad025af59..d989027463e6 100644 --- a/fs/fuse/kio/pcs/pcs_req.c +++ b/fs/fuse/kio/pcs/pcs_req.c @@ -139,7 +139,7 @@ noinline void pcs_ireq_queue_fail(struct list_head *queue, int error) if (!(ireq->flags & IREQ_F_FATAL)) { pcs_clear_error(>error); - FUSE_KTRACE(ireq->cc->fc, "requeue truncate(%d) %llu@" DENTRY_FMT "\n", ireq->type, + FUSE_KTRACE(ireq->cc->fc, "requeue truncate(%d) %llu@" DENTRY_FMT, ireq->type, (unsigned long long)ireq->truncreq.offset, DENTRY_ARGS(ireq->dentry)); ireq_delay(ireq); diff --git a/fs/fuse/kio/pcs/pcs_rpc.c b/fs/fuse/kio/pcs/pcs_rpc.c index f6b8aefe6884..a34b204476bd 100644 --- a/fs/fuse/kio/pcs/pcs_rpc.c +++ b/fs/fuse/kio/pcs/pcs_rpc.c @@ -565,7 +565,7 @@ struct pcs_msg *rpc_get_hdr(struct pcs_sockio * sio, u32 *msg_size) /* Fatal stream format error */ if (h->len < sizeof(struct pcs_rpc_hdr) || h->len > ep->params.max_msg_size) { - FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Bad message header %u %u\n", h->len, h->type); + FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Bad message header %u %u", h->len, h->type); return NULL; } @@ -580,12 +580,12 @@ struct pcs_msg *rpc_get_hdr(struct pcs_sockio * sio, u32 *msg_size) next_input = rpc_work_input; break; default: - FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Received msg in bad state %u\n", ep->state); + FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Received msg in bad state %u", ep->state); return NULL; } if (h->len > PAGE_SIZE) { - FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Received too big msg %u\n", h->len); + FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Received too big msg %u", h->len); *msg_size = h->len; return PCS_TRASH_MSG; } @@ -615,7 +
[Devel] [PATCH 3/3] fs/fuse kio: make it possible to enable TRACE/DTRACE in the release kernel
Sometimes it can be very convenient to enable detailed tracing on the release kernel too. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/fuse_ktrace.h | 6 ++ fs/fuse/kio/pcs/log.h | 10 +++--- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/fuse/kio/pcs/fuse_ktrace.h b/fs/fuse/kio/pcs/fuse_ktrace.h index 1950b872ef4a..7cce9e26959a 100644 --- a/fs/fuse/kio/pcs/fuse_ktrace.h +++ b/fs/fuse/kio/pcs/fuse_ktrace.h @@ -4,6 +4,12 @@ #include "fuse_ktrace_prot.h" #include +#ifdef CONFIG_FUSE_KIO_DEBUG +#define DEBUGFS_TRACE 1 +#else +#define DEBUGFS_TRACE 0 +#endif /* CONFIG_FUSE_KIO_DEBUG */ + #define KTRACE_LOG_BUF_SIZE256 struct fuse_ktrace diff --git a/fs/fuse/kio/pcs/log.h b/fs/fuse/kio/pcs/log.h index a26ed08a557a..c77d9f3f8817 100644 --- a/fs/fuse/kio/pcs/log.h +++ b/fs/fuse/kio/pcs/log.h @@ -22,12 +22,8 @@ #define LOG_DTRACE LOG_DEBUG4 extern unsigned int pcs_loglevel; +extern unsigned int debugfs_tracing; -#ifdef CONFIG_FUSE_KIO_DEBUG -#define TRACE(fmt, args...)if (pcs_loglevel >= LOG_TRACE) trace_printk("%d: " fmt "\n", __LINE__, ## args) -#define DTRACE(fmt, args...) if (pcs_loglevel >= LOG_DTRACE) trace_printk("%d: " fmt "\n", __LINE__, ## args) -#else -#define TRACE(fmt, ...) do {} while (0) -#define DTRACE(fmt, ...) do {} while (0) -#endif /* CONFIG_FUSE_KIO_DEBUG */ +#define TRACE(fmt, args...)if (unlikely(debugfs_tracing && pcs_loglevel >= LOG_TRACE)) trace_printk("%d: " fmt "\n", __LINE__, ## args) +#define DTRACE(fmt, args...) if (unlikely(debugfs_tracing && pcs_loglevel >= LOG_DTRACE)) trace_printk("%d: " fmt "\n", __LINE__, ## args) #endif /* __PCSLOG_H__ */ diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index e4d23eb38208..f0bf0d31bdd2 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -31,7 +31,7 @@ unsigned int pcs_loglevel = LOG_TRACE; module_param(pcs_loglevel, uint, 0644); MODULE_PARM_DESC(pcs_loglevel, "Trace level"); -unsigned int debugfs_tracing; +unsigned int debugfs_tracing = DEBUGFS_TRACE; module_param(debugfs_tracing, uint, 0644); MODULE_PARM_DESC(debugfs_tracing, "Enable/Disbale debugfs tracing"); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/3] fs/fuse kio: disable duplication FUSE_K* messages to debugfs by default
It's not very polite to put trace messages to debugfs without asking the user, while they are only used for easier debugging fuse_kio_pcs module. This patch disables debugfs tracing by default and makes it possible to enable this traces via debugfs_tracing option. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 7bedb7f95486..e4d23eb38208 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -31,6 +31,10 @@ unsigned int pcs_loglevel = LOG_TRACE; module_param(pcs_loglevel, uint, 0644); MODULE_PARM_DESC(pcs_loglevel, "Trace level"); +unsigned int debugfs_tracing; +module_param(debugfs_tracing, uint, 0644); +MODULE_PARM_DESC(debugfs_tracing, "Enable/Disbale debugfs tracing"); + #ifdef CONFIG_DEBUG_KERNEL static int set_sockio_fail_percent(const char *val, struct kernel_param *kp) { @@ -1472,10 +1476,12 @@ void __kfuse_trace(struct fuse_conn * fc, unsigned long ip, const char * fmt, .. if (t) memcpy(t + 1, buf, len + 1); FUSE_TRACE_COMMIT(tr); - if (ip) - __trace_puts(ip, buf, len); - else - pr_debug("%s\n", buf); + if (unlikely(debugfs_tracing)) { + if (ip) + __trace_puts(ip, buf, len); + else + pr_debug("%s\n", buf); + } } put_cpu(); } -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 0/3] Fuse KIO: clanup fuse ktrace messages
#VSTOR-18383 Pavel Butsykin (3): fs/fuse kio: bring fuse ktraces to a common view fs/fuse kio: disable duplication FUSE_K* messages to debugfs by default fs/fuse kio: make it possible to enable TRACE/DTRACE in the release kernel fs/fuse/kio/pcs/fuse_ktrace.h | 6 ++ fs/fuse/kio/pcs/log.h | 10 +++--- fs/fuse/kio/pcs/pcs_cs.c | 2 +- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 14 ++ fs/fuse/kio/pcs/pcs_map.c | 2 +- fs/fuse/kio/pcs/pcs_req.c | 2 +- fs/fuse/kio/pcs/pcs_rpc.c | 10 +- 7 files changed, 27 insertions(+), 19 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: fix getting a non-existent pcs inode in kpcs_kill_requests()
Some files may not have pcs inode, so it will be safer to check for !fi->private before using it. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 875ad18df4a7..a8c235244506 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -1506,11 +1506,16 @@ static void kpcs_kill_requests(struct fuse_conn *fc, struct inode *inode) list_for_each_entry(ff, >conn_files, fl) { struct pcs_dentry_info *di; + struct fuse_inode *fi; if (!ff->ff_dentry) continue; - di = get_pcs_inode(ff->ff_dentry->d_inode); + fi = get_fuse_inode(ff->ff_dentry->d_inode); + if (!fi->private) + continue; + + di = pcs_inode_from_fuse(fi); spin_lock(>kq_lock); fuse_kill_requests(fc, inode, >kq); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 1/3] Revert "fs/fuse kio: add warning about jumbo chunks"
This reverts commit afb8d534110dbe203e4ae6385cef79b38c9e4771. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 3 --- fs/fuse/kio/pcs/pcs_mds_prot.h | 2 -- 2 files changed, 5 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 104fab25692b..875ad18df4a7 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -318,9 +318,6 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino if (info.sys.map_type != PCS_MAP_PLAIN) { TRACE("Unsupported map_type:%x, ignore\n", info.sys.map_type); - - if (info.sys.map_type & PCS_JUMBO_CHUNK_FLAG) - pr_warn_once("kio: fpath doesn't support jumbo chunks\n"); return 0; } diff --git a/fs/fuse/kio/pcs/pcs_mds_prot.h b/fs/fuse/kio/pcs/pcs_mds_prot.h index 4aca1e970170..80c20fde1537 100644 --- a/fs/fuse/kio/pcs/pcs_mds_prot.h +++ b/fs/fuse/kio/pcs/pcs_mds_prot.h @@ -259,8 +259,6 @@ enum PCS_MAP_LS = PCS_MAP_COMBINED, /* Log structured storage */ }; -#define PCS_JUMBO_CHUNK_FLAG (1ULL << 63) /* Chunks size > 4G */ - /* Max inline file size */ #define PCS_MAX_INLINE_SIZE 0x10 /* 1Mb */ -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/3] fs/fuse kio: sync pcs_mds_sys_info struct
For some reason pcs_mds_sys_info structure is different in the kernel and userspace. Let's synchronize it to avoid inaccuracies and discrepancies in the future. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_client_types.h | 6 +++--- fs/fuse/kio/pcs/pcs_cluster.c | 8 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 2 +- fs/fuse/kio/pcs/pcs_prot_types.h | 10 ++ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_client_types.h b/fs/fuse/kio/pcs/pcs_client_types.h index 1be32cbbf285..c0d14ec5b5d4 100644 --- a/fs/fuse/kio/pcs/pcs_client_types.h +++ b/fs/fuse/kio/pcs/pcs_client_types.h @@ -87,9 +87,9 @@ static inline void pcs_set_fileinfo(struct pcs_dentry_info *i, const struct pcs_ if (mi->sys.stripe_depth == 0) { mi->sys.stripe_depth = 1; - mi->sys.strip_width = mi->sys.chunk_size; + mi->sys.strip_width = mi->sys.chunk_size_lo; } - i->mapping.chunk_size_bits = ilog2(mi->sys.chunk_size); + i->mapping.chunk_size_bits = ilog2(mi->sys.chunk_size_lo); } @@ -170,7 +170,7 @@ typedef struct _pcs_api_csconnreq_t { #define DENTRY_ARGS(de) PCS_FILE_ID_ARGS((de)->id.parent), PCS_FILE_ID_ARGS((de)->fileinfo.attr.id) #define DENTRY_SIZE(de) ((de)->fileinfo.attr.size) -#define DENTRY_CHUNK_SIZE(de) ((de)->fileinfo.sys.chunk_size) +#define DENTRY_CHUNK_SIZE(de) ((de)->fileinfo.sys.chunk_size_lo) #define DENTRY_CHUNK_SIZE_BITS(de) ((de)->mapping.chunk_size_bits) void pcs_mapset_limit(struct pcs_map_set *maps, int limit); diff --git a/fs/fuse/kio/pcs/pcs_cluster.c b/fs/fuse/kio/pcs/pcs_cluster.c index 5df263f01f98..a73120c97e5e 100644 --- a/fs/fuse/kio/pcs/pcs_cluster.c +++ b/fs/fuse/kio/pcs/pcs_cluster.c @@ -364,9 +364,9 @@ static noinline void __pcs_cc_process_ireq_rw(struct pcs_int_request *ireq) unsigned int len; u64 rpos, chunk, end_pos; - rpos = map_file_to_chunk(pos, di->fileinfo.sys.chunk_size, di->fileinfo.sys.stripe_depth, di->fileinfo.sys.strip_width); + rpos = map_file_to_chunk(pos, di->fileinfo.sys.chunk_size_lo, di->fileinfo.sys.stripe_depth, di->fileinfo.sys.strip_width); - chunk = rpos & ~((u64)di->fileinfo.sys.chunk_size - 1); + chunk = rpos & ~((u64)di->fileinfo.sys.chunk_size_lo - 1); end_pos = ((rpos / di->fileinfo.sys.strip_width) + 1) * (u64)di->fileinfo.sys.strip_width; sreq = ireq_alloc(di); @@ -385,9 +385,9 @@ static noinline void __pcs_cc_process_ireq_rw(struct pcs_int_request *ireq) sreq->iochunk.cmd = ireq->apireq.req->type; sreq->iochunk.cs_index = 0; sreq->iochunk.chunk = chunk; - sreq->iochunk.offset = rpos % di->fileinfo.sys.chunk_size; + sreq->iochunk.offset = rpos % di->fileinfo.sys.chunk_size_lo; sreq->iochunk.dio_offset = dio_offset; - len = di->fileinfo.sys.chunk_size - sreq->iochunk.offset; + len = di->fileinfo.sys.chunk_size_lo - sreq->iochunk.offset; if (len > sz) len = sz; if (rpos + len > end_pos) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 875ad18df4a7..6d12b8038e8a 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -343,7 +343,7 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino INIT_LIST_HEAD(>kq); spin_lock_init(>kq_lock); TRACE("init id:%llu chunk_size:%d stripe_depth:%d strip_width:%d\n", - fi->nodeid, di->fileinfo.sys.chunk_size, + fi->nodeid, di->fileinfo.sys.chunk_size_lo, di->fileinfo.sys.stripe_depth, di->fileinfo.sys.strip_width); ret = fuse_pcs_kdirect_claim_op(fc, file, true); diff --git a/fs/fuse/kio/pcs/pcs_prot_types.h b/fs/fuse/kio/pcs/pcs_prot_types.h index bba1f1dc76e3..0e7bc9743885 100644 --- a/fs/fuse/kio/pcs/pcs_prot_types.h +++ b/fs/fuse/kio/pcs/pcs_prot_types.h @@ -104,15 +104,17 @@ struct __pre_aligned(8) pcs_mds_fattr }; struct __pre_aligned(8) pcs_mds_sys_info { - u32 map_type; /* reserved for RAID */ - u32 chunk_size; /* global constant */ + u8 map_type; /* reserved for RAID */ + u8 reserved[2]; + u8 chunk_size_hi; /* chunk size (hi bits) */ + u32 chunk_size_lo; /* chunk size (lo bits) */ u8 stripe_depth; /* for RAID6/RS */ u8 redundancy; /* number of checksums for RAID6/RS */ u8 tolerance;/* write-tolerance (how much lost replicas we can tolerate still allowing writing) */ - u8 reserved8
[Devel] [PATCH 0/3] fix jumbo chunk warning
Initially the warning was added incorrectly due to unsynchronization of pcs_mds_sys_info structure with the userspace client. Let's sync the structure and fix that. Pavel Butsykin (3): Revert "fs/fuse kio: add warning about jumbo chunks" fs/fuse kio: sync pcs_mds_sys_info struct fs/fuse kio: add warning about jumbo chunks fs/fuse/kio/pcs/pcs_client_types.h | 6 +++--- fs/fuse/kio/pcs/pcs_cluster.c | 8 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 4 ++-- fs/fuse/kio/pcs/pcs_mds_prot.h | 2 -- fs/fuse/kio/pcs/pcs_prot_types.h | 10 ++ 5 files changed, 15 insertions(+), 15 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 3/3] fs/fuse kio: add warning about jumbo chunks
KIO doesn't support jumbo chunks yet, so all requests to jumbo chunks are silently redirected to user-space. It will be useful to see a message about this until support has been added to KIO. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 6d12b8038e8a..aa1c79f440cb 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -318,6 +318,9 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino if (info.sys.map_type != PCS_MAP_PLAIN) { TRACE("Unsupported map_type:%x, ignore\n", info.sys.map_type); + + if (info.sys.chunk_size_hi) + pr_warn_once("kio: fpath doesn't support jumbo chunks\n"); return 0; } -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse kio: add warning about jumbo chunks
pls, ignore this. On 12.02.2019 17:20, Pavel Butsykin wrote: > KIO doesn't support jumbo chunks yet, so all requests to jumbo chunks are > silently redirected to user-space. It will be useful to see a message about > this until support has been added to KIO. > > #VSTOR-20372 > > Signed-off-by: Pavel Butsykin > --- > fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 3 +++ > fs/fuse/kio/pcs/pcs_mds_prot.h | 2 ++ > 2 files changed, 5 insertions(+) > > diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > index 3ca1ce2d6bd5..466380c6e945 100644 > --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c > @@ -319,6 +319,9 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct > file *file, struct ino > > if (info.sys.map_type != PCS_MAP_PLAIN) { > TRACE("Unsupported map_type:%x, ignore\n", info.sys.map_type); > + > + if (info.sys.map_type & PCS_JUMBO_CHUNK_FLAG) > + pr_warn_once("kio: fpath doesn't support jumbo > chunks\n"); > return 0; > } > > diff --git a/fs/fuse/kio/pcs/pcs_mds_prot.h b/fs/fuse/kio/pcs/pcs_mds_prot.h > index 80c20fde1537..4aca1e970170 100644 > --- a/fs/fuse/kio/pcs/pcs_mds_prot.h > +++ b/fs/fuse/kio/pcs/pcs_mds_prot.h > @@ -259,6 +259,8 @@ enum > PCS_MAP_LS = PCS_MAP_COMBINED, /* Log structured storage */ > }; > > +#define PCS_JUMBO_CHUNK_FLAG (1ULL << 63) /* Chunks size > 4G */ > + > /* Max inline file size */ > #define PCS_MAX_INLINE_SIZE 0x10 /* 1Mb */ > > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: add warning about jumbo chunks
KIO doesn't support jumbo chunks yet, so all requests to jumbo chunks are silently redirected to user-space. It will be useful to see a message about this until support has been added to KIO. #VSTOR-20372 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 3 +++ fs/fuse/kio/pcs/pcs_mds_prot.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 3ca1ce2d6bd5..466380c6e945 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -319,6 +319,9 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino if (info.sys.map_type != PCS_MAP_PLAIN) { TRACE("Unsupported map_type:%x, ignore\n", info.sys.map_type); + + if (info.sys.map_type & PCS_JUMBO_CHUNK_FLAG) + pr_warn_once("kio: fpath doesn't support jumbo chunks\n"); return 0; } diff --git a/fs/fuse/kio/pcs/pcs_mds_prot.h b/fs/fuse/kio/pcs/pcs_mds_prot.h index 80c20fde1537..4aca1e970170 100644 --- a/fs/fuse/kio/pcs/pcs_mds_prot.h +++ b/fs/fuse/kio/pcs/pcs_mds_prot.h @@ -259,6 +259,8 @@ enum PCS_MAP_LS = PCS_MAP_COMBINED, /* Log structured storage */ }; +#define PCS_JUMBO_CHUNK_FLAG (1ULL << 63) /* Chunks size > 4G */ + /* Max inline file size */ #define PCS_MAX_INLINE_SIZE 0x10 /* 1Mb */ -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: add warning about jumbo chunks
KIO doesn't support jumbo chunks yet, so all requests to jumbo chunks are silently redirected to user-space. It will be useful to see a message about this until support has been added to KIO. #VSTOR-20372 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 3 +++ fs/fuse/kio/pcs/pcs_mds_prot.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 3ca1ce2d6bd5..466380c6e945 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -319,6 +319,9 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino if (info.sys.map_type != PCS_MAP_PLAIN) { TRACE("Unsupported map_type:%x, ignore\n", info.sys.map_type); + + if (info.sys.map_type & PCS_JUMBO_CHUNK_FLAG) + pr_warn_once("kio: fpath doesn't support jumbo chunks\n"); return 0; } diff --git a/fs/fuse/kio/pcs/pcs_mds_prot.h b/fs/fuse/kio/pcs/pcs_mds_prot.h index 80c20fde1537..4aca1e970170 100644 --- a/fs/fuse/kio/pcs/pcs_mds_prot.h +++ b/fs/fuse/kio/pcs/pcs_mds_prot.h @@ -259,6 +259,8 @@ enum PCS_MAP_LS = PCS_MAP_COMBINED, /* Log structured storage */ }; +#define PCS_JUMBO_CHUNK_FLAG (1 << 28) /* Chunks size > 4G */ + /* Max inline file size */ #define PCS_MAX_INLINE_SIZE 0x10 /* 1Mb */ -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send
Yes, I missed this synchronization idea, the check and list_add should be together, will fix. On 24.01.2019 11:45, Kirill Tkhai wrote: > On 23.01.2019 20:22, Pavel Butsykin wrote: >> >> 23.01.2019 16:55, Kirill Tkhai пишет: >>> On 23.01.2019 14:49, Pavel Butsykin wrote: >>>> Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to execute >>>> new >>>> requests. But in case of kio requests it doesn't work because the status >>>> check >>>> is located behind kio.op->req_send(). To fix this let's move the status >>>> check >>>> before kio.op->req_send(). >>>> >>>> Note: We can drop hunk with req->end(fc, req) in __fuse_request_send() >>>> because >>>> it was only needed to clenup kio setattr request after >>>> pcs_kio_setattr_handle(). >>>> >>>> Signed-off-by: Pavel Butsykin >>> Why is this safe? >>> >>> After you move the check out of fc->lock, it becomes racy, and >>> fuse_invalidate_files() >>> may become work not as expected. >> >> test_bit is atomic operation. Which type of race do you mean? > > fuse_request_send_background() > fuse_invalidate_files() >test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff->ff_state)) > > > spin_lock(>lock); > > list_for_each_entry(ff, >rw_files, rw_entry) > > set_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state); > > spin_unlock(>lock); > > > spin_lock(>lock); > > fuse_kill_requests(fc, inode, >bg_queue); > > spin_unlock(>lock); > > >spin_lock(>lock); >if (fc->connected) { > fuse_request_send_background_locked(fc, req); <-- queuing request after > fuse_invalidate_files() thinks that >requests for all > immediate files already killed. > > ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH] fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send
On 24.01.2019 12:21, Kirill Tkhai wrote: > On 24.01.2019 12:17, Pavel Butsykin wrote: >> Yes, I missed this synchronization idea, the check and list_add should >> be together, will fix. > > Also, __fuse_request_send() may need to be fixed, since it does not look > as having appropriate in already existing code (I haven't checked deeply). Yep, a similar race is present. Moreover, there may be kernel panic in fuse_kill_requests(fc, inode, >pending) since fiq->pending list is passed without fiq->waitq.lock. > >> On 24.01.2019 11:45, Kirill Tkhai wrote: >>> On 23.01.2019 20:22, Pavel Butsykin wrote: >>>> >>>> 23.01.2019 16:55, Kirill Tkhai пишет: >>>>> On 23.01.2019 14:49, Pavel Butsykin wrote: >>>>>> Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to execute >>>>>> new >>>>>> requests. But in case of kio requests it doesn't work because the status >>>>>> check >>>>>> is located behind kio.op->req_send(). To fix this let's move the status >>>>>> check >>>>>> before kio.op->req_send(). >>>>>> >>>>>> Note: We can drop hunk with req->end(fc, req) in __fuse_request_send() >>>>>> because >>>>>> it was only needed to clenup kio setattr request after >>>>>> pcs_kio_setattr_handle(). >>>>>> >>>>>> Signed-off-by: Pavel Butsykin >>>>> Why is this safe? >>>>> >>>>> After you move the check out of fc->lock, it becomes racy, and >>>>> fuse_invalidate_files() >>>>> may become work not as expected. >>>> >>>> test_bit is atomic operation. Which type of race do you mean? >>> >>> fuse_request_send_background() >>> fuse_invalidate_files() >>> test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff->ff_state)) >>> >>> >>> spin_lock(>lock); >>> >>> list_for_each_entry(ff, >rw_files, rw_entry) >>> >>> set_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state); >>> >>> spin_unlock(>lock); >>> >>> >>> spin_lock(>lock); >>> >>> fuse_kill_requests(fc, inode, >bg_queue); >>> >>> spin_unlock(>lock); >>> >>> >>> spin_lock(>lock); >>> if (fc->connected) { >>> fuse_request_send_background_locked(fc, req); <-- queuing request >>> after fuse_invalidate_files() thinks that >>> requests for all >>> immediate files already killed. >>> >>> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/2] fs/fuse: fix unsafe killing fiq->pending requests
There are two problems related to the lack of fiq locking in fuse_invalidate_files(). The first is an unsafe iteration of fiq->pending list in fuse_kill_requests(). The second problem is the race between __fuse_request_send() and fuse_invalidate_files(): __fuse_request_send(): fuse_invalidate_files(): spin_lock(>waitq.lock); test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state) spin_lock(>lock); list_for_each_entry(ff, >rw_files, rw_entry) set_bit(FUSE_S_FAIL_IMMEDIATELY, >ff_state); spin_unlock(>lock); spin_lock(>lock); spin_lock(>lock); fuse_kill_requests(fc, inode, >pending); spin_unlock(>lock); spin_unlock(>lock); queue_request(fiq, req);<-- add a new request after fuse_invalidate_files(), spin_unlock(>waitq.lock); that's wrong. The patch fixes both problems. Signed-off-by: Pavel Butsykin --- fs/fuse/inode.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index cb275ff21991..80bfe45d5d46 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -437,9 +437,12 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid) spin_lock(>lock); for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) fuse_kill_requests(fc, inode, >processing[i]); - fuse_kill_requests(fc, inode, >pending); fuse_kill_requests(fc, inode, >io); spin_unlock(>lock); + + spin_lock(>waitq.lock); + fuse_kill_requests(fc, inode, >pending); + spin_unlock(>waitq.lock); } fuse_kill_requests(fc, inode, >main_iq.pending); fuse_kill_requests(fc, inode, >bg_queue); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 1/2] fs/fuse kio: add FUSE_S_FAIL_IMMEDIATELY check in pcs_fuse_submit()
Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to execute new requests. But in case of kio requests it doesn't work because the status check is located behind kio.op->req_send(). To fix this let's add the status check in pcs_fuse_submit(). Signed-off-by: Pavel Butsykin --- Note: applies on top of "[PATCH v2] fs/fuse kio: invalidate files for kio" fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 5 + 1 file changed, 5 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index da4b5fba03fb..3ca1ce2d6bd5 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -986,6 +986,11 @@ error: submit: spin_lock(>kq_lock); + if (req->ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff->ff_state)) { + spin_unlock(>kq_lock); + req->out.h.error = -EIO; + goto error; + } list_add_tail(>list, >kq); spin_unlock(>kq_lock); -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 1/2] fs/fuse kio: add FUSE_S_FAIL_IMMEDIATELY check in pcs_fuse_submit()
On 01.02.2019 17:24, Kirill Tkhai wrote: > On 24.01.2019 16:12, Pavel Butsykin wrote: >> Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to execute new >> requests. But in case of kio requests it doesn't work because the status >> check >> is located behind kio.op->req_send(). To fix this let's add the status check >> in pcs_fuse_submit(). >> >> Signed-off-by: Pavel Butsykin >> --- >> Note: >> applies on top of "[PATCH v2] fs/fuse kio: invalidate files for kio" >> >> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 5 + >> 1 file changed, 5 insertions(+) >> >> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> index da4b5fba03fb..3ca1ce2d6bd5 100644 >> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >> @@ -986,6 +986,11 @@ error: >> >> submit: >> spin_lock(>kq_lock); >> +if (req->ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >ff->ff_state)) { > > FUSE_S_FAIL_IMMEDIATELY is set under fc->lock, while it's checked under > kq_lock. Actually this lock is needed to protect listing fi->rw_files, not for set_bit. > How do you guarantee visibility? It's atomic operation, so I should just guarantee synchronization with fuse_invalidate_files() which is carried out by set_bit(FUSE_S_FAIL_IMMEDIATELY, ) + kpcs_kill_requests() and the locked check. > >> +spin_unlock(>kq_lock); >> +req->out.h.error = -EIO; >> +goto error; >> +} >> list_add_tail(>list, >kq); >> spin_unlock(>kq_lock); >> >> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
Re: [Devel] [PATCH 1/2] fs/fuse kio: add FUSE_S_FAIL_IMMEDIATELY check in pcs_fuse_submit()
On 01.02.2019 18:13, Pavel Butsykin wrote: > > > On 01.02.2019 17:24, Kirill Tkhai wrote: >> On 24.01.2019 16:12, Pavel Butsykin wrote: >>> Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to >>> execute new >>> requests. But in case of kio requests it doesn't work because the >>> status check >>> is located behind kio.op->req_send(). To fix this let's add the >>> status check >>> in pcs_fuse_submit(). >>> >>> Signed-off-by: Pavel Butsykin >>> --- >>> Note: >>> applies on top of "[PATCH v2] fs/fuse kio: invalidate files for kio" >>> >>> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 5 + >>> 1 file changed, 5 insertions(+) >>> >>> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> index da4b5fba03fb..3ca1ce2d6bd5 100644 >>> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c >>> @@ -986,6 +986,11 @@ error: >>> submit: >>> spin_lock(>kq_lock); >>> + if (req->ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, >>> >ff->ff_state)) { >> >> FUSE_S_FAIL_IMMEDIATELY is set under fc->lock, while it's checked >> under kq_lock. > > Actually this lock is needed to protect listing fi->rw_files, not for > set_bit. > >> How do you guarantee visibility? > > It's atomic operation, so I should just guarantee > synchronization with fuse_invalidate_files() which is carried out by > set_bit(FUSE_S_FAIL_IMMEDIATELY, ) + kpcs_kill_requests() and the locked > check. But perhaps for architectures "not x86" need barriers. >> >>> + spin_unlock(>kq_lock); >>> + req->out.h.error = -EIO; >>> + goto error; >>> + } >>> list_add_tail(>list, >kq); >>> spin_unlock(>kq_lock); >>> ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH] fs/fuse kio: export fastpath protocol version
In order to transfer the logic of the fallback decision to user-space, let's add export fastpath version. #PSBM-93637 Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 6 ++ fs/fuse/kio/pcs/pcs_ioctl.h| 2 +- fs/fuse/kio/pcs/pcs_prot_types.h | 9 ++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 3b1d819792b2..002eaae18687 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -31,6 +31,10 @@ unsigned int pcs_loglevel = LOG_TRACE; module_param(pcs_loglevel, uint, 0644); MODULE_PARM_DESC(pcs_loglevel, "Trace level"); +u64 fast_path_version; +module_param(fast_path_version, ullong, 0444); +MODULE_PARM_DESC(fast_path_version, "Fast path protocol version"); + #ifdef CONFIG_DEBUG_KERNEL static int set_sockio_fail_percent(const char *val, struct kernel_param *kp) { @@ -1509,6 +1513,8 @@ static int __init kpcs_mod_init(void) if (!pcs_cleanup_wq) goto free_wq; + fast_path_version = PCS_FAST_PATH_VERSION.full; + if (fuse_register_kio(_pcs_ops)) goto free_cleanup_wq; diff --git a/fs/fuse/kio/pcs/pcs_ioctl.h b/fs/fuse/kio/pcs/pcs_ioctl.h index 5cf40e35f881..6da5ceb03122 100644 --- a/fs/fuse/kio/pcs/pcs_ioctl.h +++ b/fs/fuse/kio/pcs/pcs_ioctl.h @@ -10,7 +10,7 @@ #include "pcs_map.h" #include "pcs_rpc.h" -#define PCS_FAST_PATH_VERSION ((PCS_FAST_PATH_VERSION_T){1, 2}) +#define PCS_FAST_PATH_VERSION ((PCS_FAST_PATH_VERSION_T){{1, 2}}) #define PCS_FUSE_INO_SPECIAL_ ((unsigned long long)-0x1000) diff --git a/fs/fuse/kio/pcs/pcs_prot_types.h b/fs/fuse/kio/pcs/pcs_prot_types.h index 9db4516824aa..268701511457 100644 --- a/fs/fuse/kio/pcs/pcs_prot_types.h +++ b/fs/fuse/kio/pcs/pcs_prot_types.h @@ -73,9 +73,12 @@ typedef u64 PCS_CHUNK_UID_T; typedef u64 PCS_LEASE_GEN_T; typedef u32 PCS_POLICY_GEN_T; -typedef struct { - u32 major; - u32 minor; +typedef union { + struct { + u32 major; + u32 minor; + }; + u64 full; } PCS_FAST_PATH_VERSION_T; /* -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 4/4] fs/fuse kio: export io_locality
We will need this option for performance analysis. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_cluster_core.c | 1 - fs/fuse/kio/pcs/pcs_map.c | 7 ++- fs/fuse/kio/pcs/pcs_req.h | 1 - 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_cluster_core.c b/fs/fuse/kio/pcs/pcs_cluster_core.c index d1379c99ac6a..053325f94de9 100644 --- a/fs/fuse/kio/pcs/pcs_cluster_core.c +++ b/fs/fuse/kio/pcs/pcs_cluster_core.c @@ -159,7 +159,6 @@ int pcs_cc_init(struct pcs_cluster_core *cc, struct workqueue_struct *wq, cc->cfg.curr = cc->cfg.def; cc->cfg.sn = PCS_CONFIG_SEQ_ANY; - cc->io_locality = 0; cc->io_tweaks = 0; cc->netlat_cutoff = PCS_MAX_NETWORK_LATENCY*1000; cc->iolat_cutoff = PCS_MAX_IO_LATENCY*1000; diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 9c3762c92315..e794b94095f3 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "pcs_types.h" #include "pcs_sock_io.h" @@ -30,6 +31,10 @@ struct kmem_cache *pcs_map_cachep; +unsigned int cs_io_locality = 0; +module_param(cs_io_locality, uint, 0644); +MODULE_PARM_DESC(cs_io_locality, "CS IO locality"); + static struct pcs_cs_list *cs_link_to_cs_list(struct pcs_cs_link *csl) { struct pcs_cs_record *cs_rec; @@ -1704,7 +1709,7 @@ static int get_io_locality(struct pcs_cluster_core *cc) { int io_locality; - io_locality = cc->io_locality; + io_locality = cs_io_locality; if (io_locality == 0) io_locality = cc->cfg.curr.io_locality; diff --git a/fs/fuse/kio/pcs/pcs_req.h b/fs/fuse/kio/pcs/pcs_req.h index e668e55f0b71..604402de173d 100644 --- a/fs/fuse/kio/pcs/pcs_req.h +++ b/fs/fuse/kio/pcs/pcs_req.h @@ -215,7 +215,6 @@ struct pcs_cluster_core int in_progress; } cfg; - int io_locality; int io_tweaks; int iolat_cutoff; int netlat_cutoff; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 0/4] KIO performance fixes
#VSTOR-11050 This patch-set aims to fix the performance issue with single-thread sequential async reads. Pavel Butsykin (4): fs/fuse kio: fix a typo in worth_to_grow() fs/fuse kio: relax congestion avoidance limits (backport from usermode) fs/fuse kio: add missed sock write in pcs_sock_sendmsg() fs/fuse kio: export io_locality fs/fuse/kio/pcs/pcs_cluster_core.c | 1 - fs/fuse/kio/pcs/pcs_cs.c | 26 +- fs/fuse/kio/pcs/pcs_cs.h | 1 + fs/fuse/kio/pcs/pcs_map.c | 16 +--- fs/fuse/kio/pcs/pcs_req.h | 1 - fs/fuse/kio/pcs/pcs_sock_io.c | 6 ++ 6 files changed, 41 insertions(+), 10 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 1/4] fs/fuse kio: fix a typo in worth_to_grow()
It was supposed the function returns true if time has passed less than netlat_cutoff since the request was sent. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c index 817c7d6a9379..0af852615ff4 100644 --- a/fs/fuse/kio/pcs/pcs_map.c +++ b/fs/fuse/kio/pcs/pcs_map.c @@ -1391,7 +1391,7 @@ static int worth_to_grow(struct pcs_int_request *ireq, struct pcs_cs * cs) if (ireq->type == PCS_IREQ_FLUSH) return 0; - return ktime_to_ms(ktime_sub(ktime_get(), ireq->ts_sent)) + cc_from_csset(cs->css)->netlat_cutoff; + return ktime_to_ms(ktime_sub(ktime_get(), ireq->ts_sent)) < cc_from_csset(cs->css)->netlat_cutoff; } static void pcs_cs_deaccount(struct pcs_int_request *ireq, struct pcs_cs * cs, int error) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH v2 1/2] fs/fuse kio: sync pcs_mds_sys_info struct
For some reason pcs_mds_sys_info structure is different in the kernel and userspace. Let's synchronize it to avoid inaccuracies and discrepancies in the future. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_client_types.h | 6 +++--- fs/fuse/kio/pcs/pcs_cluster.c | 8 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 2 +- fs/fuse/kio/pcs/pcs_prot_types.h | 10 ++ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_client_types.h b/fs/fuse/kio/pcs/pcs_client_types.h index 9ddce5cff3f5..8790e16f227c 100644 --- a/fs/fuse/kio/pcs/pcs_client_types.h +++ b/fs/fuse/kio/pcs/pcs_client_types.h @@ -85,9 +85,9 @@ static inline void pcs_set_fileinfo(struct pcs_dentry_info *i, const struct pcs_ if (mi->sys.stripe_depth == 0) { mi->sys.stripe_depth = 1; - mi->sys.strip_width = mi->sys.chunk_size; + mi->sys.strip_width = mi->sys.chunk_size_lo; } - i->mapping.chunk_size_bits = ilog2(mi->sys.chunk_size); + i->mapping.chunk_size_bits = ilog2(mi->sys.chunk_size_lo); } @@ -168,7 +168,7 @@ typedef struct _pcs_api_csconnreq_t { #define DENTRY_ARGS(de) PCS_FILE_ID_ARGS((de)->id.parent), PCS_FILE_ID_ARGS((de)->fileinfo.attr.id) #define DENTRY_SIZE(de) ((de)->fileinfo.attr.size) -#define DENTRY_CHUNK_SIZE(de) ((de)->fileinfo.sys.chunk_size) +#define DENTRY_CHUNK_SIZE(de) ((de)->fileinfo.sys.chunk_size_lo) #define DENTRY_CHUNK_SIZE_BITS(de) ((de)->mapping.chunk_size_bits) void pcs_mapset_limit(struct pcs_map_set *maps, int limit); diff --git a/fs/fuse/kio/pcs/pcs_cluster.c b/fs/fuse/kio/pcs/pcs_cluster.c index 5df263f01f98..a73120c97e5e 100644 --- a/fs/fuse/kio/pcs/pcs_cluster.c +++ b/fs/fuse/kio/pcs/pcs_cluster.c @@ -364,9 +364,9 @@ static noinline void __pcs_cc_process_ireq_rw(struct pcs_int_request *ireq) unsigned int len; u64 rpos, chunk, end_pos; - rpos = map_file_to_chunk(pos, di->fileinfo.sys.chunk_size, di->fileinfo.sys.stripe_depth, di->fileinfo.sys.strip_width); + rpos = map_file_to_chunk(pos, di->fileinfo.sys.chunk_size_lo, di->fileinfo.sys.stripe_depth, di->fileinfo.sys.strip_width); - chunk = rpos & ~((u64)di->fileinfo.sys.chunk_size - 1); + chunk = rpos & ~((u64)di->fileinfo.sys.chunk_size_lo - 1); end_pos = ((rpos / di->fileinfo.sys.strip_width) + 1) * (u64)di->fileinfo.sys.strip_width; sreq = ireq_alloc(di); @@ -385,9 +385,9 @@ static noinline void __pcs_cc_process_ireq_rw(struct pcs_int_request *ireq) sreq->iochunk.cmd = ireq->apireq.req->type; sreq->iochunk.cs_index = 0; sreq->iochunk.chunk = chunk; - sreq->iochunk.offset = rpos % di->fileinfo.sys.chunk_size; + sreq->iochunk.offset = rpos % di->fileinfo.sys.chunk_size_lo; sreq->iochunk.dio_offset = dio_offset; - len = di->fileinfo.sys.chunk_size - sreq->iochunk.offset; + len = di->fileinfo.sys.chunk_size_lo - sreq->iochunk.offset; if (len > sz) len = sz; if (rpos + len > end_pos) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 002eaae18687..460155bc9d10 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -343,7 +343,7 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino di->cluster = >cc; di->inode = fi; TRACE("init id:%llu chunk_size:%d stripe_depth:%d strip_width:%d\n", - fi->nodeid, di->fileinfo.sys.chunk_size, + fi->nodeid, di->fileinfo.sys.chunk_size_lo, di->fileinfo.sys.stripe_depth, di->fileinfo.sys.strip_width); ret = fuse_pcs_kdirect_claim_op(fc, file, true); diff --git a/fs/fuse/kio/pcs/pcs_prot_types.h b/fs/fuse/kio/pcs/pcs_prot_types.h index 268701511457..98dfee47318d 100644 --- a/fs/fuse/kio/pcs/pcs_prot_types.h +++ b/fs/fuse/kio/pcs/pcs_prot_types.h @@ -107,15 +107,17 @@ struct __pre_aligned(8) pcs_mds_fattr }; struct __pre_aligned(8) pcs_mds_sys_info { - u32 map_type; /* reserved for RAID */ - u32 chunk_size; /* global constant */ + u8 map_type; /* reserved for RAID */ + u8 reserved[2]; + u8 chunk_size_hi; /* chunk size (hi bits) */ + u32 chunk_size_lo; /* chunk size (lo bits) */ u8 stripe_depth; /* for RAID6/RS */ u8 redundancy; /* number of checksums for RAID6/RS */ u8 tolerance;/* write-tolerance (how much lost replicas we can tolerate still allowing writing) */ - u8 reserved8; + u8
[Devel] [PATCH v2 2/2] fs/fuse kio: add warning about jumbo chunks
KIO doesn't support jumbo chunks yet, so all requests to jumbo chunks are silently redirected to user-space. It will be useful to see a message about this until support has been added to KIO. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c index 460155bc9d10..a719a8cc4c60 100644 --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c @@ -323,6 +323,12 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino return 0; } + if (info.sys.chunk_size_hi) { + TRACE("Unsupported chunk_size_hi:%x\n", info.sys.chunk_size_hi); + pr_warn_once("kio: fpath doesn't support jumbo chunks\n"); + return 0; + } + di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 3/4] fs/fuse kio: add missed sock write in pcs_sock_sendmsg()
We need to write the ready data to socket, in case write_queue list is empty, instead of rescheduling it. This will help maintain a balance between recv and send, because after rescheduling the receive will be called first. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_sock_io.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c index ede71c255084..e0699f57a007 100644 --- a/fs/fuse/kio/pcs/pcs_sock_io.c +++ b/fs/fuse/kio/pcs/pcs_sock_io.c @@ -415,6 +415,8 @@ int pcs_sockio_delayed_seg(struct pcs_sockio *sio) void pcs_sock_sendmsg(struct pcs_sockio * sio, struct pcs_msg *msg) { + int was_idle = list_empty(>write_queue); + DTRACE("sio(%p) msg:%p\n", sio, msg); if (pcs_if_error(>error)) { @@ -432,6 +434,10 @@ void pcs_sock_sendmsg(struct pcs_sockio * sio, struct pcs_msg *msg) if (!(sio->flags & PCS_SOCK_F_POOLOUT)) sio->flags |= PCS_SOCK_F_POOLOUT; + if (was_idle) { + sio->flags &= ~PCS_SOCK_F_POOLOUT; + pcs_sockio_send(sio); + } } /* Try to cancel message send. If it is impossible, because message is in the middle -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 2/4] fs/fuse kio: relax congestion avoidance limits (backport from usermode)
Investigation of VZ US-QA cluster shows that congestion window reduction after idle periods results in too slow window open after data start to flow again. So, introduce ssthresh to allow faster window open after idle periods. Maybe, even this is not enough and window should be open even more aggressively. Further observations will show. Signed-off-by: Pavel Butsykin --- fs/fuse/kio/pcs/pcs_cs.c | 26 +- fs/fuse/kio/pcs/pcs_cs.h | 1 + fs/fuse/kio/pcs/pcs_map.c | 7 ++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c index 00cd1ae99850..58ad6aea17b8 100644 --- a/fs/fuse/kio/pcs/pcs_cs.c +++ b/fs/fuse/kio/pcs/pcs_cs.c @@ -62,6 +62,7 @@ struct pcs_cs *pcs_cs_alloc(struct pcs_cs_set *css, cs->in_flight = 0; cs->cwnd = PCS_CS_INIT_CWND; cs->eff_cwnd = PCS_CS_INIT_CWND; + cs->ssthresh = PCS_CS_INIT_CWND; cs->cwr_state = 0; atomic_set(>latency_avg, 0); cs->net_latency_avg = 0; @@ -603,6 +604,10 @@ static void handle_congestion(struct pcs_cs *cs, struct pcs_rpc_hdr *h) * to half of min(in_flight, cwnd) and enter congestion reduction state, * where we ignore further congestion notifications until window is reduced */ + if (who->cwnd >= PCS_CS_INIT_CWND) + who->ssthresh = who->cwnd; + else + who->ssthresh = PCS_CS_INIT_CWND; if (who->in_flight < who->cwnd) who->cwnd = who->in_flight; who->cwnd /= 2; @@ -659,8 +664,12 @@ static void cs_keep_waiting(struct pcs_rpc *ep, struct pcs_msg *req, struct pcs_ } if (!who->cwr_state) { - FUSE_KDTRACE(cc_from_csset(cs->css)->fc, "Congestion window on CS" NODE_FMT " reducing %d/%d/%d", NODE_ARGS(h->xid.origin), -who->in_flight, who->eff_cwnd, who->cwnd); + FUSE_KTRACE(cc_from_csset(cs->css)->fc, "Congestion window on CS" NODE_FMT " reducing %d/%d/%d", NODE_ARGS(h->xid.origin), + who->in_flight, who->eff_cwnd, who->cwnd); + if (who->cwnd >= PCS_CS_INIT_CWND) + who->ssthresh = who->cwnd; + else + who->ssthresh = PCS_CS_INIT_CWND; if (who->in_flight < who->cwnd) who->cwnd = who->in_flight; who->cwnd /= 2; @@ -899,9 +908,14 @@ unsigned int cs_get_avg_in_flight(struct pcs_cs *cs) cs->in_flight_avg >>= interval; } if (cs->cwnd > PCS_CS_INIT_CWND) { - cs->cwnd = PCS_CS_INIT_CWND; - if (cs->eff_cwnd > PCS_CS_INIT_CWND) - cs->eff_cwnd = PCS_CS_INIT_CWND; + unsigned int cwnd = PCS_CS_INIT_CWND; + TRACE("Congestion window on CS#" NODE_FMT " was not used, shrink %u -> %u", NODE_ARGS(cs->id), + cs->cwnd, cwnd); + if (cs->cwnd > cs->ssthresh) + cs->ssthresh = cs->cwnd; + cs->cwnd = cwnd; + if (cs->eff_cwnd > cwnd) + cs->eff_cwnd = cwnd; } } } @@ -962,6 +976,8 @@ void cs_cwnd_use_or_lose(struct pcs_cs *cs) FUSE_KTRACE(cc_from_csset(cs->css)->fc, "Congestion window on CS#" NODE_FMT " was not used, shrink %u -> %u", NODE_ARGS(cs->id), cs->cwnd, cwnd); + if (cs->cwnd > cs->ssthresh) + cs->ssthresh = cs->cwnd; cs->cwnd = cwnd; if (cs->eff_cwnd > cwnd) cs->eff_cwnd = cwnd; diff --git a/fs/fuse/kio/pcs/pcs_cs.h b/fs/fuse/kio/pcs/pcs_cs.h index 1fb40936d046..513d53539211 100644 --- a/fs/fuse/kio/pcs/pcs_cs.h +++ b/fs/fuse/kio/pcs/pcs_cs.h @@ -52,6 +52,7 @@ struct pcs_cs { unsigned intin_flight; unsigned inteff_cwnd; unsigned intcwnd; + unsigned intssthresh; int cwr_state; atomic_tlatency_avg; unsigned intnet_
[Devel] [PATCH v2 0/2] fix jumbo chunk warning
Initially the warning was added incorrectly due to unsynchronization of pcs_mds_sys_info structure with the userspace client. Let's sync the structure and fix that. Pavel Butsykin (2): fs/fuse kio: sync pcs_mds_sys_info struct fs/fuse kio: add warning about jumbo chunks fs/fuse/kio/pcs/pcs_client_types.h | 6 +++--- fs/fuse/kio/pcs/pcs_cluster.c | 8 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 8 +++- fs/fuse/kio/pcs/pcs_prot_types.h | 10 ++ 4 files changed, 20 insertions(+), 12 deletions(-) -- 2.15.1 ___ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel
[Devel] [PATCH 02/15] fs/fuse kio: create sysfs stat directory
This patch implements the interfaces for initialize/finalize kio stat subsystem and adds the creation of stat directory. The sysfs directory will be created separately for each point. Signed-off-by: Pavel Butsykin --- fs/fuse/Makefile | 3 +- fs/fuse/control.c | 3 +- fs/fuse/inode.c| 1 + fs/fuse/kio/pcs/fuse_stat.c| 83 ++ fs/fuse/kio/pcs/fuse_stat.h| 11 + fs/fuse/kio/pcs/pcs_cluster_core.c | 3 ++ fs/fuse/kio/pcs/pcs_req.h | 2 + 7 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 fs/fuse/kio/pcs/fuse_stat.c create mode 100644 fs/fuse/kio/pcs/fuse_stat.h diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index 3eb06648da2c..87f655c596e6 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -24,6 +24,7 @@ fuse_kio_pcs-objs := kio/pcs/pcs_fuse_kdirect.o \ kio/pcs/pcs_cluster.o \ kio/pcs/pcs_cluster_core.o \ kio/pcs/pcs_cs.o \ - kio/pcs/fuse_io.o + kio/pcs/fuse_io.o \ + kio/pcs/fuse_stat.o fuse-objs := dev.o dir.o file.o inode.o control.o diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 5ea8ab2165cf..e9734d597419 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -18,7 +18,8 @@ * This is non-NULL when the single instance of the control filesystem * exists. Protected by fuse_mutex */ -static struct super_block *fuse_control_sb; +struct super_block *fuse_control_sb; +EXPORT_SYMBOL_GPL(fuse_control_sb); static struct fuse_conn *fuse_ctl_file_conn_get(struct file *file) { diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 25f6e0ceac37..ff3fbc0a779b 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -31,6 +31,7 @@ static struct kmem_cache *fuse_inode_cachep; static LIST_HEAD(fuse_kios_list); struct list_head fuse_conn_list; DEFINE_MUTEX(fuse_mutex); +EXPORT_SYMBOL_GPL(fuse_mutex); static int fuse_ve_odirect; diff --git a/fs/fuse/kio/pcs/fuse_stat.c b/fs/fuse/kio/pcs/fuse_stat.c new file mode 100644 index ..da8428ebe600 --- /dev/null +++ b/fs/fuse/kio/pcs/fuse_stat.c @@ -0,0 +1,83 @@ +#include +#include + +#include "fuse_stat.h" +#include "pcs_cluster.h" + +extern struct super_block *fuse_control_sb; + +static struct dentry *fuse_kio_add_dentry(struct dentry *parent, + struct fuse_conn *fc, + const char *name, + int mode, int nlink, + const struct inode_operations *iop, + const struct file_operations *fop, + void *ctx) +{ + struct inode *inode; + struct dentry *dentry = d_alloc_name(parent, name); + + if (!dentry) + return NULL; + + inode = new_inode(fc->sb); + if (!inode) { + dput(dentry); + return NULL; + } + + inode->i_ino = get_next_ino(); + inode->i_mode = mode; + inode->i_uid = fc->user_id; + inode->i_gid = fc->group_id; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + if (iop) + inode->i_op = iop; + inode->i_fop = fop; + set_nlink(inode, nlink); + inode->i_private = ctx; + d_add(dentry, inode); + + return dentry; +} + +static void fuse_kio_rm_dentry(struct dentry *dentry) +{ + d_inode(dentry)->i_private = NULL; + d_drop(dentry); + dput(dentry); +} + +void pcs_fuse_stat_init(struct pcs_fuse_stat *stat) +{ + struct fuse_conn *fc = + container_of(stat, struct pcs_fuse_cluster, cc.stat)->fc; + + mutex_lock(_mutex); + if (!fuse_control_sb) + goto out; + + stat->kio_stat = fuse_kio_add_dentry(fc->conn_ctl, fc, "kio_stat", +S_IFDIR | S_IXUSR, 2, +_dir_inode_operations, +_dir_operations, fc); + if (!stat->kio_stat) { + pr_err("kio: can't create kio stat directory"); + goto out; + } + + /* Stat initialize */ +out: + mutex_unlock(_mutex); +} + +void pcs_fuse_stat_fini(struct pcs_fuse_stat *stat) +{ + if (!stat->kio_stat) + return; + + mutex_lock(_mutex); + if (fuse_control_sb) + fuse_kio_rm_dentry(stat->kio_stat); + mutex_unlock(_mutex); +} diff --git a/fs/fuse/kio/pcs/fuse_stat.h b/fs/fuse/kio/pcs/fuse_stat.h new file mode 100644 index ..14687ffd83f2 --- /dev/null +++ b/fs/fuse/kio/pcs/fuse_stat.h @@ -0,0 +1,11 @@ +#ifndef _FUSE_STAT_H_ +#define _FUSE_STAT_H_ 1 + +struct pcs_fuse_stat { + struct dentry *kio_stat; +}; + +void pcs_fuse_st