From 09ab624b4827ee7dbfe6569e077309f81a6902a8 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Mon, 15 Mar 2010 10:42:11 -0400 Subject: [PATCH] --- yaml --- r: 189918 b: refs/heads/master c: 6c9ff1013b7a21099da838eeef7c3f23ee347957 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 4 +- trunk/arch/m68k/include/asm/atomic_mm.h | 8 +- trunk/arch/m68k/include/asm/sigcontext.h | 4 +- trunk/arch/x86/include/asm/lguest_hcall.h | 29 +--- trunk/arch/x86/lguest/boot.c | 61 ++++---- trunk/arch/x86/lguest/i386_head.S | 2 +- trunk/drivers/hwmon/applesmc.c | 18 --- trunk/drivers/hwmon/it87.c | 32 ++-- trunk/drivers/hwmon/sht15.c | 13 +- trunk/drivers/lguest/lguest_device.c | 4 +- trunk/drivers/lguest/x86/core.c | 12 -- trunk/fs/ceph/addr.c | 62 ++++---- trunk/fs/ceph/caps.c | 42 ++--- trunk/fs/ceph/dir.c | 7 +- trunk/fs/ceph/inode.c | 10 +- trunk/fs/ceph/messenger.c | 9 -- trunk/fs/ceph/osdmap.c | 180 +++++++++------------- trunk/fs/ceph/osdmap.h | 1 - trunk/fs/ceph/rados.h | 6 +- trunk/fs/ceph/snap.c | 26 ++-- trunk/fs/ceph/super.h | 3 +- trunk/lib/vsprintf.c | 10 +- trunk/security/selinux/ss/avtab.h | 2 +- 24 files changed, 209 insertions(+), 338 deletions(-) diff --git a/[refs] b/[refs] index 0f0cb1f1c068..00ecc3707568 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 96e35b40c0d6206f56370f937f6f4722739eb273 +refs/heads/master: 6c9ff1013b7a21099da838eeef7c3f23ee347957 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a0e3c3a47a51..5b422908d0f3 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -485,8 +485,8 @@ S: Maintained F: drivers/input/mouse/bcm5974.c APPLE SMC DRIVER -M: Henrik Rydberg -L: lm-sensors@lm-sensors.org +M: Nicolas Boichat +L: mactel-linux-devel@lists.sourceforge.net S: Maintained F: drivers/hwmon/applesmc.c diff --git a/trunk/arch/m68k/include/asm/atomic_mm.h b/trunk/arch/m68k/include/asm/atomic_mm.h index d9d2ed647435..88b7af20a996 100644 --- a/trunk/arch/m68k/include/asm/atomic_mm.h +++ b/trunk/arch/m68k/include/asm/atomic_mm.h @@ -148,18 +148,14 @@ static inline int atomic_xchg(atomic_t *v, int new) static inline int atomic_sub_and_test(int i, atomic_t *v) { char c; - __asm__ __volatile__("subl %2,%1; seq %0" - : "=d" (c), "+m" (*v) - : "id" (i)); + __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i)); return c != 0; } static inline int atomic_add_negative(int i, atomic_t *v) { char c; - __asm__ __volatile__("addl %2,%1; smi %0" - : "=d" (c), "+m" (*v) - : "id" (i)); + __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i)); return c != 0; } diff --git a/trunk/arch/m68k/include/asm/sigcontext.h b/trunk/arch/m68k/include/asm/sigcontext.h index a29dd74a17cb..1320eaa4cc2a 100644 --- a/trunk/arch/m68k/include/asm/sigcontext.h +++ b/trunk/arch/m68k/include/asm/sigcontext.h @@ -17,11 +17,13 @@ struct sigcontext { #ifndef __uClinux__ # ifdef __mcoldfire__ unsigned long sc_fpregs[2][2]; /* room for two fp registers */ + unsigned long sc_fpcntl[3]; + unsigned char sc_fpstate[16+6*8]; # else unsigned long sc_fpregs[2*3]; /* room for two fp registers */ -# endif unsigned long sc_fpcntl[3]; unsigned char sc_fpstate[216]; +# endif #endif }; diff --git a/trunk/arch/x86/include/asm/lguest_hcall.h b/trunk/arch/x86/include/asm/lguest_hcall.h index b60f2924c413..ba0eed8aa1a6 100644 --- a/trunk/arch/x86/include/asm/lguest_hcall.h +++ b/trunk/arch/x86/include/asm/lguest_hcall.h @@ -28,39 +28,22 @@ #ifndef __ASSEMBLY__ #include +#include /*G:030 * But first, how does our Guest contact the Host to ask for privileged * operations? There are two ways: the direct way is to make a "hypercall", * to make requests of the Host Itself. * - * Our hypercall mechanism uses the highest unused trap code (traps 32 and - * above are used by real hardware interrupts). Seventeen hypercalls are - * available: the hypercall number is put in the %eax register, and the - * arguments (when required) are placed in %ebx, %ecx, %edx and %esi. - * If a return value makes sense, it's returned in %eax. + * We use the KVM hypercall mechanism, though completely different hypercall + * numbers. Seventeen hypercalls are available: the hypercall number is put in + * the %eax register, and the arguments (when required) are placed in %ebx, + * %ecx, %edx and %esi. If a return value makes sense, it's returned in %eax. * * Grossly invalid calls result in Sudden Death at the hands of the vengeful * Host, rather than returning failure. This reflects Winston Churchill's * definition of a gentleman: "someone who is only rude intentionally". - */ -static inline unsigned long -hcall(unsigned long call, - unsigned long arg1, unsigned long arg2, unsigned long arg3, - unsigned long arg4) -{ - /* "int" is the Intel instruction to trigger a trap. */ - asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) - /* The call in %eax (aka "a") might be overwritten */ - : "=a"(call) - /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */ - : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) - /* "memory" means this might write somewhere in memory. - * This isn't true for all calls, but it's safe to tell - * gcc that it might happen so it doesn't get clever. */ - : "memory"); - return call; -} +:*/ /* Can't use our min() macro here: needs to be a constant */ #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) diff --git a/trunk/arch/x86/lguest/boot.c b/trunk/arch/x86/lguest/boot.c index 2bdf628066bd..7e59dc1d3fc2 100644 --- a/trunk/arch/x86/lguest/boot.c +++ b/trunk/arch/x86/lguest/boot.c @@ -115,7 +115,7 @@ static void async_hcall(unsigned long call, unsigned long arg1, local_irq_save(flags); if (lguest_data.hcall_status[next_call] != 0xFF) { /* Table full, so do normal hcall which will flush table. */ - hcall(call, arg1, arg2, arg3, arg4); + kvm_hypercall4(call, arg1, arg2, arg3, arg4); } else { lguest_data.hcalls[next_call].arg0 = call; lguest_data.hcalls[next_call].arg1 = arg1; @@ -145,45 +145,46 @@ static void async_hcall(unsigned long call, unsigned long arg1, * So, when we're in lazy mode, we call async_hcall() to store the call for * future processing: */ -static void lazy_hcall1(unsigned long call, unsigned long arg1) +static void lazy_hcall1(unsigned long call, + unsigned long arg1) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - hcall(call, arg1, 0, 0, 0); + kvm_hypercall1(call, arg1); else async_hcall(call, arg1, 0, 0, 0); } /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/ static void lazy_hcall2(unsigned long call, - unsigned long arg1, - unsigned long arg2) + unsigned long arg1, + unsigned long arg2) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - hcall(call, arg1, arg2, 0, 0); + kvm_hypercall2(call, arg1, arg2); else async_hcall(call, arg1, arg2, 0, 0); } static void lazy_hcall3(unsigned long call, - unsigned long arg1, - unsigned long arg2, - unsigned long arg3) + unsigned long arg1, + unsigned long arg2, + unsigned long arg3) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - hcall(call, arg1, arg2, arg3, 0); + kvm_hypercall3(call, arg1, arg2, arg3); else async_hcall(call, arg1, arg2, arg3, 0); } #ifdef CONFIG_X86_PAE static void lazy_hcall4(unsigned long call, - unsigned long arg1, - unsigned long arg2, - unsigned long arg3, - unsigned long arg4) + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - hcall(call, arg1, arg2, arg3, arg4); + kvm_hypercall4(call, arg1, arg2, arg3, arg4); else async_hcall(call, arg1, arg2, arg3, arg4); } @@ -195,13 +196,13 @@ static void lazy_hcall4(unsigned long call, :*/ static void lguest_leave_lazy_mmu_mode(void) { - hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); + kvm_hypercall0(LHCALL_FLUSH_ASYNC); paravirt_leave_lazy_mmu(); } static void lguest_end_context_switch(struct task_struct *next) { - hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); + kvm_hypercall0(LHCALL_FLUSH_ASYNC); paravirt_end_context_switch(next); } @@ -285,7 +286,7 @@ static void lguest_write_idt_entry(gate_desc *dt, /* Keep the local copy up to date. */ native_write_idt_entry(dt, entrynum, g); /* Tell Host about this new entry. */ - hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0); + kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); } /* @@ -299,7 +300,7 @@ static void lguest_load_idt(const struct desc_ptr *desc) struct desc_struct *idt = (void *)desc->address; for (i = 0; i < (desc->size+1)/8; i++) - hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0); + kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b); } /* @@ -320,7 +321,7 @@ static void lguest_load_gdt(const struct desc_ptr *desc) struct desc_struct *gdt = (void *)desc->address; for (i = 0; i < (desc->size+1)/8; i++) - hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0); + kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b); } /* @@ -333,8 +334,8 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, { native_write_gdt_entry(dt, entrynum, desc, type); /* Tell Host about this new entry. */ - hcall(LHCALL_LOAD_GDT_ENTRY, entrynum, - dt[entrynum].a, dt[entrynum].b, 0); + kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum, + dt[entrynum].a, dt[entrynum].b); } /* @@ -930,7 +931,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta, } /* Please wake us this far in the future. */ - hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0); + kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta); return 0; } @@ -941,7 +942,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: /* A 0 argument shuts the clock down. */ - hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0); + kvm_hypercall0(LHCALL_SET_CLOCKEVENT); break; case CLOCK_EVT_MODE_ONESHOT: /* This is what we expect. */ @@ -1099,7 +1100,7 @@ static void set_lguest_basic_apic_ops(void) /* STOP! Until an interrupt comes in. */ static void lguest_safe_halt(void) { - hcall(LHCALL_HALT, 0, 0, 0, 0); + kvm_hypercall0(LHCALL_HALT); } /* @@ -1111,8 +1112,8 @@ static void lguest_safe_halt(void) */ static void lguest_power_off(void) { - hcall(LHCALL_SHUTDOWN, __pa("Power down"), - LGUEST_SHUTDOWN_POWEROFF, 0, 0); + kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"), + LGUEST_SHUTDOWN_POWEROFF); } /* @@ -1122,7 +1123,7 @@ static void lguest_power_off(void) */ static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) { - hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0); + kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF); /* The hcall won't return, but to keep gcc happy, we're "done". */ return NOTIFY_DONE; } @@ -1161,7 +1162,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) len = sizeof(scratch) - 1; scratch[len] = '\0'; memcpy(scratch, buf, len); - hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0); + kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch)); /* This routine returns the number of bytes actually written. */ return len; @@ -1173,7 +1174,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) */ static void lguest_restart(char *reason) { - hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0); + kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART); } /*G:050 diff --git a/trunk/arch/x86/lguest/i386_head.S b/trunk/arch/x86/lguest/i386_head.S index 4f420c2f2d55..27eac0faee48 100644 --- a/trunk/arch/x86/lguest/i386_head.S +++ b/trunk/arch/x86/lguest/i386_head.S @@ -32,7 +32,7 @@ ENTRY(lguest_entry) */ movl $LHCALL_LGUEST_INIT, %eax movl $lguest_data - __PAGE_OFFSET, %ebx - int $LGUEST_TRAP_ENTRY + .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */ /* Set up the initial stack so we can run C code. */ movl $(init_thread_union+THREAD_SIZE),%esp diff --git a/trunk/drivers/hwmon/applesmc.c b/trunk/drivers/hwmon/applesmc.c index 0f28d91f29d8..c1605b528e8f 100644 --- a/trunk/drivers/hwmon/applesmc.c +++ b/trunk/drivers/hwmon/applesmc.c @@ -142,12 +142,6 @@ static const char *temperature_sensors_sets[][41] = { "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S", "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S", NULL }, -/* Set 17: iMac 9,1 */ - { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P", - "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL }, -/* Set 18: MacBook Pro 2,2 */ - { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0", - "Th0H", "Th1H", "Tm0P", "Ts0P", NULL }, }; /* List of keys used to read/write fan speeds */ @@ -1356,10 +1350,6 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { { .accelerometer = 1, .light = 1, .temperature_set = 15 }, /* MacPro3,1: temperature set 16 */ { .accelerometer = 0, .light = 0, .temperature_set = 16 }, -/* iMac 9,1: light sensor only, temperature set 17 */ - { .accelerometer = 0, .light = 0, .temperature_set = 17 }, -/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ - { .accelerometer = 1, .light = 1, .temperature_set = 18 }, }; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". @@ -1385,10 +1375,6 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, &applesmc_dmi_data[9]}, - { applesmc_dmi_match, "Apple MacBook Pro 2,2", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") }, - &applesmc_dmi_data[18]}, { applesmc_dmi_match, "Apple MacBook Pro", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, @@ -1429,10 +1415,6 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, &applesmc_dmi_data[4]}, - { applesmc_dmi_match, "Apple iMac 9,1", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") }, - &applesmc_dmi_data[17]}, { applesmc_dmi_match, "Apple iMac 8", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, diff --git a/trunk/drivers/hwmon/it87.c b/trunk/drivers/hwmon/it87.c index 5be09c048c5f..1002befd87d5 100644 --- a/trunk/drivers/hwmon/it87.c +++ b/trunk/drivers/hwmon/it87.c @@ -539,14 +539,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); long val; - u8 reg; if (strict_strtol(buf, 10, &val) < 0) return -EINVAL; - reg = it87_read_value(data, IT87_REG_TEMP_ENABLE); - reg &= ~(1 << nr); - reg &= ~(8 << nr); + mutex_lock(&data->update_lock); + + data->sensor &= ~(1 << nr); + data->sensor &= ~(8 << nr); if (val == 2) { /* backwards compatibility */ dev_warn(dev, "Sensor type 2 is deprecated, please use 4 " "instead\n"); @@ -554,16 +554,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, } /* 3 = thermal diode; 4 = thermistor; 0 = disabled */ if (val == 3) - reg |= 1 << nr; + data->sensor |= 1 << nr; else if (val == 4) - reg |= 8 << nr; - else if (val != 0) + data->sensor |= 8 << nr; + else if (val != 0) { + mutex_unlock(&data->update_lock); return -EINVAL; - - mutex_lock(&data->update_lock); - data->sensor = reg; + } it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); - data->valid = 0; /* Force cache refresh */ mutex_unlock(&data->update_lock); return count; } @@ -1843,10 +1841,14 @@ static void __devinit it87_init_device(struct platform_device *pdev) it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); } - /* Temperature channels are not forcibly enabled, as they can be - * set to two different sensor types and we can't guess which one - * is correct for a given system. These channels can be enabled at - * run-time through the temp{1-3}_type sysfs accessors if needed. */ + /* Check if temperature channels are reset manually or by some reason */ + tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE); + if ((tmp & 0x3f) == 0) { + /* Temp1,Temp3=thermistor; Temp2=thermal diode */ + tmp = (tmp & 0xc0) | 0x2a; + it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp); + } + data->sensor = tmp; /* Check if voltage monitors are reset manually or by some reason */ tmp = it87_read_value(data, IT87_REG_VIN_ENABLE); diff --git a/trunk/drivers/hwmon/sht15.c b/trunk/drivers/hwmon/sht15.c index a610e7880fb3..6b2d8ae64fe1 100644 --- a/trunk/drivers/hwmon/sht15.c +++ b/trunk/drivers/hwmon/sht15.c @@ -303,13 +303,13 @@ static int sht15_update_vals(struct sht15_data *data) **/ static inline int sht15_calc_temp(struct sht15_data *data) { - int d1 = temppoints[0].d1; + int d1 = 0; int i; - for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--) + for (i = 1; i < ARRAY_SIZE(temppoints); i++) /* Find pointer to interpolate */ if (data->supply_uV > temppoints[i - 1].vdd) { - d1 = (data->supply_uV - temppoints[i - 1].vdd) + d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd) * (temppoints[i].d1 - temppoints[i - 1].d1) / (temppoints[i].vdd - temppoints[i - 1].vdd) + temppoints[i - 1].d1; @@ -542,12 +542,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) /* If a regulator is available, query what the supply voltage actually is!*/ data->reg = regulator_get(data->dev, "vcc"); if (!IS_ERR(data->reg)) { - int voltage; - - voltage = regulator_get_voltage(data->reg); - if (voltage) - data->supply_uV = voltage; - + data->supply_uV = regulator_get_voltage(data->reg); regulator_enable(data->reg); /* setup a notifier block to update this if another device * causes the voltage to change */ diff --git a/trunk/drivers/lguest/lguest_device.c b/trunk/drivers/lguest/lguest_device.c index 69c84a1d88ea..07090f379c63 100644 --- a/trunk/drivers/lguest/lguest_device.c +++ b/trunk/drivers/lguest/lguest_device.c @@ -178,7 +178,7 @@ static void set_status(struct virtio_device *vdev, u8 status) /* We set the status. */ to_lgdev(vdev)->desc->status = status; - hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0); + kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset); } static void lg_set_status(struct virtio_device *vdev, u8 status) @@ -229,7 +229,7 @@ static void lg_notify(struct virtqueue *vq) */ struct lguest_vq_info *lvq = vq->priv; - hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0); + kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT); } /* An extern declaration inside a C file is bad form. Don't do it. */ diff --git a/trunk/drivers/lguest/x86/core.c b/trunk/drivers/lguest/x86/core.c index b4eb675a807e..fb2b7ef7868e 100644 --- a/trunk/drivers/lguest/x86/core.c +++ b/trunk/drivers/lguest/x86/core.c @@ -287,18 +287,6 @@ static int emulate_insn(struct lg_cpu *cpu) /* Decoding x86 instructions is icky. */ insn = lgread(cpu, physaddr, u8); - /* - * Around 2.6.33, the kernel started using an emulation for the - * cmpxchg8b instruction in early boot on many configurations. This - * code isn't paravirtualized, and it tries to disable interrupts. - * Ignore it, which will Mostly Work. - */ - if (insn == 0xfa) { - /* "cli", or Clear Interrupt Enable instruction. Skip it. */ - cpu->regs->eip++; - return 1; - } - /* * 0x66 is an "operand prefix". It means it's using the upper 16 bits * of the eax register. diff --git a/trunk/fs/ceph/addr.c b/trunk/fs/ceph/addr.c index 412593703d1e..aa3cd7cc3e40 100644 --- a/trunk/fs/ceph/addr.c +++ b/trunk/fs/ceph/addr.c @@ -337,15 +337,16 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, /* * Get ref for the oldest snapc for an inode with dirty data... that is, the * only snap context we are allowed to write back. + * + * Caller holds i_lock. */ -static struct ceph_snap_context *get_oldest_context(struct inode *inode, - u64 *snap_size) +static struct ceph_snap_context *__get_oldest_context(struct inode *inode, + u64 *snap_size) { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_snap_context *snapc = NULL; struct ceph_cap_snap *capsnap = NULL; - spin_lock(&inode->i_lock); list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap, capsnap->context, capsnap->dirty_pages); @@ -356,11 +357,21 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode, break; } } - if (!snapc && ci->i_head_snapc) { - snapc = ceph_get_snap_context(ci->i_head_snapc); + if (!snapc && ci->i_snap_realm) { + snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context); dout(" head snapc %p has %d dirty pages\n", snapc, ci->i_wrbuffer_ref_head); } + return snapc; +} + +static struct ceph_snap_context *get_oldest_context(struct inode *inode, + u64 *snap_size) +{ + struct ceph_snap_context *snapc = NULL; + + spin_lock(&inode->i_lock); + snapc = __get_oldest_context(inode, snap_size); spin_unlock(&inode->i_lock); return snapc; } @@ -381,7 +392,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) int len = PAGE_CACHE_SIZE; loff_t i_size; int err = 0; - struct ceph_snap_context *snapc, *oldest; + struct ceph_snap_context *snapc; u64 snap_size = 0; long writeback_stat; @@ -402,16 +413,13 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) dout("writepage %p page %p not dirty?\n", inode, page); goto out; } - oldest = get_oldest_context(inode, &snap_size); - if (snapc->seq > oldest->seq) { + if (snapc != get_oldest_context(inode, &snap_size)) { dout("writepage %p page %p snapc %p not writeable - noop\n", inode, page, (void *)page->private); /* we should only noop if called by kswapd */ WARN_ON((current->flags & PF_MEMALLOC) == 0); - ceph_put_snap_context(oldest); goto out; } - ceph_put_snap_context(oldest); /* is this a partial page at end of file? */ if (snap_size) @@ -450,7 +458,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) ClearPagePrivate(page); end_page_writeback(page); ceph_put_wrbuffer_cap_refs(ci, 1, snapc); - ceph_put_snap_context(snapc); /* page's reference */ + ceph_put_snap_context(snapc); out: return err; } @@ -550,9 +558,9 @@ static void writepages_finish(struct ceph_osd_request *req, dout("inode %p skipping page %p\n", inode, page); wbc->pages_skipped++; } - ceph_put_snap_context((void *)page->private); page->private = 0; ClearPagePrivate(page); + ceph_put_snap_context(snapc); dout("unlocking %d %p\n", i, page); end_page_writeback(page); @@ -610,7 +618,7 @@ static int ceph_writepages_start(struct address_space *mapping, int range_whole = 0; int should_loop = 1; pgoff_t max_pages = 0, max_pages_ever = 0; - struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc; + struct ceph_snap_context *snapc = NULL, *last_snapc = NULL; struct pagevec pvec; int done = 0; int rc = 0; @@ -762,10 +770,9 @@ static int ceph_writepages_start(struct address_space *mapping, } /* only if matching snap context */ - pgsnapc = (void *)page->private; - if (pgsnapc->seq > snapc->seq) { - dout("page snapc %p %lld > oldest %p %lld\n", - pgsnapc, pgsnapc->seq, snapc, snapc->seq); + if (snapc != (void *)page->private) { + dout("page snapc %p != oldest %p\n", + (void *)page->private, snapc); unlock_page(page); if (!locked_pages) continue; /* keep looking for snap */ @@ -907,10 +914,7 @@ static int context_is_writeable_or_written(struct inode *inode, struct ceph_snap_context *snapc) { struct ceph_snap_context *oldest = get_oldest_context(inode, NULL); - int ret = !oldest || snapc->seq <= oldest->seq; - - ceph_put_snap_context(oldest); - return ret; + return !oldest || snapc->seq <= oldest->seq; } /* @@ -932,8 +936,8 @@ static int ceph_update_writeable_page(struct file *file, int pos_in_page = pos & ~PAGE_CACHE_MASK; int end_in_page = pos_in_page + len; loff_t i_size; + struct ceph_snap_context *snapc; int r; - struct ceph_snap_context *snapc, *oldest; retry_locked: /* writepages currently holds page lock, but if we change that later, */ @@ -943,24 +947,23 @@ static int ceph_update_writeable_page(struct file *file, BUG_ON(!ci->i_snap_realm); down_read(&mdsc->snap_rwsem); BUG_ON(!ci->i_snap_realm->cached_context); - snapc = (void *)page->private; - if (snapc && snapc != ci->i_head_snapc) { + if (page->private && + (void *)page->private != ci->i_snap_realm->cached_context) { /* * this page is already dirty in another (older) snap * context! is it writeable now? */ - oldest = get_oldest_context(inode, NULL); + snapc = get_oldest_context(inode, NULL); up_read(&mdsc->snap_rwsem); - if (snapc->seq > oldest->seq) { - ceph_put_snap_context(oldest); + if (snapc != (void *)page->private) { dout(" page %p snapc %p not current or oldest\n", - page, snapc); + page, (void *)page->private); /* * queue for writeback, and wait for snapc to * be writeable or written */ - snapc = ceph_get_snap_context(snapc); + snapc = ceph_get_snap_context((void *)page->private); unlock_page(page); ceph_queue_writeback(inode); r = wait_event_interruptible(ci->i_cap_wq, @@ -970,7 +973,6 @@ static int ceph_update_writeable_page(struct file *file, return r; return -EAGAIN; } - ceph_put_snap_context(oldest); /* yay, writeable, do it now (without dropping page lock) */ dout(" page %p snapc %p not current, but oldest\n", diff --git a/trunk/fs/ceph/caps.c b/trunk/fs/ceph/caps.c index aa2239fa9a3b..3710e077a857 100644 --- a/trunk/fs/ceph/caps.c +++ b/trunk/fs/ceph/caps.c @@ -1205,12 +1205,6 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci, if (capsnap->dirty_pages || capsnap->writing) continue; - /* - * if cap writeback already occurred, we should have dropped - * the capsnap in ceph_put_wrbuffer_cap_refs. - */ - BUG_ON(capsnap->dirty == 0); - /* pick mds, take s_mutex */ mds = __ceph_get_cap_mds(ci, &mseq); if (session && session->s_mds != mds) { @@ -2124,8 +2118,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) } spin_unlock(&inode->i_lock); - dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had), - last ? " last" : "", put ? " put" : ""); + dout("put_cap_refs %p had %s %s\n", inode, ceph_cap_string(had), + last ? "last" : ""); if (last && !flushsnaps) ceph_check_caps(ci, 0, NULL); @@ -2149,8 +2143,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, { struct inode *inode = &ci->vfs_inode; int last = 0; - int complete_capsnap = 0; - int drop_capsnap = 0; + int last_snap = 0; int found = 0; struct ceph_cap_snap *capsnap = NULL; @@ -2173,32 +2166,19 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { if (capsnap->context == snapc) { found = 1; + capsnap->dirty_pages -= nr; + last_snap = !capsnap->dirty_pages; break; } } BUG_ON(!found); - capsnap->dirty_pages -= nr; - if (capsnap->dirty_pages == 0) { - complete_capsnap = 1; - if (capsnap->dirty == 0) - /* cap writeback completed before we created - * the cap_snap; no FLUSHSNAP is needed */ - drop_capsnap = 1; - } dout("put_wrbuffer_cap_refs on %p cap_snap %p " - " snap %lld %d/%d -> %d/%d %s%s%s\n", + " snap %lld %d/%d -> %d/%d %s%s\n", inode, capsnap, capsnap->context->seq, ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr, ci->i_wrbuffer_ref, capsnap->dirty_pages, last ? " (wrbuffer last)" : "", - complete_capsnap ? " (complete capsnap)" : "", - drop_capsnap ? " (drop capsnap)" : ""); - if (drop_capsnap) { - ceph_put_snap_context(capsnap->context); - list_del(&capsnap->ci_item); - list_del(&capsnap->flushing_item); - ceph_put_cap_snap(capsnap); - } + last_snap ? " (capsnap last)" : ""); } spin_unlock(&inode->i_lock); @@ -2206,12 +2186,10 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, if (last) { ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); iput(inode); - } else if (complete_capsnap) { + } else if (last_snap) { ceph_flush_snaps(ci); wake_up(&ci->i_cap_wq); } - if (drop_capsnap) - iput(inode); } /* @@ -2487,8 +2465,8 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, break; } WARN_ON(capsnap->dirty_pages || capsnap->writing); - dout(" removing %p cap_snap %p follows %lld\n", - inode, capsnap, follows); + dout(" removing cap_snap %p follows %lld\n", + capsnap, follows); ceph_put_snap_context(capsnap->context); list_del(&capsnap->ci_item); list_del(&capsnap->flushing_item); diff --git a/trunk/fs/ceph/dir.c b/trunk/fs/ceph/dir.c index ea8ee2e526aa..7261dc6c2ead 100644 --- a/trunk/fs/ceph/dir.c +++ b/trunk/fs/ceph/dir.c @@ -171,11 +171,11 @@ static int __dcache_readdir(struct file *filp, spin_lock(&inode->i_lock); spin_lock(&dcache_lock); - last = dentry; - if (err < 0) goto out_unlock; + last = dentry; + p = p->prev; filp->f_pos++; @@ -312,7 +312,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) req->r_readdir_offset = fi->next_offset; req->r_args.readdir.frag = cpu_to_le32(frag); req->r_args.readdir.max_entries = cpu_to_le32(max_entries); - req->r_num_caps = max_entries + 1; + req->r_num_caps = max_entries; err = ceph_mdsc_do_request(mdsc, NULL, req); if (err < 0) { ceph_mdsc_put_request(req); @@ -489,7 +489,6 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, struct inode *inode = ceph_get_snapdir(parent); dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n", dentry, dentry->d_name.len, dentry->d_name.name, inode); - BUG_ON(!d_unhashed(dentry)); d_add(dentry, inode); err = 0; } diff --git a/trunk/fs/ceph/inode.c b/trunk/fs/ceph/inode.c index 26f883c275e8..aca82d55cc53 100644 --- a/trunk/fs/ceph/inode.c +++ b/trunk/fs/ceph/inode.c @@ -886,7 +886,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, struct inode *in = NULL; struct ceph_mds_reply_inode *ininfo; struct ceph_vino vino; - struct ceph_client *client = ceph_sb_to_client(sb); int i = 0; int err = 0; @@ -950,14 +949,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, return err; } - /* - * ignore null lease/binding on snapdir ENOENT, or else we - * will have trouble splicing in the virtual snapdir later - */ - if (rinfo->head->is_dentry && !req->r_aborted && - (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name, - client->mount_args->snapdir_name, - req->r_dentry->d_name.len))) { + if (rinfo->head->is_dentry && !req->r_aborted) { /* * lookup link rename : null -> possibly existing inode * mknod symlink mkdir : null -> new inode diff --git a/trunk/fs/ceph/messenger.c b/trunk/fs/ceph/messenger.c index cdaaa131add3..8f1715ffbe4b 100644 --- a/trunk/fs/ceph/messenger.c +++ b/trunk/fs/ceph/messenger.c @@ -30,10 +30,6 @@ static char tag_msg = CEPH_MSGR_TAG_MSG; static char tag_ack = CEPH_MSGR_TAG_ACK; static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE; -#ifdef CONFIG_LOCKDEP -static struct lock_class_key socket_class; -#endif - static void queue_con(struct ceph_connection *con); static void con_work(struct work_struct *); @@ -232,10 +228,6 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con) con->sock = sock; sock->sk->sk_allocation = GFP_NOFS; -#ifdef CONFIG_LOCKDEP - lockdep_set_class(&sock->sk->sk_lock, &socket_class); -#endif - set_sock_callbacks(sock, con); dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); @@ -341,7 +333,6 @@ static void reset_connection(struct ceph_connection *con) con->out_msg = NULL; } con->in_seq = 0; - con->in_seq_acked = 0; } /* diff --git a/trunk/fs/ceph/osdmap.c b/trunk/fs/ceph/osdmap.c index 2e2c15eed82a..21c6623c4b07 100644 --- a/trunk/fs/ceph/osdmap.c +++ b/trunk/fs/ceph/osdmap.c @@ -314,6 +314,71 @@ static struct crush_map *crush_decode(void *pbyval, void *end) return ERR_PTR(err); } + +/* + * osd map + */ +void ceph_osdmap_destroy(struct ceph_osdmap *map) +{ + dout("osdmap_destroy %p\n", map); + if (map->crush) + crush_destroy(map->crush); + while (!RB_EMPTY_ROOT(&map->pg_temp)) { + struct ceph_pg_mapping *pg = + rb_entry(rb_first(&map->pg_temp), + struct ceph_pg_mapping, node); + rb_erase(&pg->node, &map->pg_temp); + kfree(pg); + } + while (!RB_EMPTY_ROOT(&map->pg_pools)) { + struct ceph_pg_pool_info *pi = + rb_entry(rb_first(&map->pg_pools), + struct ceph_pg_pool_info, node); + rb_erase(&pi->node, &map->pg_pools); + kfree(pi); + } + kfree(map->osd_state); + kfree(map->osd_weight); + kfree(map->osd_addr); + kfree(map); +} + +/* + * adjust max osd value. reallocate arrays. + */ +static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) +{ + u8 *state; + struct ceph_entity_addr *addr; + u32 *weight; + + state = kcalloc(max, sizeof(*state), GFP_NOFS); + addr = kcalloc(max, sizeof(*addr), GFP_NOFS); + weight = kcalloc(max, sizeof(*weight), GFP_NOFS); + if (state == NULL || addr == NULL || weight == NULL) { + kfree(state); + kfree(addr); + kfree(weight); + return -ENOMEM; + } + + /* copy old? */ + if (map->osd_state) { + memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); + memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); + memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); + kfree(map->osd_state); + kfree(map->osd_addr); + kfree(map->osd_weight); + } + + map->osd_state = state; + map->osd_weight = weight; + map->osd_addr = addr; + map->max_osd = max; + return 0; +} + /* * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid * to a set of osds) @@ -417,13 +482,6 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id) return NULL; } -static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi) -{ - rb_erase(&pi->node, root); - kfree(pi->name); - kfree(pi); -} - void __decode_pool(void **p, struct ceph_pg_pool_info *pi) { ceph_decode_copy(p, &pi->v, sizeof(pi->v)); @@ -432,98 +490,6 @@ void __decode_pool(void **p, struct ceph_pg_pool_info *pi) *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; } -static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map) -{ - struct ceph_pg_pool_info *pi; - u32 num, len, pool; - - ceph_decode_32_safe(p, end, num, bad); - dout(" %d pool names\n", num); - while (num--) { - ceph_decode_32_safe(p, end, pool, bad); - ceph_decode_32_safe(p, end, len, bad); - dout(" pool %d len %d\n", pool, len); - pi = __lookup_pg_pool(&map->pg_pools, pool); - if (pi) { - kfree(pi->name); - pi->name = kmalloc(len + 1, GFP_NOFS); - if (pi->name) { - memcpy(pi->name, *p, len); - pi->name[len] = '\0'; - dout(" name is %s\n", pi->name); - } - } - *p += len; - } - return 0; - -bad: - return -EINVAL; -} - -/* - * osd map - */ -void ceph_osdmap_destroy(struct ceph_osdmap *map) -{ - dout("osdmap_destroy %p\n", map); - if (map->crush) - crush_destroy(map->crush); - while (!RB_EMPTY_ROOT(&map->pg_temp)) { - struct ceph_pg_mapping *pg = - rb_entry(rb_first(&map->pg_temp), - struct ceph_pg_mapping, node); - rb_erase(&pg->node, &map->pg_temp); - kfree(pg); - } - while (!RB_EMPTY_ROOT(&map->pg_pools)) { - struct ceph_pg_pool_info *pi = - rb_entry(rb_first(&map->pg_pools), - struct ceph_pg_pool_info, node); - __remove_pg_pool(&map->pg_pools, pi); - } - kfree(map->osd_state); - kfree(map->osd_weight); - kfree(map->osd_addr); - kfree(map); -} - -/* - * adjust max osd value. reallocate arrays. - */ -static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) -{ - u8 *state; - struct ceph_entity_addr *addr; - u32 *weight; - - state = kcalloc(max, sizeof(*state), GFP_NOFS); - addr = kcalloc(max, sizeof(*addr), GFP_NOFS); - weight = kcalloc(max, sizeof(*weight), GFP_NOFS); - if (state == NULL || addr == NULL || weight == NULL) { - kfree(state); - kfree(addr); - kfree(weight); - return -ENOMEM; - } - - /* copy old? */ - if (map->osd_state) { - memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); - memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); - memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); - kfree(map->osd_state); - kfree(map->osd_addr); - kfree(map->osd_weight); - } - - map->osd_state = state; - map->osd_weight = weight; - map->osd_addr = addr; - map->max_osd = max; - return 0; -} - /* * decode a full map. */ @@ -560,7 +526,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_32_safe(p, end, max, bad); while (max--) { ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); - pi = kzalloc(sizeof(*pi), GFP_NOFS); + pi = kmalloc(sizeof(*pi), GFP_NOFS); if (!pi) goto bad; pi->id = ceph_decode_32(p); @@ -573,10 +539,6 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) __decode_pool(p, pi); __insert_pg_pool(&map->pg_pools, pi); } - - if (version >= 5 && __decode_pool_names(p, end, map) < 0) - goto bad; - ceph_decode_32_safe(p, end, map->pool_max, bad); ceph_decode_32_safe(p, end, map->flags, bad); @@ -750,7 +712,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, } pi = __lookup_pg_pool(&map->pg_pools, pool); if (!pi) { - pi = kzalloc(sizeof(*pi), GFP_NOFS); + pi = kmalloc(sizeof(*pi), GFP_NOFS); if (!pi) { err = -ENOMEM; goto bad; @@ -760,8 +722,6 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, } __decode_pool(p, pi); } - if (version >= 5 && __decode_pool_names(p, end, map) < 0) - goto bad; /* old_pool */ ceph_decode_32_safe(p, end, len, bad); @@ -770,8 +730,10 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ceph_decode_32_safe(p, end, pool, bad); pi = __lookup_pg_pool(&map->pg_pools, pool); - if (pi) - __remove_pg_pool(&map->pg_pools, pi); + if (pi) { + rb_erase(&pi->node, &map->pg_pools); + kfree(pi); + } } /* new_up */ diff --git a/trunk/fs/ceph/osdmap.h b/trunk/fs/ceph/osdmap.h index 8bc9f1e4f562..1fb55afb2642 100644 --- a/trunk/fs/ceph/osdmap.h +++ b/trunk/fs/ceph/osdmap.h @@ -23,7 +23,6 @@ struct ceph_pg_pool_info { int id; struct ceph_pg_pool v; int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; - char *name; }; struct ceph_pg_mapping { diff --git a/trunk/fs/ceph/rados.h b/trunk/fs/ceph/rados.h index a1fc1d017b58..26ac8b89a676 100644 --- a/trunk/fs/ceph/rados.h +++ b/trunk/fs/ceph/rados.h @@ -11,10 +11,8 @@ /* * osdmap encoding versions */ -#define CEPH_OSDMAP_INC_VERSION 5 -#define CEPH_OSDMAP_INC_VERSION_EXT 5 -#define CEPH_OSDMAP_VERSION 5 -#define CEPH_OSDMAP_VERSION_EXT 5 +#define CEPH_OSDMAP_INC_VERSION 4 +#define CEPH_OSDMAP_VERSION 4 /* * fs id diff --git a/trunk/fs/ceph/snap.c b/trunk/fs/ceph/snap.c index 2b881262ef67..e6f9bc57d472 100644 --- a/trunk/fs/ceph/snap.c +++ b/trunk/fs/ceph/snap.c @@ -431,7 +431,8 @@ static int dup_array(u64 **dst, __le64 *src, int num) * Caller must hold snap_rwsem for read (i.e., the realm topology won't * change). */ -void ceph_queue_cap_snap(struct ceph_inode_info *ci) +void ceph_queue_cap_snap(struct ceph_inode_info *ci, + struct ceph_snap_context *snapc) { struct inode *inode = &ci->vfs_inode; struct ceph_cap_snap *capsnap; @@ -450,11 +451,10 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) as no new writes are allowed to start when pending, so any writes in progress now were started before the previous cap_snap. lucky us. */ - dout("queue_cap_snap %p already pending\n", inode); + dout("queue_cap_snap %p snapc %p seq %llu used %d" + " already pending\n", inode, snapc, snapc->seq, used); kfree(capsnap); } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { - struct ceph_snap_context *snapc = ci->i_head_snapc; - igrab(inode); atomic_set(&capsnap->nref, 1); @@ -463,6 +463,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) INIT_LIST_HEAD(&capsnap->flushing_item); capsnap->follows = snapc->seq - 1; + capsnap->context = ceph_get_snap_context(snapc); capsnap->issued = __ceph_caps_issued(ci, NULL); capsnap->dirty = __ceph_caps_dirty(ci); @@ -479,7 +480,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) snapshot. */ capsnap->dirty_pages = ci->i_wrbuffer_ref_head; ci->i_wrbuffer_ref_head = 0; - capsnap->context = snapc; + ceph_put_snap_context(ci->i_head_snapc); ci->i_head_snapc = NULL; list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); @@ -521,17 +522,15 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci, capsnap->ctime = inode->i_ctime; capsnap->time_warp_seq = ci->i_time_warp_seq; if (capsnap->dirty_pages) { - dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu " + dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu " "still has %d dirty pages\n", inode, capsnap, capsnap->context, capsnap->context->seq, - ceph_cap_string(capsnap->dirty), capsnap->size, - capsnap->dirty_pages); + capsnap->size, capsnap->dirty_pages); return 0; } - dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n", + dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu clean\n", inode, capsnap, capsnap->context, - capsnap->context->seq, ceph_cap_string(capsnap->dirty), - capsnap->size); + capsnap->context->seq, capsnap->size); spin_lock(&mdsc->snap_flush_lock); list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list); @@ -603,7 +602,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, if (lastinode) iput(lastinode); lastinode = inode; - ceph_queue_cap_snap(ci); + ceph_queue_cap_snap(ci, realm->cached_context); spin_lock(&realm->inodes_with_caps_lock); } spin_unlock(&realm->inodes_with_caps_lock); @@ -825,7 +824,8 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, spin_unlock(&realm->inodes_with_caps_lock); spin_unlock(&inode->i_lock); - ceph_queue_cap_snap(ci); + ceph_queue_cap_snap(ci, + ci->i_snap_realm->cached_context); iput(inode); continue; diff --git a/trunk/fs/ceph/super.h b/trunk/fs/ceph/super.h index e30dfbb056c3..ca702c67bc66 100644 --- a/trunk/fs/ceph/super.h +++ b/trunk/fs/ceph/super.h @@ -715,7 +715,8 @@ extern int ceph_update_snap_trace(struct ceph_mds_client *m, extern void ceph_handle_snap(struct ceph_mds_client *mdsc, struct ceph_mds_session *session, struct ceph_msg *msg); -extern void ceph_queue_cap_snap(struct ceph_inode_info *ci); +extern void ceph_queue_cap_snap(struct ceph_inode_info *ci, + struct ceph_snap_context *snapc); extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci, struct ceph_cap_snap *capsnap); extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc); diff --git a/trunk/lib/vsprintf.c b/trunk/lib/vsprintf.c index 7376b7c55ffe..24112e5a5780 100644 --- a/trunk/lib/vsprintf.c +++ b/trunk/lib/vsprintf.c @@ -408,12 +408,12 @@ enum format_type { }; struct printf_spec { - u8 type; /* format_type enum */ - u8 flags; /* flags to number() */ - u8 base; /* number base, 8, 10 or 16 only */ - u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */ + u16 type; s16 field_width; /* width of output field */ - s16 precision; /* # of digits/chars */ + u8 flags; /* flags to number() */ + u8 base; + s8 precision; /* # of digits/chars */ + u8 qualifier; }; static char *number(char *buf, char *end, unsigned long long num, diff --git a/trunk/security/selinux/ss/avtab.h b/trunk/security/selinux/ss/avtab.h index 8da6a8428086..cd4f734e2749 100644 --- a/trunk/security/selinux/ss/avtab.h +++ b/trunk/security/selinux/ss/avtab.h @@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified void avtab_cache_init(void); void avtab_cache_destroy(void); -#define MAX_AVTAB_HASH_BITS 13 +#define MAX_AVTAB_HASH_BITS 11 #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) #define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) #define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS