diff options
89 files changed, 1227 insertions, 817 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index f2668390e8f7..42008395534d 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
| @@ -62,8 +62,8 @@ typedef uint8_t u8; | |||
| 62 | #endif | 62 | #endif |
| 63 | /* We can have up to 256 pages for devices. */ | 63 | /* We can have up to 256 pages for devices. */ |
| 64 | #define DEVICE_PAGES 256 | 64 | #define DEVICE_PAGES 256 |
| 65 | /* This fits nicely in a single 4096-byte page. */ | 65 | /* This will occupy 2 pages: it must be a power of 2. */ |
| 66 | #define VIRTQUEUE_NUM 127 | 66 | #define VIRTQUEUE_NUM 128 |
| 67 | 67 | ||
| 68 | /*L:120 verbose is both a global flag and a macro. The C preprocessor allows | 68 | /*L:120 verbose is both a global flag and a macro. The C preprocessor allows |
| 69 | * this, and although I wouldn't recommend it, it works quite nicely here. */ | 69 | * this, and although I wouldn't recommend it, it works quite nicely here. */ |
| @@ -1036,7 +1036,8 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, | |||
| 1036 | void *p; | 1036 | void *p; |
| 1037 | 1037 | ||
| 1038 | /* First we need some pages for this virtqueue. */ | 1038 | /* First we need some pages for this virtqueue. */ |
| 1039 | pages = (vring_size(num_descs) + getpagesize() - 1) / getpagesize(); | 1039 | pages = (vring_size(num_descs, getpagesize()) + getpagesize() - 1) |
| 1040 | / getpagesize(); | ||
| 1040 | p = get_pages(pages); | 1041 | p = get_pages(pages); |
| 1041 | 1042 | ||
| 1042 | /* Initialize the configuration. */ | 1043 | /* Initialize the configuration. */ |
| @@ -1045,7 +1046,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, | |||
| 1045 | vq->config.pfn = to_guest_phys(p) / getpagesize(); | 1046 | vq->config.pfn = to_guest_phys(p) / getpagesize(); |
| 1046 | 1047 | ||
| 1047 | /* Initialize the vring. */ | 1048 | /* Initialize the vring. */ |
| 1048 | vring_init(&vq->vring, num_descs, p); | 1049 | vring_init(&vq->vring, num_descs, p, getpagesize()); |
| 1049 | 1050 | ||
| 1050 | /* Add the configuration information to this device's descriptor. */ | 1051 | /* Add the configuration information to this device's descriptor. */ |
| 1051 | add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE, | 1052 | add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE, |
| @@ -1342,7 +1343,7 @@ static bool service_io(struct device *dev) | |||
| 1342 | if (out->type & VIRTIO_BLK_T_SCSI_CMD) { | 1343 | if (out->type & VIRTIO_BLK_T_SCSI_CMD) { |
| 1343 | fprintf(stderr, "Scsi commands unsupported\n"); | 1344 | fprintf(stderr, "Scsi commands unsupported\n"); |
| 1344 | in->status = VIRTIO_BLK_S_UNSUPP; | 1345 | in->status = VIRTIO_BLK_S_UNSUPP; |
| 1345 | wlen = sizeof(in); | 1346 | wlen = sizeof(*in); |
| 1346 | } else if (out->type & VIRTIO_BLK_T_OUT) { | 1347 | } else if (out->type & VIRTIO_BLK_T_OUT) { |
| 1347 | /* Write */ | 1348 | /* Write */ |
| 1348 | 1349 | ||
| @@ -1363,7 +1364,7 @@ static bool service_io(struct device *dev) | |||
| 1363 | /* Die, bad Guest, die. */ | 1364 | /* Die, bad Guest, die. */ |
| 1364 | errx(1, "Write past end %llu+%u", off, ret); | 1365 | errx(1, "Write past end %llu+%u", off, ret); |
| 1365 | } | 1366 | } |
| 1366 | wlen = sizeof(in); | 1367 | wlen = sizeof(*in); |
| 1367 | in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); | 1368 | in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); |
| 1368 | } else { | 1369 | } else { |
| 1369 | /* Read */ | 1370 | /* Read */ |
| @@ -1376,10 +1377,10 @@ static bool service_io(struct device *dev) | |||
| 1376 | ret = readv(vblk->fd, iov+1, in_num-1); | 1377 | ret = readv(vblk->fd, iov+1, in_num-1); |
| 1377 | verbose("READ from sector %llu: %i\n", out->sector, ret); | 1378 | verbose("READ from sector %llu: %i\n", out->sector, ret); |
| 1378 | if (ret >= 0) { | 1379 | if (ret >= 0) { |
| 1379 | wlen = sizeof(in) + ret; | 1380 | wlen = sizeof(*in) + ret; |
| 1380 | in->status = VIRTIO_BLK_S_OK; | 1381 | in->status = VIRTIO_BLK_S_OK; |
| 1381 | } else { | 1382 | } else { |
| 1382 | wlen = sizeof(in); | 1383 | wlen = sizeof(*in); |
| 1383 | in->status = VIRTIO_BLK_S_IOERR; | 1384 | in->status = VIRTIO_BLK_S_IOERR; |
| 1384 | } | 1385 | } |
| 1385 | } | 1386 | } |
diff --git a/MAINTAINERS b/MAINTAINERS index 6a9702726239..cad0882754a6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3454,15 +3454,10 @@ L: lm-sensors@lm-sensors.org | |||
| 3454 | S: Maintained | 3454 | S: Maintained |
| 3455 | 3455 | ||
| 3456 | SOFTMAC LAYER (IEEE 802.11) | 3456 | SOFTMAC LAYER (IEEE 802.11) |
| 3457 | P: Johannes Berg | ||
| 3458 | M: johannes@sipsolutions.net | ||
| 3459 | P: Joe Jezak | ||
| 3460 | M: josejx@gentoo.org | ||
| 3461 | P: Daniel Drake | 3457 | P: Daniel Drake |
| 3462 | M: dsd@gentoo.org | 3458 | M: dsd@gentoo.org |
| 3463 | W: http://softmac.sipsolutions.net/ | ||
| 3464 | L: linux-wireless@vger.kernel.org | 3459 | L: linux-wireless@vger.kernel.org |
| 3465 | S: Maintained | 3460 | S: Obsolete |
| 3466 | 3461 | ||
| 3467 | SOFTWARE RAID (Multiple Disks) SUPPORT | 3462 | SOFTWARE RAID (Multiple Disks) SUPPORT |
| 3468 | P: Ingo Molnar | 3463 | P: Ingo Molnar |
diff --git a/arch/x86/kernel/i387_64.c b/arch/x86/kernel/i387_64.c index 56c1f1147109..bfaff28fb134 100644 --- a/arch/x86/kernel/i387_64.c +++ b/arch/x86/kernel/i387_64.c | |||
| @@ -92,13 +92,14 @@ int save_i387(struct _fpstate __user *buf) | |||
| 92 | if (task_thread_info(tsk)->status & TS_USEDFPU) { | 92 | if (task_thread_info(tsk)->status & TS_USEDFPU) { |
| 93 | err = save_i387_checking((struct i387_fxsave_struct __user *)buf); | 93 | err = save_i387_checking((struct i387_fxsave_struct __user *)buf); |
| 94 | if (err) return err; | 94 | if (err) return err; |
| 95 | task_thread_info(tsk)->status &= ~TS_USEDFPU; | ||
| 95 | stts(); | 96 | stts(); |
| 96 | } else { | 97 | } else { |
| 97 | if (__copy_to_user(buf, &tsk->thread.i387.fxsave, | 98 | if (__copy_to_user(buf, &tsk->thread.i387.fxsave, |
| 98 | sizeof(struct i387_fxsave_struct))) | 99 | sizeof(struct i387_fxsave_struct))) |
| 99 | return -1; | 100 | return -1; |
| 100 | } | 101 | } |
| 101 | return 1; | 102 | return 1; |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | /* | 105 | /* |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index c2ce0ad21693..192c244f6190 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -132,7 +132,7 @@ static int acpi_battery_technology(struct acpi_battery *battery) | |||
| 132 | return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; | 132 | return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | static int acpi_battery_update(struct acpi_battery *battery); | 135 | static int acpi_battery_get_state(struct acpi_battery *battery); |
| 136 | 136 | ||
| 137 | static int acpi_battery_get_property(struct power_supply *psy, | 137 | static int acpi_battery_get_property(struct power_supply *psy, |
| 138 | enum power_supply_property psp, | 138 | enum power_supply_property psp, |
| @@ -140,10 +140,11 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
| 140 | { | 140 | { |
| 141 | struct acpi_battery *battery = to_acpi_battery(psy); | 141 | struct acpi_battery *battery = to_acpi_battery(psy); |
| 142 | 142 | ||
| 143 | if ((!acpi_battery_present(battery)) && | 143 | if (acpi_battery_present(battery)) { |
| 144 | psp != POWER_SUPPLY_PROP_PRESENT) | 144 | /* run battery update only if it is present */ |
| 145 | acpi_battery_get_state(battery); | ||
| 146 | } else if (psp != POWER_SUPPLY_PROP_PRESENT) | ||
| 145 | return -ENODEV; | 147 | return -ENODEV; |
| 146 | acpi_battery_update(battery); | ||
| 147 | switch (psp) { | 148 | switch (psp) { |
| 148 | case POWER_SUPPLY_PROP_STATUS: | 149 | case POWER_SUPPLY_PROP_STATUS: |
| 149 | if (battery->state & 0x01) | 150 | if (battery->state & 0x01) |
| @@ -457,6 +458,7 @@ static void sysfs_remove_battery(struct acpi_battery *battery) | |||
| 457 | return; | 458 | return; |
| 458 | device_remove_file(battery->bat.dev, &alarm_attr); | 459 | device_remove_file(battery->bat.dev, &alarm_attr); |
| 459 | power_supply_unregister(&battery->bat); | 460 | power_supply_unregister(&battery->bat); |
| 461 | battery->bat.dev = NULL; | ||
| 460 | } | 462 | } |
| 461 | 463 | ||
| 462 | static int acpi_battery_update(struct acpi_battery *battery) | 464 | static int acpi_battery_update(struct acpi_battery *battery) |
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 729f1cd93606..7a6eead63a6b 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
| @@ -494,6 +494,7 @@ static void init_vmcb(struct vmcb *vmcb) | |||
| 494 | */ | 494 | */ |
| 495 | /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */ | 495 | /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */ |
| 496 | (1ULL << INTERCEPT_CPUID) | | 496 | (1ULL << INTERCEPT_CPUID) | |
| 497 | (1ULL << INTERCEPT_INVD) | | ||
| 497 | (1ULL << INTERCEPT_HLT) | | 498 | (1ULL << INTERCEPT_HLT) | |
| 498 | (1ULL << INTERCEPT_INVLPGA) | | 499 | (1ULL << INTERCEPT_INVLPGA) | |
| 499 | (1ULL << INTERCEPT_IOIO_PROT) | | 500 | (1ULL << INTERCEPT_IOIO_PROT) | |
| @@ -507,6 +508,7 @@ static void init_vmcb(struct vmcb *vmcb) | |||
| 507 | (1ULL << INTERCEPT_STGI) | | 508 | (1ULL << INTERCEPT_STGI) | |
| 508 | (1ULL << INTERCEPT_CLGI) | | 509 | (1ULL << INTERCEPT_CLGI) | |
| 509 | (1ULL << INTERCEPT_SKINIT) | | 510 | (1ULL << INTERCEPT_SKINIT) | |
| 511 | (1ULL << INTERCEPT_WBINVD) | | ||
| 510 | (1ULL << INTERCEPT_MONITOR) | | 512 | (1ULL << INTERCEPT_MONITOR) | |
| 511 | (1ULL << INTERCEPT_MWAIT); | 513 | (1ULL << INTERCEPT_MWAIT); |
| 512 | 514 | ||
| @@ -561,6 +563,12 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 561 | struct vcpu_svm *svm = to_svm(vcpu); | 563 | struct vcpu_svm *svm = to_svm(vcpu); |
| 562 | 564 | ||
| 563 | init_vmcb(svm->vmcb); | 565 | init_vmcb(svm->vmcb); |
| 566 | |||
| 567 | if (vcpu->vcpu_id != 0) { | ||
| 568 | svm->vmcb->save.rip = 0; | ||
| 569 | svm->vmcb->save.cs.base = svm->vcpu.sipi_vector << 12; | ||
| 570 | svm->vmcb->save.cs.selector = svm->vcpu.sipi_vector << 8; | ||
| 571 | } | ||
| 564 | } | 572 | } |
| 565 | 573 | ||
| 566 | static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | 574 | static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) |
| @@ -1241,6 +1249,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, | |||
| 1241 | [SVM_EXIT_VINTR] = interrupt_window_interception, | 1249 | [SVM_EXIT_VINTR] = interrupt_window_interception, |
| 1242 | /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */ | 1250 | /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */ |
| 1243 | [SVM_EXIT_CPUID] = cpuid_interception, | 1251 | [SVM_EXIT_CPUID] = cpuid_interception, |
| 1252 | [SVM_EXIT_INVD] = emulate_on_interception, | ||
| 1244 | [SVM_EXIT_HLT] = halt_interception, | 1253 | [SVM_EXIT_HLT] = halt_interception, |
| 1245 | [SVM_EXIT_INVLPG] = emulate_on_interception, | 1254 | [SVM_EXIT_INVLPG] = emulate_on_interception, |
| 1246 | [SVM_EXIT_INVLPGA] = invalid_op_interception, | 1255 | [SVM_EXIT_INVLPGA] = invalid_op_interception, |
| @@ -1255,6 +1264,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, | |||
| 1255 | [SVM_EXIT_STGI] = invalid_op_interception, | 1264 | [SVM_EXIT_STGI] = invalid_op_interception, |
| 1256 | [SVM_EXIT_CLGI] = invalid_op_interception, | 1265 | [SVM_EXIT_CLGI] = invalid_op_interception, |
| 1257 | [SVM_EXIT_SKINIT] = invalid_op_interception, | 1266 | [SVM_EXIT_SKINIT] = invalid_op_interception, |
| 1267 | [SVM_EXIT_WBINVD] = emulate_on_interception, | ||
| 1258 | [SVM_EXIT_MONITOR] = invalid_op_interception, | 1268 | [SVM_EXIT_MONITOR] = invalid_op_interception, |
| 1259 | [SVM_EXIT_MWAIT] = invalid_op_interception, | 1269 | [SVM_EXIT_MWAIT] = invalid_op_interception, |
| 1260 | }; | 1270 | }; |
| @@ -1579,10 +1589,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 1579 | #endif | 1589 | #endif |
| 1580 | : "cc", "memory" ); | 1590 | : "cc", "memory" ); |
| 1581 | 1591 | ||
| 1582 | local_irq_disable(); | ||
| 1583 | |||
| 1584 | stgi(); | ||
| 1585 | |||
| 1586 | if ((svm->vmcb->save.dr7 & 0xff)) | 1592 | if ((svm->vmcb->save.dr7 & 0xff)) |
| 1587 | load_db_regs(svm->host_db_regs); | 1593 | load_db_regs(svm->host_db_regs); |
| 1588 | 1594 | ||
| @@ -1599,6 +1605,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 1599 | 1605 | ||
| 1600 | reload_tss(vcpu); | 1606 | reload_tss(vcpu); |
| 1601 | 1607 | ||
| 1608 | local_irq_disable(); | ||
| 1609 | |||
| 1610 | stgi(); | ||
| 1611 | |||
| 1602 | svm->next_rip = 0; | 1612 | svm->next_rip = 0; |
| 1603 | } | 1613 | } |
| 1604 | 1614 | ||
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index a6ace302e0cd..33b181451557 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
| @@ -167,7 +167,7 @@ static u8 opcode_table[256] = { | |||
| 167 | static u16 twobyte_table[256] = { | 167 | static u16 twobyte_table[256] = { |
| 168 | /* 0x00 - 0x0F */ | 168 | /* 0x00 - 0x0F */ |
| 169 | 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, | 169 | 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, |
| 170 | 0, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, | 170 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, |
| 171 | /* 0x10 - 0x1F */ | 171 | /* 0x10 - 0x1F */ |
| 172 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, | 172 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, |
| 173 | /* 0x20 - 0x2F */ | 173 | /* 0x20 - 0x2F */ |
| @@ -980,17 +980,6 @@ done_prefixes: | |||
| 980 | goto cannot_emulate; | 980 | goto cannot_emulate; |
| 981 | dst.val = (s32) src.val; | 981 | dst.val = (s32) src.val; |
| 982 | break; | 982 | break; |
| 983 | case 0x6a: /* push imm8 */ | ||
| 984 | src.val = 0L; | ||
| 985 | src.val = insn_fetch(s8, 1, _eip); | ||
| 986 | push: | ||
| 987 | dst.type = OP_MEM; | ||
| 988 | dst.bytes = op_bytes; | ||
| 989 | dst.val = src.val; | ||
| 990 | register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes); | ||
| 991 | dst.ptr = (void *) register_address(ctxt->ss_base, | ||
| 992 | _regs[VCPU_REGS_RSP]); | ||
| 993 | break; | ||
| 994 | case 0x80 ... 0x83: /* Grp1 */ | 983 | case 0x80 ... 0x83: /* Grp1 */ |
| 995 | switch (modrm_reg) { | 984 | switch (modrm_reg) { |
| 996 | case 0: | 985 | case 0: |
| @@ -1243,6 +1232,17 @@ special_insn: | |||
| 1243 | register_address_increment(_regs[VCPU_REGS_RSP], op_bytes); | 1232 | register_address_increment(_regs[VCPU_REGS_RSP], op_bytes); |
| 1244 | no_wb = 1; /* Disable writeback. */ | 1233 | no_wb = 1; /* Disable writeback. */ |
| 1245 | break; | 1234 | break; |
| 1235 | case 0x6a: /* push imm8 */ | ||
| 1236 | src.val = 0L; | ||
| 1237 | src.val = insn_fetch(s8, 1, _eip); | ||
| 1238 | push: | ||
| 1239 | dst.type = OP_MEM; | ||
| 1240 | dst.bytes = op_bytes; | ||
| 1241 | dst.val = src.val; | ||
| 1242 | register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes); | ||
| 1243 | dst.ptr = (void *) register_address(ctxt->ss_base, | ||
| 1244 | _regs[VCPU_REGS_RSP]); | ||
| 1245 | break; | ||
| 1246 | case 0x6c: /* insb */ | 1246 | case 0x6c: /* insb */ |
| 1247 | case 0x6d: /* insw/insd */ | 1247 | case 0x6d: /* insw/insd */ |
| 1248 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, | 1248 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, |
| @@ -1532,6 +1532,8 @@ twobyte_special_insn: | |||
| 1532 | case 0x06: | 1532 | case 0x06: |
| 1533 | emulate_clts(ctxt->vcpu); | 1533 | emulate_clts(ctxt->vcpu); |
| 1534 | break; | 1534 | break; |
| 1535 | case 0x08: /* invd */ | ||
| 1536 | break; | ||
| 1535 | case 0x09: /* wbinvd */ | 1537 | case 0x09: /* wbinvd */ |
| 1536 | break; | 1538 | break; |
| 1537 | case 0x0d: /* GrpP (prefetch) */ | 1539 | case 0x0d: /* GrpP (prefetch) */ |
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 8904f72f97c6..66f38722253a 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
| @@ -200,7 +200,8 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, | |||
| 200 | 200 | ||
| 201 | /* Figure out how many pages the ring will take, and map that memory */ | 201 | /* Figure out how many pages the ring will take, and map that memory */ |
| 202 | lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT, | 202 | lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT, |
| 203 | DIV_ROUND_UP(vring_size(lvq->config.num), | 203 | DIV_ROUND_UP(vring_size(lvq->config.num, |
| 204 | PAGE_SIZE), | ||
| 204 | PAGE_SIZE)); | 205 | PAGE_SIZE)); |
| 205 | if (!lvq->pages) { | 206 | if (!lvq->pages) { |
| 206 | err = -ENOMEM; | 207 | err = -ENOMEM; |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index e396c9d2af8d..a75be57fb209 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -146,6 +146,7 @@ static void try_fill_recv(struct virtnet_info *vi) | |||
| 146 | struct scatterlist sg[1+MAX_SKB_FRAGS]; | 146 | struct scatterlist sg[1+MAX_SKB_FRAGS]; |
| 147 | int num, err; | 147 | int num, err; |
| 148 | 148 | ||
| 149 | sg_init_table(sg, 1+MAX_SKB_FRAGS); | ||
| 149 | for (;;) { | 150 | for (;;) { |
| 150 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); | 151 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); |
| 151 | if (unlikely(!skb)) | 152 | if (unlikely(!skb)) |
| @@ -231,6 +232,8 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 231 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; | 232 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; |
| 232 | DECLARE_MAC_BUF(mac); | 233 | DECLARE_MAC_BUF(mac); |
| 233 | 234 | ||
| 235 | sg_init_table(sg, 1+MAX_SKB_FRAGS); | ||
| 236 | |||
| 234 | pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest)); | 237 | pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest)); |
| 235 | 238 | ||
| 236 | free_old_xmit_skbs(vi); | 239 | free_old_xmit_skbs(vi); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4f22a7174caf..be7c9f42a340 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
| @@ -8354,6 +8354,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 8354 | } | 8354 | } |
| 8355 | SET_IEEE80211_DEV(hw, &pdev->dev); | 8355 | SET_IEEE80211_DEV(hw, &pdev->dev); |
| 8356 | 8356 | ||
| 8357 | hw->rate_control_algorithm = "iwl-3945-rs"; | ||
| 8358 | |||
| 8357 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); | 8359 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); |
| 8358 | priv = hw->priv; | 8360 | priv = hw->priv; |
| 8359 | priv->hw = hw; | 8361 | priv->hw = hw; |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index d60adcb9bd4a..6757c6c1b25a 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
| @@ -8955,6 +8955,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 8955 | } | 8955 | } |
| 8956 | SET_IEEE80211_DEV(hw, &pdev->dev); | 8956 | SET_IEEE80211_DEV(hw, &pdev->dev); |
| 8957 | 8957 | ||
| 8958 | hw->rate_control_algorithm = "iwl-4965-rs"; | ||
| 8959 | |||
| 8958 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); | 8960 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); |
| 8959 | priv = hw->priv; | 8961 | priv = hw->priv; |
| 8960 | priv->hw = hw; | 8962 | priv->hw = hw; |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index c12a741b5574..85a20546e827 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
| @@ -440,6 +440,7 @@ static int ssb_devices_register(struct ssb_bus *bus) | |||
| 440 | break; | 440 | break; |
| 441 | case SSB_BUSTYPE_PCMCIA: | 441 | case SSB_BUSTYPE_PCMCIA: |
| 442 | #ifdef CONFIG_SSB_PCMCIAHOST | 442 | #ifdef CONFIG_SSB_PCMCIAHOST |
| 443 | sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; | ||
| 443 | dev->parent = &bus->host_pcmcia->dev; | 444 | dev->parent = &bus->host_pcmcia->dev; |
| 444 | #endif | 445 | #endif |
| 445 | break; | 446 | break; |
| @@ -1147,7 +1148,10 @@ static int __init ssb_modinit(void) | |||
| 1147 | 1148 | ||
| 1148 | return err; | 1149 | return err; |
| 1149 | } | 1150 | } |
| 1150 | subsys_initcall(ssb_modinit); | 1151 | /* ssb must be initialized after PCI but before the ssb drivers. |
| 1152 | * That means we must use some initcall between subsys_initcall | ||
| 1153 | * and device_initcall. */ | ||
| 1154 | fs_initcall(ssb_modinit); | ||
| 1151 | 1155 | ||
| 1152 | static void __exit ssb_modexit(void) | 1156 | static void __exit ssb_modexit(void) |
| 1153 | { | 1157 | { |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index b6abee846f02..bb44a76b3eb5 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
| @@ -63,17 +63,17 @@ int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus, | |||
| 63 | err = pcmcia_access_configuration_register(pdev, ®); | 63 | err = pcmcia_access_configuration_register(pdev, ®); |
| 64 | if (err != CS_SUCCESS) | 64 | if (err != CS_SUCCESS) |
| 65 | goto error; | 65 | goto error; |
| 66 | read_addr |= (reg.Value & 0xF) << 12; | 66 | read_addr |= ((u32)(reg.Value & 0x0F)) << 12; |
| 67 | reg.Offset = 0x30; | 67 | reg.Offset = 0x30; |
| 68 | err = pcmcia_access_configuration_register(pdev, ®); | 68 | err = pcmcia_access_configuration_register(pdev, ®); |
| 69 | if (err != CS_SUCCESS) | 69 | if (err != CS_SUCCESS) |
| 70 | goto error; | 70 | goto error; |
| 71 | read_addr |= reg.Value << 16; | 71 | read_addr |= ((u32)reg.Value) << 16; |
| 72 | reg.Offset = 0x32; | 72 | reg.Offset = 0x32; |
| 73 | err = pcmcia_access_configuration_register(pdev, ®); | 73 | err = pcmcia_access_configuration_register(pdev, ®); |
| 74 | if (err != CS_SUCCESS) | 74 | if (err != CS_SUCCESS) |
| 75 | goto error; | 75 | goto error; |
| 76 | read_addr |= reg.Value << 24; | 76 | read_addr |= ((u32)reg.Value) << 24; |
| 77 | 77 | ||
| 78 | cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE; | 78 | cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE; |
| 79 | if (cur_core == coreidx) | 79 | if (cur_core == coreidx) |
| @@ -152,28 +152,29 @@ error: | |||
| 152 | goto out_unlock; | 152 | goto out_unlock; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | /* These are the main device register access functions. | 155 | static int select_core_and_segment(struct ssb_device *dev, |
| 156 | * do_select_core is inline to have the likely hotpath inline. | 156 | u16 *offset) |
| 157 | * All unlikely codepaths are out-of-line. */ | ||
| 158 | static inline int do_select_core(struct ssb_bus *bus, | ||
| 159 | struct ssb_device *dev, | ||
| 160 | u16 *offset) | ||
| 161 | { | 157 | { |
| 158 | struct ssb_bus *bus = dev->bus; | ||
| 162 | int err; | 159 | int err; |
| 163 | u8 need_seg = (*offset >= 0x800) ? 1 : 0; | 160 | u8 need_segment; |
| 161 | |||
| 162 | if (*offset >= 0x800) { | ||
| 163 | *offset -= 0x800; | ||
| 164 | need_segment = 1; | ||
| 165 | } else | ||
| 166 | need_segment = 0; | ||
| 164 | 167 | ||
| 165 | if (unlikely(dev != bus->mapped_device)) { | 168 | if (unlikely(dev != bus->mapped_device)) { |
| 166 | err = ssb_pcmcia_switch_core(bus, dev); | 169 | err = ssb_pcmcia_switch_core(bus, dev); |
| 167 | if (unlikely(err)) | 170 | if (unlikely(err)) |
| 168 | return err; | 171 | return err; |
| 169 | } | 172 | } |
| 170 | if (unlikely(need_seg != bus->mapped_pcmcia_seg)) { | 173 | if (unlikely(need_segment != bus->mapped_pcmcia_seg)) { |
| 171 | err = ssb_pcmcia_switch_segment(bus, need_seg); | 174 | err = ssb_pcmcia_switch_segment(bus, need_segment); |
| 172 | if (unlikely(err)) | 175 | if (unlikely(err)) |
| 173 | return err; | 176 | return err; |
| 174 | } | 177 | } |
| 175 | if (need_seg == 1) | ||
| 176 | *offset -= 0x800; | ||
| 177 | 178 | ||
| 178 | return 0; | 179 | return 0; |
| 179 | } | 180 | } |
| @@ -181,32 +182,31 @@ static inline int do_select_core(struct ssb_bus *bus, | |||
| 181 | static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) | 182 | static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) |
| 182 | { | 183 | { |
| 183 | struct ssb_bus *bus = dev->bus; | 184 | struct ssb_bus *bus = dev->bus; |
| 184 | u16 x; | ||
| 185 | 185 | ||
| 186 | if (unlikely(do_select_core(bus, dev, &offset))) | 186 | if (unlikely(select_core_and_segment(dev, &offset))) |
| 187 | return 0xFFFF; | 187 | return 0xFFFF; |
| 188 | x = readw(bus->mmio + offset); | ||
| 189 | 188 | ||
| 190 | return x; | 189 | return readw(bus->mmio + offset); |
| 191 | } | 190 | } |
| 192 | 191 | ||
| 193 | static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset) | 192 | static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset) |
| 194 | { | 193 | { |
| 195 | struct ssb_bus *bus = dev->bus; | 194 | struct ssb_bus *bus = dev->bus; |
| 196 | u32 x; | 195 | u32 lo, hi; |
| 197 | 196 | ||
| 198 | if (unlikely(do_select_core(bus, dev, &offset))) | 197 | if (unlikely(select_core_and_segment(dev, &offset))) |
| 199 | return 0xFFFFFFFF; | 198 | return 0xFFFFFFFF; |
| 200 | x = readl(bus->mmio + offset); | 199 | lo = readw(bus->mmio + offset); |
| 200 | hi = readw(bus->mmio + offset + 2); | ||
| 201 | 201 | ||
| 202 | return x; | 202 | return (lo | (hi << 16)); |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) | 205 | static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) |
| 206 | { | 206 | { |
| 207 | struct ssb_bus *bus = dev->bus; | 207 | struct ssb_bus *bus = dev->bus; |
| 208 | 208 | ||
| 209 | if (unlikely(do_select_core(bus, dev, &offset))) | 209 | if (unlikely(select_core_and_segment(dev, &offset))) |
| 210 | return; | 210 | return; |
| 211 | writew(value, bus->mmio + offset); | 211 | writew(value, bus->mmio + offset); |
| 212 | } | 212 | } |
| @@ -215,12 +215,12 @@ static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
| 215 | { | 215 | { |
| 216 | struct ssb_bus *bus = dev->bus; | 216 | struct ssb_bus *bus = dev->bus; |
| 217 | 217 | ||
| 218 | if (unlikely(do_select_core(bus, dev, &offset))) | 218 | if (unlikely(select_core_and_segment(dev, &offset))) |
| 219 | return; | 219 | return; |
| 220 | readw(bus->mmio + offset); | 220 | writeb((value & 0xFF000000) >> 24, bus->mmio + offset + 3); |
| 221 | writew(value >> 16, bus->mmio + offset + 2); | 221 | writeb((value & 0x00FF0000) >> 16, bus->mmio + offset + 2); |
| 222 | readw(bus->mmio + offset); | 222 | writeb((value & 0x0000FF00) >> 8, bus->mmio + offset + 1); |
| 223 | writew(value, bus->mmio + offset); | 223 | writeb((value & 0x000000FF) >> 0, bus->mmio + offset + 0); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | /* Not "static", as it's used in main.c */ | 226 | /* Not "static", as it's used in main.c */ |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 0e4baca21b8f..1dc04b6684e6 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
| @@ -53,7 +53,7 @@ struct vring_virtqueue | |||
| 53 | unsigned int num_added; | 53 | unsigned int num_added; |
| 54 | 54 | ||
| 55 | /* Last used index we've seen. */ | 55 | /* Last used index we've seen. */ |
| 56 | unsigned int last_used_idx; | 56 | u16 last_used_idx; |
| 57 | 57 | ||
| 58 | /* How to notify other side. FIXME: commonalize hcalls! */ | 58 | /* How to notify other side. FIXME: commonalize hcalls! */ |
| 59 | void (*notify)(struct virtqueue *vq); | 59 | void (*notify)(struct virtqueue *vq); |
| @@ -277,11 +277,17 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
| 277 | struct vring_virtqueue *vq; | 277 | struct vring_virtqueue *vq; |
| 278 | unsigned int i; | 278 | unsigned int i; |
| 279 | 279 | ||
| 280 | /* We assume num is a power of 2. */ | ||
| 281 | if (num & (num - 1)) { | ||
| 282 | dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num); | ||
| 283 | return NULL; | ||
| 284 | } | ||
| 285 | |||
| 280 | vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL); | 286 | vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL); |
| 281 | if (!vq) | 287 | if (!vq) |
| 282 | return NULL; | 288 | return NULL; |
| 283 | 289 | ||
| 284 | vring_init(&vq->vring, num, pages); | 290 | vring_init(&vq->vring, num, pages, PAGE_SIZE); |
| 285 | vq->vq.callback = callback; | 291 | vq->vq.callback = callback; |
| 286 | vq->vq.vdev = vdev; | 292 | vq->vq.vdev = vdev; |
| 287 | vq->vq.vq_ops = &vring_vq_ops; | 293 | vq->vq.vq_ops = &vring_vq_ops; |
diff --git a/fs/Kconfig b/fs/Kconfig index c75c95406497..429a00228507 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -2007,7 +2007,7 @@ config CIFS_EXPERIMENTAL | |||
| 2007 | config CIFS_UPCALL | 2007 | config CIFS_UPCALL |
| 2008 | bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" | 2008 | bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" |
| 2009 | depends on CIFS_EXPERIMENTAL | 2009 | depends on CIFS_EXPERIMENTAL |
| 2010 | depends on CONNECTOR | 2010 | depends on KEYS |
| 2011 | help | 2011 | help |
| 2012 | Enables an upcall mechanism for CIFS which will be used to contact | 2012 | Enables an upcall mechanism for CIFS which will be used to contact |
| 2013 | userspace helper utilities to provide SPNEGO packaged Kerberos | 2013 | userspace helper utilities to provide SPNEGO packaged Kerberos |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 3d419163c3d3..64dd22239b21 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | Version 1.52 | ||
| 2 | ------------ | ||
| 3 | Fix oops on second mount to server when null auth is used. | ||
| 4 | |||
| 1 | Version 1.51 | 5 | Version 1.51 |
| 2 | ------------ | 6 | ------------ |
| 3 | Fix memory leak in statfs when mounted to very old servers (e.g. | 7 | Fix memory leak in statfs when mounted to very old servers (e.g. |
| @@ -12,7 +16,12 @@ leak that causes cifsd not to stop and rmmod to fail to cleanup | |||
| 12 | cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on | 16 | cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on |
| 13 | bigendian architectures. Fix possible memory corruption when | 17 | bigendian architectures. Fix possible memory corruption when |
| 14 | EAGAIN returned on kern_recvmsg. Return better error if server | 18 | EAGAIN returned on kern_recvmsg. Return better error if server |
| 15 | requires packet signing but client has disabled it. | 19 | requires packet signing but client has disabled it. When mounted |
| 20 | with cifsacl mount option - mode bits are approximated based | ||
| 21 | on the contents of the ACL of the file or directory. When cifs | ||
| 22 | mount helper is missing convert make sure that UNC name | ||
| 23 | has backslash (not forward slash) between ip address of server | ||
| 24 | and the share name. | ||
| 16 | 25 | ||
| 17 | Version 1.50 | 26 | Version 1.50 |
| 18 | ------------ | 27 | ------------ |
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index ff6ba8d823f0..45e42fb97c19 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
| @@ -3,4 +3,9 @@ | |||
| 3 | # | 3 | # |
| 4 | obj-$(CONFIG_CIFS) += cifs.o | 4 | obj-$(CONFIG_CIFS) += cifs.o |
| 5 | 5 | ||
| 6 | cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o | 6 | cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ |
| 7 | link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ | ||
| 8 | md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o \ | ||
| 9 | readdir.o ioctl.o sess.o export.o cifsacl.o | ||
| 10 | |||
| 11 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o | ||
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index 2a01f3ef96a0..bcda2c6b6a04 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
| @@ -77,8 +77,12 @@ | |||
| 77 | 77 | ||
| 78 | #define SPNEGO_OID_LEN 7 | 78 | #define SPNEGO_OID_LEN 7 |
| 79 | #define NTLMSSP_OID_LEN 10 | 79 | #define NTLMSSP_OID_LEN 10 |
| 80 | #define KRB5_OID_LEN 7 | ||
| 81 | #define MSKRB5_OID_LEN 7 | ||
| 80 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; | 82 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; |
| 81 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; | 83 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; |
| 84 | static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; | ||
| 85 | static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; | ||
| 82 | 86 | ||
| 83 | /* | 87 | /* |
| 84 | * ASN.1 context. | 88 | * ASN.1 context. |
| @@ -457,6 +461,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 457 | unsigned long *oid = NULL; | 461 | unsigned long *oid = NULL; |
| 458 | unsigned int cls, con, tag, oidlen, rc; | 462 | unsigned int cls, con, tag, oidlen, rc; |
| 459 | int use_ntlmssp = FALSE; | 463 | int use_ntlmssp = FALSE; |
| 464 | int use_kerberos = FALSE; | ||
| 460 | 465 | ||
| 461 | *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ | 466 | *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ |
| 462 | 467 | ||
| @@ -545,18 +550,28 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 545 | return 0; | 550 | return 0; |
| 546 | } | 551 | } |
| 547 | if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { | 552 | if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { |
| 548 | rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); | 553 | if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { |
| 549 | if (rc) { | 554 | |
| 550 | cFYI(1, | 555 | cFYI(1, |
| 551 | ("OID len = %d oid = 0x%lx 0x%lx " | 556 | ("OID len = %d oid = 0x%lx 0x%lx " |
| 552 | "0x%lx 0x%lx", | 557 | "0x%lx 0x%lx", |
| 553 | oidlen, *oid, *(oid + 1), | 558 | oidlen, *oid, *(oid + 1), |
| 554 | *(oid + 2), *(oid + 3))); | 559 | *(oid + 2), *(oid + 3))); |
| 555 | rc = compare_oid(oid, oidlen, | 560 | |
| 556 | NTLMSSP_OID, NTLMSSP_OID_LEN); | 561 | if (compare_oid(oid, oidlen, |
| 557 | kfree(oid); | 562 | MSKRB5_OID, |
| 558 | if (rc) | 563 | MSKRB5_OID_LEN)) |
| 564 | use_kerberos = TRUE; | ||
| 565 | else if (compare_oid(oid, oidlen, | ||
| 566 | KRB5_OID, | ||
| 567 | KRB5_OID_LEN)) | ||
| 568 | use_kerberos = TRUE; | ||
| 569 | else if (compare_oid(oid, oidlen, | ||
| 570 | NTLMSSP_OID, | ||
| 571 | NTLMSSP_OID_LEN)) | ||
| 559 | use_ntlmssp = TRUE; | 572 | use_ntlmssp = TRUE; |
| 573 | |||
| 574 | kfree(oid); | ||
| 560 | } | 575 | } |
| 561 | } else { | 576 | } else { |
| 562 | cFYI(1, ("Should be an oid what is going on?")); | 577 | cFYI(1, ("Should be an oid what is going on?")); |
| @@ -609,12 +624,10 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 609 | ctx.pointer)); /* is this UTF-8 or ASCII? */ | 624 | ctx.pointer)); /* is this UTF-8 or ASCII? */ |
| 610 | } | 625 | } |
| 611 | 626 | ||
| 612 | /* if (use_kerberos) | 627 | if (use_kerberos) |
| 613 | *secType = Kerberos | 628 | *secType = Kerberos; |
| 614 | else */ | 629 | else if (use_ntlmssp) |
| 615 | if (use_ntlmssp) { | ||
| 616 | *secType = NTLMSSP; | 630 | *secType = NTLMSSP; |
| 617 | } | ||
| 618 | 631 | ||
| 619 | return 1; | 632 | return 1; |
| 620 | } | 633 | } |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c new file mode 100644 index 000000000000..ad54a3a6e434 --- /dev/null +++ b/fs/cifs/cifs_spnego.c | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | /* | ||
| 2 | * fs/cifs/cifs_spnego.c -- SPNEGO upcall management for CIFS | ||
| 3 | * | ||
| 4 | * Copyright (c) 2007 Red Hat, Inc. | ||
| 5 | * Author(s): Jeff Layton (jlayton@redhat.com) | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU Lesser General Public License as published | ||
| 9 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
| 15 | * the GNU Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public License | ||
| 18 | * along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/list.h> | ||
| 23 | #include <linux/string.h> | ||
| 24 | #include <keys/user-type.h> | ||
| 25 | #include <linux/key-type.h> | ||
| 26 | #include "cifsglob.h" | ||
| 27 | #include "cifs_spnego.h" | ||
| 28 | #include "cifs_debug.h" | ||
| 29 | |||
| 30 | /* create a new cifs key */ | ||
| 31 | static int | ||
| 32 | cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) | ||
| 33 | { | ||
| 34 | char *payload; | ||
| 35 | int ret; | ||
| 36 | |||
| 37 | ret = -ENOMEM; | ||
| 38 | payload = kmalloc(datalen, GFP_KERNEL); | ||
| 39 | if (!payload) | ||
| 40 | goto error; | ||
| 41 | |||
| 42 | /* attach the data */ | ||
| 43 | memcpy(payload, data, datalen); | ||
| 44 | rcu_assign_pointer(key->payload.data, payload); | ||
| 45 | ret = 0; | ||
| 46 | |||
| 47 | error: | ||
| 48 | return ret; | ||
| 49 | } | ||
| 50 | |||
| 51 | static void | ||
| 52 | cifs_spnego_key_destroy(struct key *key) | ||
| 53 | { | ||
| 54 | kfree(key->payload.data); | ||
| 55 | } | ||
| 56 | |||
| 57 | |||
| 58 | /* | ||
| 59 | * keytype for CIFS spnego keys | ||
| 60 | */ | ||
| 61 | struct key_type cifs_spnego_key_type = { | ||
| 62 | .name = "cifs.spnego", | ||
| 63 | .instantiate = cifs_spnego_key_instantiate, | ||
| 64 | .match = user_match, | ||
| 65 | .destroy = cifs_spnego_key_destroy, | ||
| 66 | .describe = user_describe, | ||
| 67 | }; | ||
| 68 | |||
| 69 | /* get a key struct with a SPNEGO security blob, suitable for session setup */ | ||
| 70 | struct key * | ||
| 71 | cifs_get_spnego_key(struct cifsSesInfo *sesInfo, const char *hostname) | ||
| 72 | { | ||
| 73 | struct TCP_Server_Info *server = sesInfo->server; | ||
| 74 | char *description, *dp; | ||
| 75 | size_t desc_len; | ||
| 76 | struct key *spnego_key; | ||
| 77 | |||
| 78 | |||
| 79 | /* version + ;ip{4|6}= + address + ;host=hostname + | ||
| 80 | ;sec= + ;uid= + NULL */ | ||
| 81 | desc_len = 4 + 5 + 32 + 1 + 5 + strlen(hostname) + | ||
| 82 | strlen(";sec=krb5") + 7 + sizeof(uid_t)*2 + 1; | ||
| 83 | spnego_key = ERR_PTR(-ENOMEM); | ||
| 84 | description = kzalloc(desc_len, GFP_KERNEL); | ||
| 85 | if (description == NULL) | ||
| 86 | goto out; | ||
| 87 | |||
| 88 | dp = description; | ||
| 89 | /* start with version and hostname portion of UNC string */ | ||
| 90 | spnego_key = ERR_PTR(-EINVAL); | ||
| 91 | sprintf(dp, "0x%2.2x;host=%s;", CIFS_SPNEGO_UPCALL_VERSION, | ||
| 92 | hostname); | ||
| 93 | dp = description + strlen(description); | ||
| 94 | |||
| 95 | /* add the server address */ | ||
| 96 | if (server->addr.sockAddr.sin_family == AF_INET) | ||
| 97 | sprintf(dp, "ip4=" NIPQUAD_FMT, | ||
| 98 | NIPQUAD(server->addr.sockAddr.sin_addr)); | ||
| 99 | else if (server->addr.sockAddr.sin_family == AF_INET6) | ||
| 100 | sprintf(dp, "ip6=" NIP6_SEQFMT, | ||
| 101 | NIP6(server->addr.sockAddr6.sin6_addr)); | ||
| 102 | else | ||
| 103 | goto out; | ||
| 104 | |||
| 105 | dp = description + strlen(description); | ||
| 106 | |||
| 107 | /* for now, only sec=krb5 is valid */ | ||
| 108 | if (server->secType == Kerberos) | ||
| 109 | sprintf(dp, ";sec=krb5"); | ||
| 110 | else | ||
| 111 | goto out; | ||
| 112 | |||
| 113 | dp = description + strlen(description); | ||
| 114 | sprintf(dp, ";uid=0x%x", sesInfo->linux_uid); | ||
| 115 | |||
| 116 | cFYI(1, ("key description = %s", description)); | ||
| 117 | spnego_key = request_key(&cifs_spnego_key_type, description, ""); | ||
| 118 | |||
| 119 | if (cifsFYI && !IS_ERR(spnego_key)) { | ||
| 120 | struct cifs_spnego_msg *msg = spnego_key->payload.data; | ||
| 121 | cifs_dump_mem("SPNEGO reply blob:", msg->data, | ||
| 122 | msg->secblob_len + msg->sesskey_len); | ||
| 123 | } | ||
| 124 | |||
| 125 | out: | ||
| 126 | kfree(description); | ||
| 127 | return spnego_key; | ||
| 128 | } | ||
diff --git a/fs/cifs/cifs_spnego.h b/fs/cifs/cifs_spnego.h new file mode 100644 index 000000000000..f443f3b35134 --- /dev/null +++ b/fs/cifs/cifs_spnego.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* | ||
| 2 | * fs/cifs/cifs_spnego.h -- SPNEGO upcall management for CIFS | ||
| 3 | * | ||
| 4 | * Copyright (c) 2007 Red Hat, Inc. | ||
| 5 | * Author(s): Jeff Layton (jlayton@redhat.com) | ||
| 6 | * Steve French (sfrench@us.ibm.com) | ||
| 7 | * | ||
| 8 | * This library is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU Lesser General Public License as published | ||
| 10 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This library is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
| 16 | * the GNU Lesser General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU Lesser General Public License | ||
| 19 | * along with this library; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef _CIFS_SPNEGO_H | ||
| 24 | #define _CIFS_SPNEGO_H | ||
| 25 | |||
| 26 | #define CIFS_SPNEGO_UPCALL_VERSION 1 | ||
| 27 | |||
| 28 | /* | ||
| 29 | * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION. | ||
| 30 | * The flags field is for future use. The request-key callout should set | ||
| 31 | * sesskey_len and secblob_len, and then concatenate the SessKey+SecBlob | ||
| 32 | * and stuff it in the data field. | ||
| 33 | */ | ||
| 34 | struct cifs_spnego_msg { | ||
| 35 | uint32_t version; | ||
| 36 | uint32_t flags; | ||
| 37 | uint32_t sesskey_len; | ||
| 38 | uint32_t secblob_len; | ||
| 39 | uint8_t data[1]; | ||
| 40 | }; | ||
| 41 | |||
| 42 | #ifdef __KERNEL__ | ||
| 43 | extern struct key_type cifs_spnego_key_type; | ||
| 44 | #endif /* KERNEL */ | ||
| 45 | |||
| 46 | #endif /* _CIFS_SPNEGO_H */ | ||
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index e8e56353f5a1..dabbce00712b 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -38,13 +38,13 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { | |||
| 38 | {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"}, | 38 | {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"}, |
| 39 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"}, | 39 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"}, |
| 40 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"}, | 40 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"}, |
| 41 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} | 41 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} } |
| 42 | }; | 42 | ; |
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | /* security id for everyone */ | 45 | /* security id for everyone */ |
| 46 | static const struct cifs_sid sid_everyone = | 46 | static const struct cifs_sid sid_everyone = { |
| 47 | {1, 1, {0, 0, 0, 0, 0, 0}, {} }; | 47 | 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; |
| 48 | /* group users */ | 48 | /* group users */ |
| 49 | static const struct cifs_sid sid_user = | 49 | static const struct cifs_sid sid_user = |
| 50 | {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; | 50 | {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; |
| @@ -97,7 +97,7 @@ int match_sid(struct cifs_sid *ctsid) | |||
| 97 | 97 | ||
| 98 | /* if the two SIDs (roughly equivalent to a UUID for a user or group) are | 98 | /* if the two SIDs (roughly equivalent to a UUID for a user or group) are |
| 99 | the same returns 1, if they do not match returns 0 */ | 99 | the same returns 1, if they do not match returns 0 */ |
| 100 | int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid) | 100 | int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) |
| 101 | { | 101 | { |
| 102 | int i; | 102 | int i; |
| 103 | int num_subauth, num_sat, num_saw; | 103 | int num_subauth, num_sat, num_saw; |
| @@ -129,66 +129,142 @@ int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid) | |||
| 129 | return (1); /* sids compare/match */ | 129 | return (1); /* sids compare/match */ |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | /* | ||
| 133 | change posix mode to reflect permissions | ||
| 134 | pmode is the existing mode (we only want to overwrite part of this | ||
| 135 | bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007 | ||
| 136 | */ | ||
| 137 | static void access_flags_to_mode(__u32 ace_flags, int type, umode_t *pmode, | ||
| 138 | umode_t *pbits_to_set) | ||
| 139 | { | ||
| 140 | /* the order of ACEs is important. The canonical order is to begin with | ||
| 141 | DENY entries followed by ALLOW, otherwise an allow entry could be | ||
| 142 | encountered first, making the subsequent deny entry like "dead code" | ||
| 143 | which would be superflous since Windows stops when a match is made | ||
| 144 | for the operation you are trying to perform for your user */ | ||
| 145 | |||
| 146 | /* For deny ACEs we change the mask so that subsequent allow access | ||
| 147 | control entries do not turn on the bits we are denying */ | ||
| 148 | if (type == ACCESS_DENIED) { | ||
| 149 | if (ace_flags & GENERIC_ALL) { | ||
| 150 | *pbits_to_set &= ~S_IRWXUGO; | ||
| 151 | } | ||
| 152 | if ((ace_flags & GENERIC_WRITE) || | ||
| 153 | ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) | ||
| 154 | *pbits_to_set &= ~S_IWUGO; | ||
| 155 | if ((ace_flags & GENERIC_READ) || | ||
| 156 | ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) | ||
| 157 | *pbits_to_set &= ~S_IRUGO; | ||
| 158 | if ((ace_flags & GENERIC_EXECUTE) || | ||
| 159 | ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) | ||
| 160 | *pbits_to_set &= ~S_IXUGO; | ||
| 161 | return; | ||
| 162 | } else if (type != ACCESS_ALLOWED) { | ||
| 163 | cERROR(1, ("unknown access control type %d", type)); | ||
| 164 | return; | ||
| 165 | } | ||
| 166 | /* else ACCESS_ALLOWED type */ | ||
| 167 | |||
| 168 | if (ace_flags & GENERIC_ALL) { | ||
| 169 | *pmode |= (S_IRWXUGO & (*pbits_to_set)); | ||
| 170 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 171 | cFYI(1, ("all perms")); | ||
| 172 | #endif | ||
| 173 | return; | ||
| 174 | } | ||
| 175 | if ((ace_flags & GENERIC_WRITE) || | ||
| 176 | ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) | ||
| 177 | *pmode |= (S_IWUGO & (*pbits_to_set)); | ||
| 178 | if ((ace_flags & GENERIC_READ) || | ||
| 179 | ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) | ||
| 180 | *pmode |= (S_IRUGO & (*pbits_to_set)); | ||
| 181 | if ((ace_flags & GENERIC_EXECUTE) || | ||
| 182 | ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) | ||
| 183 | *pmode |= (S_IXUGO & (*pbits_to_set)); | ||
| 184 | |||
| 185 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 186 | cFYI(1, ("access flags 0x%x mode now 0x%x", ace_flags, *pmode)); | ||
| 187 | #endif | ||
| 188 | return; | ||
| 189 | } | ||
| 190 | |||
| 191 | /* | ||
| 192 | Generate access flags to reflect permissions mode is the existing mode. | ||
| 193 | This function is called for every ACE in the DACL whose SID matches | ||
| 194 | with either owner or group or everyone. | ||
| 195 | */ | ||
| 196 | |||
| 197 | static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, | ||
| 198 | __u32 *pace_flags) | ||
| 199 | { | ||
| 200 | /* reset access mask */ | ||
| 201 | *pace_flags = 0x0; | ||
| 202 | |||
| 203 | /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */ | ||
| 204 | mode &= bits_to_use; | ||
| 205 | |||
| 206 | /* check for R/W/X UGO since we do not know whose flags | ||
| 207 | is this but we have cleared all the bits sans RWX for | ||
| 208 | either user or group or other as per bits_to_use */ | ||
| 209 | if (mode & S_IRUGO) | ||
| 210 | *pace_flags |= SET_FILE_READ_RIGHTS; | ||
| 211 | if (mode & S_IWUGO) | ||
| 212 | *pace_flags |= SET_FILE_WRITE_RIGHTS; | ||
| 213 | if (mode & S_IXUGO) | ||
| 214 | *pace_flags |= SET_FILE_EXEC_RIGHTS; | ||
| 215 | |||
| 216 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 217 | cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags)); | ||
| 218 | #endif | ||
| 219 | return; | ||
| 220 | } | ||
| 221 | |||
| 132 | 222 | ||
| 133 | static void parse_ace(struct cifs_ace *pace, char *end_of_acl) | 223 | #ifdef CONFIG_CIFS_DEBUG2 |
| 224 | static void dump_ace(struct cifs_ace *pace, char *end_of_acl) | ||
| 134 | { | 225 | { |
| 135 | int num_subauth; | 226 | int num_subauth; |
| 136 | 227 | ||
| 137 | /* validate that we do not go past end of acl */ | 228 | /* validate that we do not go past end of acl */ |
| 138 | 229 | ||
| 139 | /* XXX this if statement can be removed | 230 | if (le16_to_cpu(pace->size) < 16) { |
| 140 | if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) { | 231 | cERROR(1, ("ACE too small, %d", le16_to_cpu(pace->size))); |
| 232 | return; | ||
| 233 | } | ||
| 234 | |||
| 235 | if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) { | ||
| 141 | cERROR(1, ("ACL too small to parse ACE")); | 236 | cERROR(1, ("ACL too small to parse ACE")); |
| 142 | return; | 237 | return; |
| 143 | } */ | 238 | } |
| 144 | 239 | ||
| 145 | num_subauth = pace->num_subauth; | 240 | num_subauth = pace->sid.num_subauth; |
| 146 | if (num_subauth) { | 241 | if (num_subauth) { |
| 147 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 148 | int i; | 242 | int i; |
| 149 | cFYI(1, ("ACE revision %d num_subauth %d", | 243 | cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d", |
| 150 | pace->revision, pace->num_subauth)); | 244 | pace->sid.revision, pace->sid.num_subauth, pace->type, |
| 245 | pace->flags, pace->size)); | ||
| 151 | for (i = 0; i < num_subauth; ++i) { | 246 | for (i = 0; i < num_subauth; ++i) { |
| 152 | cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, | 247 | cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, |
| 153 | le32_to_cpu(pace->sub_auth[i]))); | 248 | le32_to_cpu(pace->sid.sub_auth[i]))); |
| 154 | } | 249 | } |
| 155 | 250 | ||
| 156 | /* BB add length check to make sure that we do not have huge | 251 | /* BB add length check to make sure that we do not have huge |
| 157 | num auths and therefore go off the end */ | 252 | num auths and therefore go off the end */ |
| 158 | |||
| 159 | cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1]))); | ||
| 160 | #endif | ||
| 161 | } | 253 | } |
| 162 | 254 | ||
| 163 | return; | 255 | return; |
| 164 | } | 256 | } |
| 165 | |||
| 166 | static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl) | ||
| 167 | { | ||
| 168 | /* validate that we do not go past end of acl */ | ||
| 169 | if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) { | ||
| 170 | cERROR(1, ("ACL too small to parse NT ACE")); | ||
| 171 | return; | ||
| 172 | } | ||
| 173 | |||
| 174 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 175 | cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x", | ||
| 176 | pntace->type, pntace->flags, pntace->size, | ||
| 177 | pntace->access_req)); | ||
| 178 | #endif | 257 | #endif |
| 179 | return; | ||
| 180 | } | ||
| 181 | |||
| 182 | 258 | ||
| 183 | 259 | ||
| 184 | static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | 260 | static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, |
| 185 | struct cifs_sid *pownersid, struct cifs_sid *pgrpsid) | 261 | struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, |
| 262 | struct inode *inode) | ||
| 186 | { | 263 | { |
| 187 | int i; | 264 | int i; |
| 188 | int num_aces = 0; | 265 | int num_aces = 0; |
| 189 | int acl_size; | 266 | int acl_size; |
| 190 | char *acl_base; | 267 | char *acl_base; |
| 191 | struct cifs_ntace **ppntace; | ||
| 192 | struct cifs_ace **ppace; | 268 | struct cifs_ace **ppace; |
| 193 | 269 | ||
| 194 | /* BB need to add parm so we can store the SID BB */ | 270 | /* BB need to add parm so we can store the SID BB */ |
| @@ -205,50 +281,63 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
| 205 | le32_to_cpu(pdacl->num_aces))); | 281 | le32_to_cpu(pdacl->num_aces))); |
| 206 | #endif | 282 | #endif |
| 207 | 283 | ||
| 284 | /* reset rwx permissions for user/group/other. | ||
| 285 | Also, if num_aces is 0 i.e. DACL has no ACEs, | ||
| 286 | user/group/other have no permissions */ | ||
| 287 | inode->i_mode &= ~(S_IRWXUGO); | ||
| 288 | |||
| 289 | if (!pdacl) { | ||
| 290 | /* no DACL in the security descriptor, set | ||
| 291 | all the permissions for user/group/other */ | ||
| 292 | inode->i_mode |= S_IRWXUGO; | ||
| 293 | return; | ||
| 294 | } | ||
| 208 | acl_base = (char *)pdacl; | 295 | acl_base = (char *)pdacl; |
| 209 | acl_size = sizeof(struct cifs_acl); | 296 | acl_size = sizeof(struct cifs_acl); |
| 210 | 297 | ||
| 211 | num_aces = le32_to_cpu(pdacl->num_aces); | 298 | num_aces = le32_to_cpu(pdacl->num_aces); |
| 212 | if (num_aces > 0) { | 299 | if (num_aces > 0) { |
| 213 | ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *), | 300 | umode_t user_mask = S_IRWXU; |
| 214 | GFP_KERNEL); | 301 | umode_t group_mask = S_IRWXG; |
| 302 | umode_t other_mask = S_IRWXO; | ||
| 303 | |||
| 215 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), | 304 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), |
| 216 | GFP_KERNEL); | 305 | GFP_KERNEL); |
| 217 | 306 | ||
| 218 | /* cifscred->cecount = pdacl->num_aces; | 307 | /* cifscred->cecount = pdacl->num_aces; |
| 219 | cifscred->ntaces = kmalloc(num_aces * | ||
| 220 | sizeof(struct cifs_ntace *), GFP_KERNEL); | ||
| 221 | cifscred->aces = kmalloc(num_aces * | 308 | cifscred->aces = kmalloc(num_aces * |
| 222 | sizeof(struct cifs_ace *), GFP_KERNEL);*/ | 309 | sizeof(struct cifs_ace *), GFP_KERNEL);*/ |
| 223 | 310 | ||
| 224 | for (i = 0; i < num_aces; ++i) { | 311 | for (i = 0; i < num_aces; ++i) { |
| 225 | ppntace[i] = (struct cifs_ntace *) | 312 | ppace[i] = (struct cifs_ace *) (acl_base + acl_size); |
| 226 | (acl_base + acl_size); | 313 | #ifdef CONFIG_CIFS_DEBUG2 |
| 227 | ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] + | 314 | dump_ace(ppace[i], end_of_acl); |
| 228 | sizeof(struct cifs_ntace)); | 315 | #endif |
| 229 | 316 | if (compare_sids(&(ppace[i]->sid), pownersid)) | |
| 230 | parse_ntace(ppntace[i], end_of_acl); | 317 | access_flags_to_mode(ppace[i]->access_req, |
| 231 | if (end_of_acl < ((char *)ppace[i] + | 318 | ppace[i]->type, |
| 232 | (le16_to_cpu(ppntace[i]->size) - | 319 | &(inode->i_mode), |
| 233 | sizeof(struct cifs_ntace)))) { | 320 | &user_mask); |
| 234 | cERROR(1, ("ACL too small to parse ACE")); | 321 | if (compare_sids(&(ppace[i]->sid), pgrpsid)) |
| 235 | break; | 322 | access_flags_to_mode(ppace[i]->access_req, |
| 236 | } else | 323 | ppace[i]->type, |
| 237 | parse_ace(ppace[i], end_of_acl); | 324 | &(inode->i_mode), |
| 238 | 325 | &group_mask); | |
| 239 | /* memcpy((void *)(&(cifscred->ntaces[i])), | 326 | if (compare_sids(&(ppace[i]->sid), &sid_everyone)) |
| 240 | (void *)ppntace[i], | 327 | access_flags_to_mode(ppace[i]->access_req, |
| 241 | sizeof(struct cifs_ntace)); | 328 | ppace[i]->type, |
| 242 | memcpy((void *)(&(cifscred->aces[i])), | 329 | &(inode->i_mode), |
| 330 | &other_mask); | ||
| 331 | |||
| 332 | /* memcpy((void *)(&(cifscred->aces[i])), | ||
| 243 | (void *)ppace[i], | 333 | (void *)ppace[i], |
| 244 | sizeof(struct cifs_ace)); */ | 334 | sizeof(struct cifs_ace)); */ |
| 245 | 335 | ||
| 246 | acl_base = (char *)ppntace[i]; | 336 | acl_base = (char *)ppace[i]; |
| 247 | acl_size = le16_to_cpu(ppntace[i]->size); | 337 | acl_size = le16_to_cpu(ppace[i]->size); |
| 248 | } | 338 | } |
| 249 | 339 | ||
| 250 | kfree(ppace); | 340 | kfree(ppace); |
| 251 | kfree(ppntace); | ||
| 252 | } | 341 | } |
| 253 | 342 | ||
| 254 | return; | 343 | return; |
| @@ -257,20 +346,20 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
| 257 | 346 | ||
| 258 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | 347 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) |
| 259 | { | 348 | { |
| 260 | |||
| 261 | /* BB need to add parm so we can store the SID BB */ | 349 | /* BB need to add parm so we can store the SID BB */ |
| 262 | 350 | ||
| 263 | /* validate that we do not go past end of acl */ | 351 | /* validate that we do not go past end of ACL - sid must be at least 8 |
| 264 | if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { | 352 | bytes long (assuming no sub-auths - e.g. the null SID */ |
| 265 | cERROR(1, ("ACL too small to parse SID")); | 353 | if (end_of_acl < (char *)psid + 8) { |
| 354 | cERROR(1, ("ACL too small to parse SID %p", psid)); | ||
| 266 | return -EINVAL; | 355 | return -EINVAL; |
| 267 | } | 356 | } |
| 268 | 357 | ||
| 269 | if (psid->num_subauth) { | 358 | if (psid->num_subauth) { |
| 270 | #ifdef CONFIG_CIFS_DEBUG2 | 359 | #ifdef CONFIG_CIFS_DEBUG2 |
| 271 | int i; | 360 | int i; |
| 272 | cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x", | 361 | cFYI(1, ("SID revision %d num_auth %d", |
| 273 | psid->revision, psid->num_subauth, psid->sub_auth[0])); | 362 | psid->revision, psid->num_subauth)); |
| 274 | 363 | ||
| 275 | for (i = 0; i < psid->num_subauth; i++) { | 364 | for (i = 0; i < psid->num_subauth; i++) { |
| 276 | cFYI(1, ("SID sub_auth[%d]: 0x%x ", i, | 365 | cFYI(1, ("SID sub_auth[%d]: 0x%x ", i, |
| @@ -289,27 +378,32 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | |||
| 289 | 378 | ||
| 290 | 379 | ||
| 291 | /* Convert CIFS ACL to POSIX form */ | 380 | /* Convert CIFS ACL to POSIX form */ |
| 292 | int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) | 381 | static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, |
| 382 | struct inode *inode) | ||
| 293 | { | 383 | { |
| 294 | int rc; | 384 | int rc; |
| 295 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | 385 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
| 296 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ | 386 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ |
| 297 | char *end_of_acl = ((char *)pntsd) + acl_len; | 387 | char *end_of_acl = ((char *)pntsd) + acl_len; |
| 388 | __u32 dacloffset; | ||
| 389 | |||
| 390 | if ((inode == NULL) || (pntsd == NULL)) | ||
| 391 | return -EIO; | ||
| 298 | 392 | ||
| 299 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | 393 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
| 300 | le32_to_cpu(pntsd->osidoffset)); | 394 | le32_to_cpu(pntsd->osidoffset)); |
| 301 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | 395 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
| 302 | le32_to_cpu(pntsd->gsidoffset)); | 396 | le32_to_cpu(pntsd->gsidoffset)); |
| 303 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + | 397 | dacloffset = le32_to_cpu(pntsd->dacloffset); |
| 304 | le32_to_cpu(pntsd->dacloffset)); | 398 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); |
| 305 | #ifdef CONFIG_CIFS_DEBUG2 | 399 | #ifdef CONFIG_CIFS_DEBUG2 |
| 306 | cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " | 400 | cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " |
| 307 | "sacloffset 0x%x dacloffset 0x%x", | 401 | "sacloffset 0x%x dacloffset 0x%x", |
| 308 | pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), | 402 | pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), |
| 309 | le32_to_cpu(pntsd->gsidoffset), | 403 | le32_to_cpu(pntsd->gsidoffset), |
| 310 | le32_to_cpu(pntsd->sacloffset), | 404 | le32_to_cpu(pntsd->sacloffset), dacloffset)); |
| 311 | le32_to_cpu(pntsd->dacloffset))); | ||
| 312 | #endif | 405 | #endif |
| 406 | /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ | ||
| 313 | rc = parse_sid(owner_sid_ptr, end_of_acl); | 407 | rc = parse_sid(owner_sid_ptr, end_of_acl); |
| 314 | if (rc) | 408 | if (rc) |
| 315 | return rc; | 409 | return rc; |
| @@ -318,16 +412,120 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) | |||
| 318 | if (rc) | 412 | if (rc) |
| 319 | return rc; | 413 | return rc; |
| 320 | 414 | ||
| 321 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr); | 415 | if (dacloffset) |
| 416 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, | ||
| 417 | group_sid_ptr, inode); | ||
| 418 | else | ||
| 419 | cFYI(1, ("no ACL")); /* BB grant all or default perms? */ | ||
| 322 | 420 | ||
| 323 | /* cifscred->uid = owner_sid_ptr->rid; | 421 | /* cifscred->uid = owner_sid_ptr->rid; |
| 324 | cifscred->gid = group_sid_ptr->rid; | 422 | cifscred->gid = group_sid_ptr->rid; |
| 325 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, | 423 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, |
| 326 | sizeof (struct cifs_sid)); | 424 | sizeof(struct cifs_sid)); |
| 327 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | 425 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, |
| 328 | sizeof (struct cifs_sid)); */ | 426 | sizeof(struct cifs_sid)); */ |
| 329 | 427 | ||
| 330 | 428 | ||
| 331 | return (0); | 429 | return (0); |
| 332 | } | 430 | } |
| 431 | |||
| 432 | |||
| 433 | /* Retrieve an ACL from the server */ | ||
| 434 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | ||
| 435 | const char *path) | ||
| 436 | { | ||
| 437 | struct cifsFileInfo *open_file; | ||
| 438 | int unlock_file = FALSE; | ||
| 439 | int xid; | ||
| 440 | int rc = -EIO; | ||
| 441 | __u16 fid; | ||
| 442 | struct super_block *sb; | ||
| 443 | struct cifs_sb_info *cifs_sb; | ||
| 444 | struct cifs_ntsd *pntsd = NULL; | ||
| 445 | |||
| 446 | cFYI(1, ("get mode from ACL for %s", path)); | ||
| 447 | |||
| 448 | if (inode == NULL) | ||
| 449 | return NULL; | ||
| 450 | |||
| 451 | xid = GetXid(); | ||
| 452 | open_file = find_readable_file(CIFS_I(inode)); | ||
| 453 | sb = inode->i_sb; | ||
| 454 | if (sb == NULL) { | ||
| 455 | FreeXid(xid); | ||
| 456 | return NULL; | ||
| 457 | } | ||
| 458 | cifs_sb = CIFS_SB(sb); | ||
| 459 | |||
| 460 | if (open_file) { | ||
| 461 | unlock_file = TRUE; | ||
| 462 | fid = open_file->netfid; | ||
| 463 | } else { | ||
| 464 | int oplock = FALSE; | ||
| 465 | /* open file */ | ||
| 466 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
| 467 | READ_CONTROL, 0, &fid, &oplock, NULL, | ||
| 468 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
| 469 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 470 | if (rc != 0) { | ||
| 471 | cERROR(1, ("Unable to open file to get ACL")); | ||
| 472 | FreeXid(xid); | ||
| 473 | return NULL; | ||
| 474 | } | ||
| 475 | } | ||
| 476 | |||
| 477 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | ||
| 478 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); | ||
| 479 | if (unlock_file == TRUE) | ||
| 480 | atomic_dec(&open_file->wrtPending); | ||
| 481 | else | ||
| 482 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
| 483 | |||
| 484 | FreeXid(xid); | ||
| 485 | return pntsd; | ||
| 486 | } | ||
| 487 | |||
| 488 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | ||
| 489 | void acl_to_uid_mode(struct inode *inode, const char *path) | ||
| 490 | { | ||
| 491 | struct cifs_ntsd *pntsd = NULL; | ||
| 492 | u32 acllen = 0; | ||
| 493 | int rc = 0; | ||
| 494 | |||
| 495 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 496 | cFYI(1, ("converting ACL to mode for %s", path)); | ||
| 497 | #endif | ||
| 498 | pntsd = get_cifs_acl(&acllen, inode, path); | ||
| 499 | |||
| 500 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | ||
| 501 | if (pntsd) | ||
| 502 | rc = parse_sec_desc(pntsd, acllen, inode); | ||
| 503 | if (rc) | ||
| 504 | cFYI(1, ("parse sec desc failed rc = %d", rc)); | ||
| 505 | |||
| 506 | kfree(pntsd); | ||
| 507 | return; | ||
| 508 | } | ||
| 509 | |||
| 510 | /* Convert mode bits to an ACL so we can update the ACL on the server */ | ||
| 511 | int mode_to_acl(struct inode *inode, const char *path) | ||
| 512 | { | ||
| 513 | int rc = 0; | ||
| 514 | __u32 acllen = 0; | ||
| 515 | struct cifs_ntsd *pntsd = NULL; | ||
| 516 | |||
| 517 | cFYI(1, ("set ACL from mode for %s", path)); | ||
| 518 | |||
| 519 | /* Get the security descriptor */ | ||
| 520 | pntsd = get_cifs_acl(&acllen, inode, path); | ||
| 521 | |||
| 522 | /* Add/Modify the three ACEs for owner, group, everyone | ||
| 523 | while retaining the other ACEs */ | ||
| 524 | |||
| 525 | /* Set the security descriptor */ | ||
| 526 | |||
| 527 | |||
| 528 | kfree(pntsd); | ||
| 529 | return rc; | ||
| 530 | } | ||
| 333 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 531 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index 420f87813647..93a7c3462ea2 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h | |||
| @@ -35,6 +35,9 @@ | |||
| 35 | #define UBITSHIFT 6 | 35 | #define UBITSHIFT 6 |
| 36 | #define GBITSHIFT 3 | 36 | #define GBITSHIFT 3 |
| 37 | 37 | ||
| 38 | #define ACCESS_ALLOWED 0 | ||
| 39 | #define ACCESS_DENIED 1 | ||
| 40 | |||
| 38 | struct cifs_ntsd { | 41 | struct cifs_ntsd { |
| 39 | __le16 revision; /* revision level */ | 42 | __le16 revision; /* revision level */ |
| 40 | __le16 type; | 43 | __le16 type; |
| @@ -48,7 +51,7 @@ struct cifs_sid { | |||
| 48 | __u8 revision; /* revision level */ | 51 | __u8 revision; /* revision level */ |
| 49 | __u8 num_subauth; | 52 | __u8 num_subauth; |
| 50 | __u8 authority[6]; | 53 | __u8 authority[6]; |
| 51 | __le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */ | 54 | __le32 sub_auth[5]; /* sub_auth[num_subauth] */ |
| 52 | } __attribute__((packed)); | 55 | } __attribute__((packed)); |
| 53 | 56 | ||
| 54 | struct cifs_acl { | 57 | struct cifs_acl { |
| @@ -57,18 +60,12 @@ struct cifs_acl { | |||
| 57 | __le32 num_aces; | 60 | __le32 num_aces; |
| 58 | } __attribute__((packed)); | 61 | } __attribute__((packed)); |
| 59 | 62 | ||
| 60 | struct cifs_ntace { /* first part of ACE which contains perms */ | 63 | struct cifs_ace { |
| 61 | __u8 type; | 64 | __u8 type; |
| 62 | __u8 flags; | 65 | __u8 flags; |
| 63 | __le16 size; | 66 | __le16 size; |
| 64 | __le32 access_req; | 67 | __le32 access_req; |
| 65 | } __attribute__((packed)); | 68 | struct cifs_sid sid; /* ie UUID of user or group who gets these perms */ |
| 66 | |||
| 67 | struct cifs_ace { /* last part of ACE which includes user info */ | ||
| 68 | __u8 revision; /* revision level */ | ||
| 69 | __u8 num_subauth; | ||
| 70 | __u8 authority[6]; | ||
| 71 | __le32 sub_auth[5]; | ||
| 72 | } __attribute__((packed)); | 69 | } __attribute__((packed)); |
| 73 | 70 | ||
| 74 | struct cifs_wksid { | 71 | struct cifs_wksid { |
| @@ -79,7 +76,7 @@ struct cifs_wksid { | |||
| 79 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 76 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
| 80 | 77 | ||
| 81 | extern int match_sid(struct cifs_sid *); | 78 | extern int match_sid(struct cifs_sid *); |
| 82 | extern int compare_sids(struct cifs_sid *, struct cifs_sid *); | 79 | extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); |
| 83 | 80 | ||
| 84 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 81 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
| 85 | 82 | ||
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 632070b4275d..4ff8939c6cc7 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
| @@ -99,15 +99,16 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, | |||
| 99 | MD5Init(&context); | 99 | MD5Init(&context); |
| 100 | MD5Update(&context, (char *)&key->data, key->len); | 100 | MD5Update(&context, (char *)&key->data, key->len); |
| 101 | for (i = 0; i < n_vec; i++) { | 101 | for (i = 0; i < n_vec; i++) { |
| 102 | if (iov[i].iov_len == 0) | ||
| 103 | continue; | ||
| 102 | if (iov[i].iov_base == NULL) { | 104 | if (iov[i].iov_base == NULL) { |
| 103 | cERROR(1, ("null iovec entry")); | 105 | cERROR(1, ("null iovec entry")); |
| 104 | return -EIO; | 106 | return -EIO; |
| 105 | } else if (iov[i].iov_len == 0) | 107 | } |
| 106 | break; /* bail out if we are sent nothing to sign */ | ||
| 107 | /* The first entry includes a length field (which does not get | 108 | /* The first entry includes a length field (which does not get |
| 108 | signed that occupies the first 4 bytes before the header */ | 109 | signed that occupies the first 4 bytes before the header */ |
| 109 | if (i == 0) { | 110 | if (i == 0) { |
| 110 | if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */ | 111 | if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ |
| 111 | break; /* nothing to sign or corrupt header */ | 112 | break; /* nothing to sign or corrupt header */ |
| 112 | MD5Update(&context, iov[0].iov_base+4, | 113 | MD5Update(&context, iov[0].iov_base+4, |
| 113 | iov[0].iov_len-4); | 114 | iov[0].iov_len-4); |
| @@ -122,7 +123,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, | |||
| 122 | 123 | ||
| 123 | 124 | ||
| 124 | int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, | 125 | int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, |
| 125 | __u32 * pexpected_response_sequence_number) | 126 | __u32 *pexpected_response_sequence_number) |
| 126 | { | 127 | { |
| 127 | int rc = 0; | 128 | int rc = 0; |
| 128 | char smb_signature[20]; | 129 | char smb_signature[20]; |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index a6fbea57c4b1..416dc9fe8961 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -43,6 +43,8 @@ | |||
| 43 | #include "cifs_debug.h" | 43 | #include "cifs_debug.h" |
| 44 | #include "cifs_fs_sb.h" | 44 | #include "cifs_fs_sb.h" |
| 45 | #include <linux/mm.h> | 45 | #include <linux/mm.h> |
| 46 | #include <linux/key-type.h> | ||
| 47 | #include "cifs_spnego.h" | ||
| 46 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ | 48 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ |
| 47 | 49 | ||
| 48 | #ifdef CONFIG_CIFS_QUOTA | 50 | #ifdef CONFIG_CIFS_QUOTA |
| @@ -1005,12 +1007,16 @@ init_cifs(void) | |||
| 1005 | rc = register_filesystem(&cifs_fs_type); | 1007 | rc = register_filesystem(&cifs_fs_type); |
| 1006 | if (rc) | 1008 | if (rc) |
| 1007 | goto out_destroy_request_bufs; | 1009 | goto out_destroy_request_bufs; |
| 1008 | 1010 | #ifdef CONFIG_CIFS_UPCALL | |
| 1011 | rc = register_key_type(&cifs_spnego_key_type); | ||
| 1012 | if (rc) | ||
| 1013 | goto out_unregister_filesystem; | ||
| 1014 | #endif | ||
| 1009 | oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); | 1015 | oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); |
| 1010 | if (IS_ERR(oplockThread)) { | 1016 | if (IS_ERR(oplockThread)) { |
| 1011 | rc = PTR_ERR(oplockThread); | 1017 | rc = PTR_ERR(oplockThread); |
| 1012 | cERROR(1, ("error %d create oplock thread", rc)); | 1018 | cERROR(1, ("error %d create oplock thread", rc)); |
| 1013 | goto out_unregister_filesystem; | 1019 | goto out_unregister_key_type; |
| 1014 | } | 1020 | } |
| 1015 | 1021 | ||
| 1016 | dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); | 1022 | dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); |
| @@ -1024,7 +1030,11 @@ init_cifs(void) | |||
| 1024 | 1030 | ||
| 1025 | out_stop_oplock_thread: | 1031 | out_stop_oplock_thread: |
| 1026 | kthread_stop(oplockThread); | 1032 | kthread_stop(oplockThread); |
| 1033 | out_unregister_key_type: | ||
| 1034 | #ifdef CONFIG_CIFS_UPCALL | ||
| 1035 | unregister_key_type(&cifs_spnego_key_type); | ||
| 1027 | out_unregister_filesystem: | 1036 | out_unregister_filesystem: |
| 1037 | #endif | ||
| 1028 | unregister_filesystem(&cifs_fs_type); | 1038 | unregister_filesystem(&cifs_fs_type); |
| 1029 | out_destroy_request_bufs: | 1039 | out_destroy_request_bufs: |
| 1030 | cifs_destroy_request_bufs(); | 1040 | cifs_destroy_request_bufs(); |
| @@ -1046,6 +1056,9 @@ exit_cifs(void) | |||
| 1046 | #ifdef CONFIG_PROC_FS | 1056 | #ifdef CONFIG_PROC_FS |
| 1047 | cifs_proc_clean(); | 1057 | cifs_proc_clean(); |
| 1048 | #endif | 1058 | #endif |
| 1059 | #ifdef CONFIG_CIFS_UPCALL | ||
| 1060 | unregister_key_type(&cifs_spnego_key_type); | ||
| 1061 | #endif | ||
| 1049 | unregister_filesystem(&cifs_fs_type); | 1062 | unregister_filesystem(&cifs_fs_type); |
| 1050 | cifs_destroy_inodecache(); | 1063 | cifs_destroy_inodecache(); |
| 1051 | cifs_destroy_mids(); | 1064 | cifs_destroy_mids(); |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 5574ba3ab1f9..2a21dc66f0de 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -106,5 +106,5 @@ extern int cifs_ioctl(struct inode *inode, struct file *filep, | |||
| 106 | extern const struct export_operations cifs_export_ops; | 106 | extern const struct export_operations cifs_export_ops; |
| 107 | #endif /* EXPERIMENTAL */ | 107 | #endif /* EXPERIMENTAL */ |
| 108 | 108 | ||
| 109 | #define CIFS_VERSION "1.51" | 109 | #define CIFS_VERSION "1.52" |
| 110 | #endif /* _CIFSFS_H */ | 110 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index c41ff74e9128..dbe6b846f37f 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
| @@ -220,6 +220,23 @@ | |||
| 220 | | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) | 220 | | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) |
| 221 | #define FILE_EXEC_RIGHTS (FILE_EXECUTE) | 221 | #define FILE_EXEC_RIGHTS (FILE_EXECUTE) |
| 222 | 222 | ||
| 223 | #define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \ | ||
| 224 | | FILE_READ_ATTRIBUTES \ | ||
| 225 | | FILE_WRITE_ATTRIBUTES \ | ||
| 226 | | DELETE | READ_CONTROL | WRITE_DAC \ | ||
| 227 | | WRITE_OWNER | SYNCHRONIZE) | ||
| 228 | #define SET_FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \ | ||
| 229 | | FILE_READ_EA | FILE_WRITE_EA \ | ||
| 230 | | FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES \ | ||
| 231 | | FILE_WRITE_ATTRIBUTES \ | ||
| 232 | | DELETE | READ_CONTROL | WRITE_DAC \ | ||
| 233 | | WRITE_OWNER | SYNCHRONIZE) | ||
| 234 | #define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \ | ||
| 235 | | FILE_READ_ATTRIBUTES \ | ||
| 236 | | FILE_WRITE_ATTRIBUTES \ | ||
| 237 | | DELETE | READ_CONTROL | WRITE_DAC \ | ||
| 238 | | WRITE_OWNER | SYNCHRONIZE) | ||
| 239 | |||
| 223 | 240 | ||
| 224 | /* | 241 | /* |
| 225 | * Invalid readdir handle | 242 | * Invalid readdir handle |
| @@ -1211,6 +1228,29 @@ typedef struct smb_com_transaction_qsec_req { | |||
| 1211 | __le32 AclFlags; | 1228 | __le32 AclFlags; |
| 1212 | } __attribute__((packed)) QUERY_SEC_DESC_REQ; | 1229 | } __attribute__((packed)) QUERY_SEC_DESC_REQ; |
| 1213 | 1230 | ||
| 1231 | |||
| 1232 | typedef struct smb_com_transaction_ssec_req { | ||
| 1233 | struct smb_hdr hdr; /* wct = 19 */ | ||
| 1234 | __u8 MaxSetupCount; | ||
| 1235 | __u16 Reserved; | ||
| 1236 | __le32 TotalParameterCount; | ||
| 1237 | __le32 TotalDataCount; | ||
| 1238 | __le32 MaxParameterCount; | ||
| 1239 | __le32 MaxDataCount; | ||
| 1240 | __le32 ParameterCount; | ||
| 1241 | __le32 ParameterOffset; | ||
| 1242 | __le32 DataCount; | ||
| 1243 | __le32 DataOffset; | ||
| 1244 | __u8 SetupCount; /* no setup words follow subcommand */ | ||
| 1245 | /* SNIA spec incorrectly included spurious pad here */ | ||
| 1246 | __le16 SubCommand; /* 3 = SET_SECURITY_DESC */ | ||
| 1247 | __le16 ByteCount; /* bcc = 3 + 8 */ | ||
| 1248 | __u8 Pad[3]; | ||
| 1249 | __u16 Fid; | ||
| 1250 | __u16 Reserved2; | ||
| 1251 | __le32 AclFlags; | ||
| 1252 | } __attribute__((packed)) SET_SEC_DESC_REQ; | ||
| 1253 | |||
| 1214 | typedef struct smb_com_transaction_change_notify_req { | 1254 | typedef struct smb_com_transaction_change_notify_req { |
| 1215 | struct smb_hdr hdr; /* wct = 23 */ | 1255 | struct smb_hdr hdr; /* wct = 23 */ |
| 1216 | __u8 MaxSetupCount; | 1256 | __u8 MaxSetupCount; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1a883663b22d..dd1d7c200ee6 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -61,6 +61,9 @@ extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); | |||
| 61 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); | 61 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); |
| 62 | extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); | 62 | extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); |
| 63 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); | 63 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); |
| 64 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 65 | extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *); | ||
| 66 | #endif | ||
| 64 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); | 67 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); |
| 65 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | 68 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); |
| 66 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 69 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
| @@ -73,6 +76,8 @@ extern void header_assemble(struct smb_hdr *, char /* command */ , | |||
| 73 | extern int small_smb_init_no_tc(const int smb_cmd, const int wct, | 76 | extern int small_smb_init_no_tc(const int smb_cmd, const int wct, |
| 74 | struct cifsSesInfo *ses, | 77 | struct cifsSesInfo *ses, |
| 75 | void **request_buf); | 78 | void **request_buf); |
| 79 | extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo, | ||
| 80 | const char *hostname); | ||
| 76 | extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, | 81 | extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, |
| 77 | const int stage, | 82 | const int stage, |
| 78 | const struct nls_table *nls_cp); | 83 | const struct nls_table *nls_cp); |
| @@ -92,6 +97,8 @@ extern int cifs_get_inode_info(struct inode **pinode, | |||
| 92 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 97 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
| 93 | const unsigned char *search_path, | 98 | const unsigned char *search_path, |
| 94 | struct super_block *sb, int xid); | 99 | struct super_block *sb, int xid); |
| 100 | extern void acl_to_uid_mode(struct inode *inode, const char *search_path); | ||
| 101 | extern int mode_to_acl(struct inode *inode, const char *path); | ||
| 95 | 102 | ||
| 96 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 103 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
| 97 | const char *); | 104 | const char *); |
| @@ -311,7 +318,6 @@ extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, | |||
| 311 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 318 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
| 312 | extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); | 319 | extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); |
| 313 | #endif /* CIFS_WEAK_PW_HASH */ | 320 | #endif /* CIFS_WEAK_PW_HASH */ |
| 314 | extern int parse_sec_desc(struct cifs_ntsd *, int); | ||
| 315 | extern int CIFSSMBCopy(int xid, | 321 | extern int CIFSSMBCopy(int xid, |
| 316 | struct cifsTconInfo *source_tcon, | 322 | struct cifsTconInfo *source_tcon, |
| 317 | const char *fromName, | 323 | const char *fromName, |
| @@ -336,8 +342,7 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, | |||
| 336 | const void *ea_value, const __u16 ea_value_len, | 342 | const void *ea_value, const __u16 ea_value_len, |
| 337 | const struct nls_table *nls_codepage, int remap_special_chars); | 343 | const struct nls_table *nls_codepage, int remap_special_chars); |
| 338 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, | 344 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, |
| 339 | __u16 fid, char *acl_inf, const int buflen, | 345 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); |
| 340 | const int acl_type /* ACCESS vs. DEFAULT */); | ||
| 341 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, | 346 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, |
| 342 | const unsigned char *searchName, | 347 | const unsigned char *searchName, |
| 343 | char *acl_inf, const int buflen, const int acl_type, | 348 | char *acl_inf, const int buflen, const int acl_type, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f0d9a485d095..59d7b7c037ad 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -647,8 +647,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 647 | count - 16, | 647 | count - 16, |
| 648 | &server->secType); | 648 | &server->secType); |
| 649 | if (rc == 1) { | 649 | if (rc == 1) { |
| 650 | /* BB Need to fill struct for sessetup here */ | 650 | rc = 0; |
| 651 | rc = -EOPNOTSUPP; | ||
| 652 | } else { | 651 | } else { |
| 653 | rc = -EINVAL; | 652 | rc = -EINVAL; |
| 654 | } | 653 | } |
| @@ -2486,6 +2485,7 @@ querySymLinkRetry: | |||
| 2486 | return rc; | 2485 | return rc; |
| 2487 | } | 2486 | } |
| 2488 | 2487 | ||
| 2488 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 2489 | /* Initialize NT TRANSACT SMB into small smb request buffer. | 2489 | /* Initialize NT TRANSACT SMB into small smb request buffer. |
| 2490 | This assumes that all NT TRANSACTS that we init here have | 2490 | This assumes that all NT TRANSACTS that we init here have |
| 2491 | total parm and data under about 400 bytes (to fit in small cifs | 2491 | total parm and data under about 400 bytes (to fit in small cifs |
| @@ -2494,7 +2494,7 @@ querySymLinkRetry: | |||
| 2494 | MaxSetupCount (size of returned setup area) and | 2494 | MaxSetupCount (size of returned setup area) and |
| 2495 | MaxParameterCount (returned parms size) must be set by caller */ | 2495 | MaxParameterCount (returned parms size) must be set by caller */ |
| 2496 | static int | 2496 | static int |
| 2497 | smb_init_ntransact(const __u16 sub_command, const int setup_count, | 2497 | smb_init_nttransact(const __u16 sub_command, const int setup_count, |
| 2498 | const int parm_len, struct cifsTconInfo *tcon, | 2498 | const int parm_len, struct cifsTconInfo *tcon, |
| 2499 | void **ret_buf) | 2499 | void **ret_buf) |
| 2500 | { | 2500 | { |
| @@ -2525,12 +2525,15 @@ smb_init_ntransact(const __u16 sub_command, const int setup_count, | |||
| 2525 | 2525 | ||
| 2526 | static int | 2526 | static int |
| 2527 | validate_ntransact(char *buf, char **ppparm, char **ppdata, | 2527 | validate_ntransact(char *buf, char **ppparm, char **ppdata, |
| 2528 | int *pdatalen, int *pparmlen) | 2528 | __u32 *pparmlen, __u32 *pdatalen) |
| 2529 | { | 2529 | { |
| 2530 | char *end_of_smb; | 2530 | char *end_of_smb; |
| 2531 | __u32 data_count, data_offset, parm_count, parm_offset; | 2531 | __u32 data_count, data_offset, parm_count, parm_offset; |
| 2532 | struct smb_com_ntransact_rsp *pSMBr; | 2532 | struct smb_com_ntransact_rsp *pSMBr; |
| 2533 | 2533 | ||
| 2534 | *pdatalen = 0; | ||
| 2535 | *pparmlen = 0; | ||
| 2536 | |||
| 2534 | if (buf == NULL) | 2537 | if (buf == NULL) |
| 2535 | return -EINVAL; | 2538 | return -EINVAL; |
| 2536 | 2539 | ||
| @@ -2567,8 +2570,11 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, | |||
| 2567 | cFYI(1, ("parm count and data count larger than SMB")); | 2570 | cFYI(1, ("parm count and data count larger than SMB")); |
| 2568 | return -EINVAL; | 2571 | return -EINVAL; |
| 2569 | } | 2572 | } |
| 2573 | *pdatalen = data_count; | ||
| 2574 | *pparmlen = parm_count; | ||
| 2570 | return 0; | 2575 | return 0; |
| 2571 | } | 2576 | } |
| 2577 | #endif /* CIFS_EXPERIMENTAL */ | ||
| 2572 | 2578 | ||
| 2573 | int | 2579 | int |
| 2574 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | 2580 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, |
| @@ -3067,8 +3073,7 @@ GetExtAttrOut: | |||
| 3067 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | 3073 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ |
| 3068 | int | 3074 | int |
| 3069 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | 3075 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, |
| 3070 | /* BB fix up return info */ char *acl_inf, const int buflen, | 3076 | struct cifs_ntsd **acl_inf, __u32 *pbuflen) |
| 3071 | const int acl_type) | ||
| 3072 | { | 3077 | { |
| 3073 | int rc = 0; | 3078 | int rc = 0; |
| 3074 | int buf_type = 0; | 3079 | int buf_type = 0; |
| @@ -3077,7 +3082,10 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
| 3077 | 3082 | ||
| 3078 | cFYI(1, ("GetCifsACL")); | 3083 | cFYI(1, ("GetCifsACL")); |
| 3079 | 3084 | ||
| 3080 | rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, | 3085 | *pbuflen = 0; |
| 3086 | *acl_inf = NULL; | ||
| 3087 | |||
| 3088 | rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, | ||
| 3081 | 8 /* parm len */, tcon, (void **) &pSMB); | 3089 | 8 /* parm len */, tcon, (void **) &pSMB); |
| 3082 | if (rc) | 3090 | if (rc) |
| 3083 | return rc; | 3091 | return rc; |
| @@ -3099,34 +3107,52 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
| 3099 | if (rc) { | 3107 | if (rc) { |
| 3100 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | 3108 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); |
| 3101 | } else { /* decode response */ | 3109 | } else { /* decode response */ |
| 3102 | struct cifs_ntsd *psec_desc; | ||
| 3103 | __le32 * parm; | 3110 | __le32 * parm; |
| 3104 | int parm_len; | 3111 | __u32 parm_len; |
| 3105 | int data_len; | 3112 | __u32 acl_len; |
| 3106 | int acl_len; | ||
| 3107 | struct smb_com_ntransact_rsp *pSMBr; | 3113 | struct smb_com_ntransact_rsp *pSMBr; |
| 3114 | char *pdata; | ||
| 3108 | 3115 | ||
| 3109 | /* validate_nttransact */ | 3116 | /* validate_nttransact */ |
| 3110 | rc = validate_ntransact(iov[0].iov_base, (char **)&parm, | 3117 | rc = validate_ntransact(iov[0].iov_base, (char **)&parm, |
| 3111 | (char **)&psec_desc, | 3118 | &pdata, &parm_len, pbuflen); |
| 3112 | &parm_len, &data_len); | ||
| 3113 | if (rc) | 3119 | if (rc) |
| 3114 | goto qsec_out; | 3120 | goto qsec_out; |
| 3115 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; | 3121 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; |
| 3116 | 3122 | ||
| 3117 | cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc)); | 3123 | cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, *acl_inf)); |
| 3118 | 3124 | ||
| 3119 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { | 3125 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { |
| 3120 | rc = -EIO; /* bad smb */ | 3126 | rc = -EIO; /* bad smb */ |
| 3127 | *pbuflen = 0; | ||
| 3121 | goto qsec_out; | 3128 | goto qsec_out; |
| 3122 | } | 3129 | } |
| 3123 | 3130 | ||
| 3124 | /* BB check that data area is minimum length and as big as acl_len */ | 3131 | /* BB check that data area is minimum length and as big as acl_len */ |
| 3125 | 3132 | ||
| 3126 | acl_len = le32_to_cpu(*parm); | 3133 | acl_len = le32_to_cpu(*parm); |
| 3127 | /* BB check if (acl_len > bufsize) */ | 3134 | if (acl_len != *pbuflen) { |
| 3135 | cERROR(1, ("acl length %d does not match %d", | ||
| 3136 | acl_len, *pbuflen)); | ||
| 3137 | if (*pbuflen > acl_len) | ||
| 3138 | *pbuflen = acl_len; | ||
| 3139 | } | ||
| 3128 | 3140 | ||
| 3129 | parse_sec_desc(psec_desc, acl_len); | 3141 | /* check if buffer is big enough for the acl |
| 3142 | header followed by the smallest SID */ | ||
| 3143 | if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) || | ||
| 3144 | (*pbuflen >= 64 * 1024)) { | ||
| 3145 | cERROR(1, ("bad acl length %d", *pbuflen)); | ||
| 3146 | rc = -EINVAL; | ||
| 3147 | *pbuflen = 0; | ||
| 3148 | } else { | ||
| 3149 | *acl_inf = kmalloc(*pbuflen, GFP_KERNEL); | ||
| 3150 | if (*acl_inf == NULL) { | ||
| 3151 | *pbuflen = 0; | ||
| 3152 | rc = -ENOMEM; | ||
| 3153 | } | ||
| 3154 | memcpy(*acl_inf, pdata, *pbuflen); | ||
| 3155 | } | ||
| 3130 | } | 3156 | } |
| 3131 | qsec_out: | 3157 | qsec_out: |
| 3132 | if (buf_type == CIFS_SMALL_BUFFER) | 3158 | if (buf_type == CIFS_SMALL_BUFFER) |
| @@ -3381,7 +3407,7 @@ UnixQPathInfoRetry: | |||
| 3381 | memcpy((char *) pFindData, | 3407 | memcpy((char *) pFindData, |
| 3382 | (char *) &pSMBr->hdr.Protocol + | 3408 | (char *) &pSMBr->hdr.Protocol + |
| 3383 | data_offset, | 3409 | data_offset, |
| 3384 | sizeof (FILE_UNIX_BASIC_INFO)); | 3410 | sizeof(FILE_UNIX_BASIC_INFO)); |
| 3385 | } | 3411 | } |
| 3386 | } | 3412 | } |
| 3387 | cifs_buf_release(pSMB); | 3413 | cifs_buf_release(pSMB); |
| @@ -3649,7 +3675,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, | |||
| 3649 | pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); | 3675 | pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); |
| 3650 | pSMB->SearchHandle = searchHandle; /* always kept as le */ | 3676 | pSMB->SearchHandle = searchHandle; /* always kept as le */ |
| 3651 | pSMB->SearchCount = | 3677 | pSMB->SearchCount = |
| 3652 | cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO)); | 3678 | cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); |
| 3653 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); | 3679 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); |
| 3654 | pSMB->ResumeKey = psrch_inf->resume_key; | 3680 | pSMB->ResumeKey = psrch_inf->resume_key; |
| 3655 | pSMB->SearchFlags = | 3681 | pSMB->SearchFlags = |
| @@ -4331,7 +4357,7 @@ QFSDeviceRetry: | |||
| 4331 | } else { /* decode response */ | 4357 | } else { /* decode response */ |
| 4332 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | 4358 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); |
| 4333 | 4359 | ||
| 4334 | if (rc || (pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))) | 4360 | if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO))) |
| 4335 | rc = -EIO; /* bad smb */ | 4361 | rc = -EIO; /* bad smb */ |
| 4336 | else { | 4362 | else { |
| 4337 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 4363 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 19ee11f7f35a..1102160f6661 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -793,7 +793,7 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 793 | vol->linux_gid = current->gid; | 793 | vol->linux_gid = current->gid; |
| 794 | vol->dir_mode = S_IRWXUGO; | 794 | vol->dir_mode = S_IRWXUGO; |
| 795 | /* 2767 perms indicate mandatory locking support */ | 795 | /* 2767 perms indicate mandatory locking support */ |
| 796 | vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP); | 796 | vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP); |
| 797 | 797 | ||
| 798 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ | 798 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ |
| 799 | vol->rw = TRUE; | 799 | vol->rw = TRUE; |
| @@ -1790,7 +1790,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1790 | 1790 | ||
| 1791 | if (volume_info.nullauth) { | 1791 | if (volume_info.nullauth) { |
| 1792 | cFYI(1, ("null user")); | 1792 | cFYI(1, ("null user")); |
| 1793 | volume_info.username = NULL; | 1793 | volume_info.username = ""; |
| 1794 | } else if (volume_info.username) { | 1794 | } else if (volume_info.username) { |
| 1795 | /* BB fixme parse for domain name here */ | 1795 | /* BB fixme parse for domain name here */ |
| 1796 | cFYI(1, ("Username: %s", volume_info.username)); | 1796 | cFYI(1, ("Username: %s", volume_info.username)); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 793404b10925..37dc97af1487 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -593,7 +593,7 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a, | |||
| 593 | * case take precedence. If a is not a negative dentry, this | 593 | * case take precedence. If a is not a negative dentry, this |
| 594 | * should have no side effects | 594 | * should have no side effects |
| 595 | */ | 595 | */ |
| 596 | memcpy((unsigned char *)a->name, b->name, a->len); | 596 | memcpy(a->name, b->name, a->len); |
| 597 | return 0; | 597 | return 0; |
| 598 | } | 598 | } |
| 599 | return 1; | 599 | return 1; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1e7e4c06d9e3..68ad4ca0cfa3 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -1026,6 +1026,37 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
| 1026 | return total_written; | 1026 | return total_written; |
| 1027 | } | 1027 | } |
| 1028 | 1028 | ||
| 1029 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 1030 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode) | ||
| 1031 | { | ||
| 1032 | struct cifsFileInfo *open_file = NULL; | ||
| 1033 | |||
| 1034 | read_lock(&GlobalSMBSeslock); | ||
| 1035 | /* we could simply get the first_list_entry since write-only entries | ||
| 1036 | are always at the end of the list but since the first entry might | ||
| 1037 | have a close pending, we go through the whole list */ | ||
| 1038 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | ||
| 1039 | if (open_file->closePend) | ||
| 1040 | continue; | ||
| 1041 | if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) || | ||
| 1042 | (open_file->pfile->f_flags & O_RDONLY))) { | ||
| 1043 | if (!open_file->invalidHandle) { | ||
| 1044 | /* found a good file */ | ||
| 1045 | /* lock it so it will not be closed on us */ | ||
| 1046 | atomic_inc(&open_file->wrtPending); | ||
| 1047 | read_unlock(&GlobalSMBSeslock); | ||
| 1048 | return open_file; | ||
| 1049 | } /* else might as well continue, and look for | ||
| 1050 | another, or simply have the caller reopen it | ||
| 1051 | again rather than trying to fix this handle */ | ||
| 1052 | } else /* write only file */ | ||
| 1053 | break; /* write only files are last so must be done */ | ||
| 1054 | } | ||
| 1055 | read_unlock(&GlobalSMBSeslock); | ||
| 1056 | return NULL; | ||
| 1057 | } | ||
| 1058 | #endif | ||
| 1059 | |||
| 1029 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | 1060 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) |
| 1030 | { | 1061 | { |
| 1031 | struct cifsFileInfo *open_file; | 1062 | struct cifsFileInfo *open_file; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 5e8b388be3b6..7d907e84e032 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -289,7 +289,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size, | |||
| 289 | 289 | ||
| 290 | #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ | 290 | #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ |
| 291 | 291 | ||
| 292 | static int get_sfu_uid_mode(struct inode *inode, | 292 | static int get_sfu_mode(struct inode *inode, |
| 293 | const unsigned char *path, | 293 | const unsigned char *path, |
| 294 | struct cifs_sb_info *cifs_sb, int xid) | 294 | struct cifs_sb_info *cifs_sb, int xid) |
| 295 | { | 295 | { |
| @@ -527,11 +527,16 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 527 | 527 | ||
| 528 | /* BB fill in uid and gid here? with help from winbind? | 528 | /* BB fill in uid and gid here? with help from winbind? |
| 529 | or retrieve from NTFS stream extended attribute */ | 529 | or retrieve from NTFS stream extended attribute */ |
| 530 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 531 | /* fill in 0777 bits from ACL */ | ||
| 532 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
| 533 | cFYI(1, ("Getting mode bits from ACL")); | ||
| 534 | acl_to_uid_mode(inode, search_path); | ||
| 535 | } | ||
| 536 | #endif | ||
| 530 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 537 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
| 531 | /* fill in uid, gid, mode from server ACL */ | 538 | /* fill in remaining high mode bits e.g. SUID, VTX */ |
| 532 | /* BB FIXME this should also take into account the | 539 | get_sfu_mode(inode, search_path, cifs_sb, xid); |
| 533 | * default uid specified on mount if present */ | ||
| 534 | get_sfu_uid_mode(inode, search_path, cifs_sb, xid); | ||
| 535 | } else if (atomic_read(&cifsInfo->inUse) == 0) { | 540 | } else if (atomic_read(&cifsInfo->inUse) == 0) { |
| 536 | inode->i_uid = cifs_sb->mnt_uid; | 541 | inode->i_uid = cifs_sb->mnt_uid; |
| 537 | inode->i_gid = cifs_sb->mnt_gid; | 542 | inode->i_gid = cifs_sb->mnt_gid; |
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c index e5c3e1212697..f13f96d42fcf 100644 --- a/fs/cifs/md5.c +++ b/fs/cifs/md5.c | |||
| @@ -276,8 +276,8 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len, | |||
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | /* start out by storing key in pads */ | 278 | /* start out by storing key in pads */ |
| 279 | memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad)); | 279 | memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); |
| 280 | memset(ctx->k_opad, 0, sizeof (ctx->k_opad)); | 280 | memset(ctx->k_opad, 0, sizeof(ctx->k_opad)); |
| 281 | memcpy(ctx->k_ipad, key, key_len); | 281 | memcpy(ctx->k_ipad, key, key_len); |
| 282 | memcpy(ctx->k_opad, key, key_len); | 282 | memcpy(ctx->k_opad, key, key_len); |
| 283 | 283 | ||
| @@ -307,8 +307,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, | |||
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | /* start out by storing key in pads */ | 309 | /* start out by storing key in pads */ |
| 310 | memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad)); | 310 | memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); |
| 311 | memset(ctx->k_opad, 0, sizeof (ctx->k_opad)); | 311 | memset(ctx->k_opad, 0, sizeof(ctx->k_opad)); |
| 312 | memcpy(ctx->k_ipad, key, key_len); | 312 | memcpy(ctx->k_ipad, key, key_len); |
| 313 | memcpy(ctx->k_opad, key, key_len); | 313 | memcpy(ctx->k_opad, key, key_len); |
| 314 | 314 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 51ec681fe74a..15546c2354c5 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
| @@ -73,7 +73,7 @@ sesInfoAlloc(void) | |||
| 73 | { | 73 | { |
| 74 | struct cifsSesInfo *ret_buf; | 74 | struct cifsSesInfo *ret_buf; |
| 75 | 75 | ||
| 76 | ret_buf = kzalloc(sizeof (struct cifsSesInfo), GFP_KERNEL); | 76 | ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL); |
| 77 | if (ret_buf) { | 77 | if (ret_buf) { |
| 78 | write_lock(&GlobalSMBSeslock); | 78 | write_lock(&GlobalSMBSeslock); |
| 79 | atomic_inc(&sesInfoAllocCount); | 79 | atomic_inc(&sesInfoAllocCount); |
| @@ -109,7 +109,7 @@ struct cifsTconInfo * | |||
| 109 | tconInfoAlloc(void) | 109 | tconInfoAlloc(void) |
| 110 | { | 110 | { |
| 111 | struct cifsTconInfo *ret_buf; | 111 | struct cifsTconInfo *ret_buf; |
| 112 | ret_buf = kzalloc(sizeof (struct cifsTconInfo), GFP_KERNEL); | 112 | ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL); |
| 113 | if (ret_buf) { | 113 | if (ret_buf) { |
| 114 | write_lock(&GlobalSMBSeslock); | 114 | write_lock(&GlobalSMBSeslock); |
| 115 | atomic_inc(&tconInfoAllocCount); | 115 | atomic_inc(&tconInfoAllocCount); |
| @@ -298,7 +298,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
| 298 | memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ | 298 | memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ |
| 299 | 299 | ||
| 300 | buffer->smb_buf_length = | 300 | buffer->smb_buf_length = |
| 301 | (2 * word_count) + sizeof (struct smb_hdr) - | 301 | (2 * word_count) + sizeof(struct smb_hdr) - |
| 302 | 4 /* RFC 1001 length field does not count */ + | 302 | 4 /* RFC 1001 length field does not count */ + |
| 303 | 2 /* for bcc field itself */ ; | 303 | 2 /* for bcc field itself */ ; |
| 304 | /* Note that this is the only network field that has to be converted | 304 | /* Note that this is the only network field that has to be converted |
| @@ -422,8 +422,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) | |||
| 422 | __u32 clc_len; /* calculated length */ | 422 | __u32 clc_len; /* calculated length */ |
| 423 | cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); | 423 | cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); |
| 424 | 424 | ||
| 425 | if (length < 2 + sizeof (struct smb_hdr)) { | 425 | if (length < 2 + sizeof(struct smb_hdr)) { |
| 426 | if ((length >= sizeof (struct smb_hdr) - 1) | 426 | if ((length >= sizeof(struct smb_hdr) - 1) |
| 427 | && (smb->Status.CifsError != 0)) { | 427 | && (smb->Status.CifsError != 0)) { |
| 428 | smb->WordCount = 0; | 428 | smb->WordCount = 0; |
| 429 | /* some error cases do not return wct and bcc */ | 429 | /* some error cases do not return wct and bcc */ |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index f06359cb22ee..646e1f06941b 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
| @@ -132,6 +132,34 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { | |||
| 132 | {0, 0} | 132 | {0, 0} |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | |||
| 136 | /* if the mount helper is missing we need to reverse the 1st slash | ||
| 137 | from '/' to backslash in order to format the UNC properly for | ||
| 138 | ip address parsing and for tree connect (unless the user | ||
| 139 | remembered to put the UNC name in properly). Fortunately we do | ||
| 140 | not have to call this twice (we check for IPv4 addresses | ||
| 141 | first, so it is already converted by the time we | ||
| 142 | try IPv6 addresses */ | ||
| 143 | static int canonicalize_unc(char *cp) | ||
| 144 | { | ||
| 145 | int i; | ||
| 146 | |||
| 147 | for (i = 0; i <= 46 /* INET6_ADDRSTRLEN */ ; i++) { | ||
| 148 | if (cp[i] == 0) | ||
| 149 | break; | ||
| 150 | if (cp[i] == '\\') | ||
| 151 | break; | ||
| 152 | if (cp[i] == '/') { | ||
| 153 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 154 | cFYI(1, ("change slash to backslash in malformed UNC")); | ||
| 155 | #endif | ||
| 156 | cp[i] = '\\'; | ||
| 157 | return 1; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 135 | /* Convert string containing dotted ip address to binary form */ | 163 | /* Convert string containing dotted ip address to binary form */ |
| 136 | /* returns 0 if invalid address */ | 164 | /* returns 0 if invalid address */ |
| 137 | 165 | ||
| @@ -141,11 +169,13 @@ cifs_inet_pton(int address_family, char *cp, void *dst) | |||
| 141 | int ret = 0; | 169 | int ret = 0; |
| 142 | 170 | ||
| 143 | /* calculate length by finding first slash or NULL */ | 171 | /* calculate length by finding first slash or NULL */ |
| 144 | /* BB Should we convert '/' slash to '\' here since it seems already | 172 | if (address_family == AF_INET) { |
| 145 | * done before this */ | 173 | ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL); |
| 146 | if ( address_family == AF_INET ) { | 174 | if (ret == 0) { |
| 147 | ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL); | 175 | if (canonicalize_unc(cp)) |
| 148 | } else if ( address_family == AF_INET6 ) { | 176 | ret = in4_pton(cp, -1, dst, '\\', NULL); |
| 177 | } | ||
| 178 | } else if (address_family == AF_INET6) { | ||
| 149 | ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); | 179 | ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); |
| 150 | } | 180 | } |
| 151 | #ifdef CONFIG_CIFS_DEBUG2 | 181 | #ifdef CONFIG_CIFS_DEBUG2 |
| @@ -740,7 +770,7 @@ cifs_print_status(__u32 status_code) | |||
| 740 | 770 | ||
| 741 | 771 | ||
| 742 | static void | 772 | static void |
| 743 | ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode) | 773 | ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode) |
| 744 | { | 774 | { |
| 745 | int i; | 775 | int i; |
| 746 | if (ntstatus == 0) { | 776 | if (ntstatus == 0) { |
| @@ -793,8 +823,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
| 793 | if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */ | 823 | if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */ |
| 794 | for (i = 0; | 824 | for (i = 0; |
| 795 | i < | 825 | i < |
| 796 | sizeof (mapping_table_ERRDOS) / | 826 | sizeof(mapping_table_ERRDOS) / |
| 797 | sizeof (struct smb_to_posix_error); i++) { | 827 | sizeof(struct smb_to_posix_error); i++) { |
| 798 | if (mapping_table_ERRDOS[i].smb_err == 0) | 828 | if (mapping_table_ERRDOS[i].smb_err == 0) |
| 799 | break; | 829 | break; |
| 800 | else if (mapping_table_ERRDOS[i].smb_err == | 830 | else if (mapping_table_ERRDOS[i].smb_err == |
| @@ -807,8 +837,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
| 807 | } else if (smberrclass == ERRSRV) { /* server class of error codes */ | 837 | } else if (smberrclass == ERRSRV) { /* server class of error codes */ |
| 808 | for (i = 0; | 838 | for (i = 0; |
| 809 | i < | 839 | i < |
| 810 | sizeof (mapping_table_ERRSRV) / | 840 | sizeof(mapping_table_ERRSRV) / |
| 811 | sizeof (struct smb_to_posix_error); i++) { | 841 | sizeof(struct smb_to_posix_error); i++) { |
| 812 | if (mapping_table_ERRSRV[i].smb_err == 0) | 842 | if (mapping_table_ERRSRV[i].smb_err == 0) |
| 813 | break; | 843 | break; |
| 814 | else if (mapping_table_ERRSRV[i].smb_err == | 844 | else if (mapping_table_ERRSRV[i].smb_err == |
| @@ -837,14 +867,14 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
| 837 | unsigned int | 867 | unsigned int |
| 838 | smbCalcSize(struct smb_hdr *ptr) | 868 | smbCalcSize(struct smb_hdr *ptr) |
| 839 | { | 869 | { |
| 840 | return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + | 870 | return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + |
| 841 | 2 /* size of the bcc field */ + BCC(ptr)); | 871 | 2 /* size of the bcc field */ + BCC(ptr)); |
| 842 | } | 872 | } |
| 843 | 873 | ||
| 844 | unsigned int | 874 | unsigned int |
| 845 | smbCalcSize_LE(struct smb_hdr *ptr) | 875 | smbCalcSize_LE(struct smb_hdr *ptr) |
| 846 | { | 876 | { |
| 847 | return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + | 877 | return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + |
| 848 | 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr))); | 878 | 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr))); |
| 849 | } | 879 | } |
| 850 | 880 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 3746580e9701..0f22def4bdff 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -171,7 +171,13 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
| 171 | /* Linux can not store file creation time unfortunately so ignore it */ | 171 | /* Linux can not store file creation time unfortunately so ignore it */ |
| 172 | 172 | ||
| 173 | cifsInfo->cifsAttrs = attr; | 173 | cifsInfo->cifsAttrs = attr; |
| 174 | cifsInfo->time = jiffies; | 174 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
| 175 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
| 176 | /* get more accurate mode via ACL - so force inode refresh */ | ||
| 177 | cifsInfo->time = 0; | ||
| 178 | } else | ||
| 179 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
| 180 | cifsInfo->time = jiffies; | ||
| 175 | 181 | ||
| 176 | /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ | 182 | /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ |
| 177 | /* 2767 perms - indicate mandatory locking */ | 183 | /* 2767 perms - indicate mandatory locking */ |
| @@ -495,7 +501,7 @@ ffirst_retry: | |||
| 495 | static int cifs_unicode_bytelen(char *str) | 501 | static int cifs_unicode_bytelen(char *str) |
| 496 | { | 502 | { |
| 497 | int len; | 503 | int len; |
| 498 | __le16 * ustr = (__le16 *)str; | 504 | __le16 *ustr = (__le16 *)str; |
| 499 | 505 | ||
| 500 | for (len = 0; len <= PATH_MAX; len++) { | 506 | for (len = 0; len <= PATH_MAX; len++) { |
| 501 | if (ustr[len] == 0) | 507 | if (ustr[len] == 0) |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 90542a39be17..58bbfd992cc0 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
| @@ -80,7 +80,7 @@ SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) | |||
| 80 | 80 | ||
| 81 | /* Routines for Windows NT MD4 Hash functions. */ | 81 | /* Routines for Windows NT MD4 Hash functions. */ |
| 82 | static int | 82 | static int |
| 83 | _my_wcslen(__u16 * str) | 83 | _my_wcslen(__u16 *str) |
| 84 | { | 84 | { |
| 85 | int len = 0; | 85 | int len = 0; |
| 86 | while (*str++ != 0) | 86 | while (*str++ != 0) |
| @@ -96,7 +96,7 @@ _my_wcslen(__u16 * str) | |||
| 96 | */ | 96 | */ |
| 97 | 97 | ||
| 98 | static int | 98 | static int |
| 99 | _my_mbstowcs(__u16 * dst, const unsigned char *src, int len) | 99 | _my_mbstowcs(__u16 *dst, const unsigned char *src, int len) |
| 100 | { /* BB not a very good conversion routine - change/fix */ | 100 | { /* BB not a very good conversion routine - change/fix */ |
| 101 | int i; | 101 | int i; |
| 102 | __u16 val; | 102 | __u16 val; |
| @@ -125,9 +125,9 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) | |||
| 125 | /* Password cannot be longer than 128 characters */ | 125 | /* Password cannot be longer than 128 characters */ |
| 126 | if (passwd) { | 126 | if (passwd) { |
| 127 | len = strlen((char *) passwd); | 127 | len = strlen((char *) passwd); |
| 128 | if (len > 128) { | 128 | if (len > 128) |
| 129 | len = 128; | 129 | len = 128; |
| 130 | } | 130 | |
| 131 | /* Password must be converted to NT unicode */ | 131 | /* Password must be converted to NT unicode */ |
| 132 | _my_mbstowcs(wpwd, passwd, len); | 132 | _my_mbstowcs(wpwd, passwd, len); |
| 133 | } else | 133 | } else |
| @@ -135,7 +135,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) | |||
| 135 | 135 | ||
| 136 | wpwd[len] = 0; /* Ensure string is null terminated */ | 136 | wpwd[len] = 0; /* Ensure string is null terminated */ |
| 137 | /* Calculate length in bytes */ | 137 | /* Calculate length in bytes */ |
| 138 | len = _my_wcslen(wpwd) * sizeof (__u16); | 138 | len = _my_wcslen(wpwd) * sizeof(__u16); |
| 139 | 139 | ||
| 140 | mdfour(p16, (unsigned char *) wpwd, len); | 140 | mdfour(p16, (unsigned char *) wpwd, len); |
| 141 | memset(wpwd, 0, 129 * 2); | 141 | memset(wpwd, 0, 129 * 2); |
| @@ -167,7 +167,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) | |||
| 167 | E_P16((unsigned char *) passwd, (unsigned char *) p16); | 167 | E_P16((unsigned char *) passwd, (unsigned char *) p16); |
| 168 | 168 | ||
| 169 | /* clear out local copy of user's password (just being paranoid). */ | 169 | /* clear out local copy of user's password (just being paranoid). */ |
| 170 | memset(passwd, '\0', sizeof (passwd)); | 170 | memset(passwd, '\0', sizeof(passwd)); |
| 171 | } | 171 | } |
| 172 | #endif | 172 | #endif |
| 173 | 173 | ||
| @@ -189,8 +189,10 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n, | |||
| 189 | return; | 189 | return; |
| 190 | dom_u = user_u + 1024; | 190 | dom_u = user_u + 1024; |
| 191 | 191 | ||
| 192 | /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); | 192 | /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, |
| 193 | push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */ | 193 | STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); |
| 194 | push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, | ||
| 195 | STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */ | ||
| 194 | 196 | ||
| 195 | /* BB user and domain may need to be uppercased */ | 197 | /* BB user and domain may need to be uppercased */ |
| 196 | user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage); | 198 | user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage); |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 369e838bebd3..54e8ef96cb79 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
| @@ -265,7 +265,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
| 265 | else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 265 | else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
| 266 | __u16 fid; | 266 | __u16 fid; |
| 267 | int oplock = FALSE; | 267 | int oplock = FALSE; |
| 268 | if (experimEnabled) | 268 | struct cifs_ntsd *pacl = NULL; |
| 269 | __u32 buflen = 0; | ||
| 270 | if (experimEnabled) | ||
| 269 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 271 | rc = CIFSSMBOpen(xid, pTcon, full_path, |
| 270 | FILE_OPEN, GENERIC_READ, 0, &fid, | 272 | FILE_OPEN, GENERIC_READ, 0, &fid, |
| 271 | &oplock, NULL, cifs_sb->local_nls, | 273 | &oplock, NULL, cifs_sb->local_nls, |
| @@ -273,10 +275,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
| 273 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 275 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 274 | /* else rc is EOPNOTSUPP from above */ | 276 | /* else rc is EOPNOTSUPP from above */ |
| 275 | 277 | ||
| 276 | if(rc == 0) { | 278 | if (rc == 0) { |
| 277 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, | 279 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl, |
| 278 | ea_value, buf_size, | 280 | &buflen); |
| 279 | ACL_TYPE_ACCESS); | ||
| 280 | CIFSSMBClose(xid, pTcon, fid); | 281 | CIFSSMBClose(xid, pTcon, fid); |
| 281 | } | 282 | } |
| 282 | } | 283 | } |
| @@ -1692,7 +1692,10 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
| 1692 | if (!binfmt || !binfmt->core_dump) | 1692 | if (!binfmt || !binfmt->core_dump) |
| 1693 | goto fail; | 1693 | goto fail; |
| 1694 | down_write(&mm->mmap_sem); | 1694 | down_write(&mm->mmap_sem); |
| 1695 | if (!get_dumpable(mm)) { | 1695 | /* |
| 1696 | * If another thread got here first, or we are not dumpable, bail out. | ||
| 1697 | */ | ||
| 1698 | if (mm->core_waiters || !get_dumpable(mm)) { | ||
| 1696 | up_write(&mm->mmap_sem); | 1699 | up_write(&mm->mmap_sem); |
| 1697 | goto fail; | 1700 | goto fail; |
| 1698 | } | 1701 | } |
| @@ -1706,7 +1709,6 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
| 1706 | flag = O_EXCL; /* Stop rewrite attacks */ | 1709 | flag = O_EXCL; /* Stop rewrite attacks */ |
| 1707 | current->fsuid = 0; /* Dump root private */ | 1710 | current->fsuid = 0; /* Dump root private */ |
| 1708 | } | 1711 | } |
| 1709 | set_dumpable(mm, 0); | ||
| 1710 | 1712 | ||
| 1711 | retval = coredump_wait(exit_code); | 1713 | retval = coredump_wait(exit_code); |
| 1712 | if (retval < 0) | 1714 | if (retval < 0) |
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 18a42de25b55..377ad172d74b 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
| @@ -69,14 +69,6 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, | |||
| 69 | return desc + offset; | 69 | return desc + offset; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static inline int | ||
| 73 | block_in_use(unsigned long block, struct super_block *sb, unsigned char *map) | ||
| 74 | { | ||
| 75 | return ext2_test_bit ((block - | ||
| 76 | le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) % | ||
| 77 | EXT2_BLOCKS_PER_GROUP(sb), map); | ||
| 78 | } | ||
| 79 | |||
| 80 | /* | 72 | /* |
| 81 | * Read the bitmap for a given block_group, reading into the specified | 73 | * Read the bitmap for a given block_group, reading into the specified |
| 82 | * slot in the superblock's bitmap cache. | 74 | * slot in the superblock's bitmap cache. |
| @@ -86,51 +78,20 @@ block_in_use(unsigned long block, struct super_block *sb, unsigned char *map) | |||
| 86 | static struct buffer_head * | 78 | static struct buffer_head * |
| 87 | read_block_bitmap(struct super_block *sb, unsigned int block_group) | 79 | read_block_bitmap(struct super_block *sb, unsigned int block_group) |
| 88 | { | 80 | { |
| 89 | int i; | ||
| 90 | struct ext2_group_desc * desc; | 81 | struct ext2_group_desc * desc; |
| 91 | struct buffer_head * bh = NULL; | 82 | struct buffer_head * bh = NULL; |
| 92 | unsigned int bitmap_blk; | 83 | |
| 93 | |||
| 94 | desc = ext2_get_group_desc (sb, block_group, NULL); | 84 | desc = ext2_get_group_desc (sb, block_group, NULL); |
| 95 | if (!desc) | 85 | if (!desc) |
| 96 | return NULL; | 86 | goto error_out; |
| 97 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); | 87 | bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); |
| 98 | bh = sb_bread(sb, bitmap_blk); | ||
| 99 | if (!bh) | 88 | if (!bh) |
| 100 | ext2_error (sb, __FUNCTION__, | 89 | ext2_error (sb, "read_block_bitmap", |
| 101 | "Cannot read block bitmap - " | 90 | "Cannot read block bitmap - " |
| 102 | "block_group = %d, block_bitmap = %u", | 91 | "block_group = %d, block_bitmap = %u", |
| 103 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | 92 | block_group, le32_to_cpu(desc->bg_block_bitmap)); |
| 104 | |||
| 105 | /* check whether block bitmap block number is set */ | ||
| 106 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 107 | /* bad block bitmap */ | ||
| 108 | goto error_out; | ||
| 109 | } | ||
| 110 | /* check whether the inode bitmap block number is set */ | ||
| 111 | bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); | ||
| 112 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 113 | /* bad block bitmap */ | ||
| 114 | goto error_out; | ||
| 115 | } | ||
| 116 | /* check whether the inode table block number is set */ | ||
| 117 | bitmap_blk = le32_to_cpu(desc->bg_inode_table); | ||
| 118 | for (i = 0; i < EXT2_SB(sb)->s_itb_per_group; i++, bitmap_blk++) { | ||
| 119 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 120 | /* bad block bitmap */ | ||
| 121 | goto error_out; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | return bh; | ||
| 126 | |||
| 127 | error_out: | 93 | error_out: |
| 128 | brelse(bh); | 94 | return bh; |
| 129 | ext2_error(sb, __FUNCTION__, | ||
| 130 | "Invalid block bitmap - " | ||
| 131 | "block_group = %d, block = %u", | ||
| 132 | block_group, bitmap_blk); | ||
| 133 | return NULL; | ||
| 134 | } | 95 | } |
| 135 | 96 | ||
| 136 | static void release_blocks(struct super_block *sb, int count) | 97 | static void release_blocks(struct super_block *sb, int count) |
| @@ -1461,7 +1422,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb) | |||
| 1461 | #endif | 1422 | #endif |
| 1462 | } | 1423 | } |
| 1463 | 1424 | ||
| 1464 | |||
| 1465 | static inline int test_root(int a, int b) | 1425 | static inline int test_root(int a, int b) |
| 1466 | { | 1426 | { |
| 1467 | int num = b; | 1427 | int num = b; |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 7a87d15523be..a8ba7e831278 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
| @@ -80,14 +80,6 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, | |||
| 80 | return desc + offset; | 80 | return desc + offset; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static inline int | ||
| 84 | block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map) | ||
| 85 | { | ||
| 86 | return ext3_test_bit ((block - | ||
| 87 | le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) % | ||
| 88 | EXT3_BLOCKS_PER_GROUP(sb), map); | ||
| 89 | } | ||
| 90 | |||
| 91 | /** | 83 | /** |
| 92 | * read_block_bitmap() | 84 | * read_block_bitmap() |
| 93 | * @sb: super block | 85 | * @sb: super block |
| @@ -101,51 +93,20 @@ block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map) | |||
| 101 | static struct buffer_head * | 93 | static struct buffer_head * |
| 102 | read_block_bitmap(struct super_block *sb, unsigned int block_group) | 94 | read_block_bitmap(struct super_block *sb, unsigned int block_group) |
| 103 | { | 95 | { |
| 104 | int i; | ||
| 105 | struct ext3_group_desc * desc; | 96 | struct ext3_group_desc * desc; |
| 106 | struct buffer_head * bh = NULL; | 97 | struct buffer_head * bh = NULL; |
| 107 | ext3_fsblk_t bitmap_blk; | ||
| 108 | 98 | ||
| 109 | desc = ext3_get_group_desc (sb, block_group, NULL); | 99 | desc = ext3_get_group_desc (sb, block_group, NULL); |
| 110 | if (!desc) | 100 | if (!desc) |
| 111 | return NULL; | 101 | goto error_out; |
| 112 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); | 102 | bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); |
| 113 | bh = sb_bread(sb, bitmap_blk); | ||
| 114 | if (!bh) | 103 | if (!bh) |
| 115 | ext3_error (sb, __FUNCTION__, | 104 | ext3_error (sb, "read_block_bitmap", |
| 116 | "Cannot read block bitmap - " | 105 | "Cannot read block bitmap - " |
| 117 | "block_group = %d, block_bitmap = %u", | 106 | "block_group = %d, block_bitmap = %u", |
| 118 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | 107 | block_group, le32_to_cpu(desc->bg_block_bitmap)); |
| 119 | |||
| 120 | /* check whether block bitmap block number is set */ | ||
| 121 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 122 | /* bad block bitmap */ | ||
| 123 | goto error_out; | ||
| 124 | } | ||
| 125 | /* check whether the inode bitmap block number is set */ | ||
| 126 | bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); | ||
| 127 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 128 | /* bad block bitmap */ | ||
| 129 | goto error_out; | ||
| 130 | } | ||
| 131 | /* check whether the inode table block number is set */ | ||
| 132 | bitmap_blk = le32_to_cpu(desc->bg_inode_table); | ||
| 133 | for (i = 0; i < EXT3_SB(sb)->s_itb_per_group; i++, bitmap_blk++) { | ||
| 134 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 135 | /* bad block bitmap */ | ||
| 136 | goto error_out; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | return bh; | ||
| 141 | |||
| 142 | error_out: | 108 | error_out: |
| 143 | brelse(bh); | 109 | return bh; |
| 144 | ext3_error(sb, __FUNCTION__, | ||
| 145 | "Invalid block bitmap - " | ||
| 146 | "block_group = %d, block = %lu", | ||
| 147 | block_group, bitmap_blk); | ||
| 148 | return NULL; | ||
| 149 | } | 110 | } |
| 150 | /* | 111 | /* |
| 151 | * The reservation window structure operations | 112 | * The reservation window structure operations |
| @@ -1772,7 +1733,6 @@ ext3_fsblk_t ext3_count_free_blocks(struct super_block *sb) | |||
| 1772 | #endif | 1733 | #endif |
| 1773 | } | 1734 | } |
| 1774 | 1735 | ||
| 1775 | |||
| 1776 | static inline int test_root(int a, int b) | 1736 | static inline int test_root(int a, int b) |
| 1777 | { | 1737 | { |
| 1778 | int num = b; | 1738 | int num = b; |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index e906b65448e2..71ee95e534fd 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -189,15 +189,6 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, | |||
| 189 | return desc; | 189 | return desc; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | static inline int | ||
| 193 | block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) | ||
| 194 | { | ||
| 195 | ext4_grpblk_t offset; | ||
| 196 | |||
| 197 | ext4_get_group_no_and_offset(sb, block, NULL, &offset); | ||
| 198 | return ext4_test_bit (offset, map); | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | 192 | /** |
| 202 | * read_block_bitmap() | 193 | * read_block_bitmap() |
| 203 | * @sb: super block | 194 | * @sb: super block |
| @@ -211,7 +202,6 @@ block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) | |||
| 211 | struct buffer_head * | 202 | struct buffer_head * |
| 212 | read_block_bitmap(struct super_block *sb, unsigned int block_group) | 203 | read_block_bitmap(struct super_block *sb, unsigned int block_group) |
| 213 | { | 204 | { |
| 214 | int i; | ||
| 215 | struct ext4_group_desc * desc; | 205 | struct ext4_group_desc * desc; |
| 216 | struct buffer_head * bh = NULL; | 206 | struct buffer_head * bh = NULL; |
| 217 | ext4_fsblk_t bitmap_blk; | 207 | ext4_fsblk_t bitmap_blk; |
| @@ -239,38 +229,7 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
| 239 | "Cannot read block bitmap - " | 229 | "Cannot read block bitmap - " |
| 240 | "block_group = %d, block_bitmap = %llu", | 230 | "block_group = %d, block_bitmap = %llu", |
| 241 | block_group, bitmap_blk); | 231 | block_group, bitmap_blk); |
| 242 | |||
| 243 | /* check whether block bitmap block number is set */ | ||
| 244 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 245 | /* bad block bitmap */ | ||
| 246 | goto error_out; | ||
| 247 | } | ||
| 248 | |||
| 249 | /* check whether the inode bitmap block number is set */ | ||
| 250 | bitmap_blk = ext4_inode_bitmap(sb, desc); | ||
| 251 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 252 | /* bad block bitmap */ | ||
| 253 | goto error_out; | ||
| 254 | } | ||
| 255 | /* check whether the inode table block number is set */ | ||
| 256 | bitmap_blk = ext4_inode_table(sb, desc); | ||
| 257 | for (i = 0; i < EXT4_SB(sb)->s_itb_per_group; i++, bitmap_blk++) { | ||
| 258 | if (!block_in_use(bitmap_blk, sb, bh->b_data)) { | ||
| 259 | /* bad block bitmap */ | ||
| 260 | goto error_out; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | return bh; | 232 | return bh; |
| 265 | |||
| 266 | error_out: | ||
| 267 | brelse(bh); | ||
| 268 | ext4_error(sb, __FUNCTION__, | ||
| 269 | "Invalid block bitmap - " | ||
| 270 | "block_group = %d, block = %llu", | ||
| 271 | block_group, bitmap_blk); | ||
| 272 | return NULL; | ||
| 273 | |||
| 274 | } | 233 | } |
| 275 | /* | 234 | /* |
| 276 | * The reservation window structure operations | 235 | * The reservation window structure operations |
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index b61742885011..0e5fa11e6b44 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c | |||
| @@ -41,7 +41,7 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, | |||
| 41 | 41 | ||
| 42 | fh = fh_copy(&resp->fh, &argp->fh); | 42 | fh = fh_copy(&resp->fh, &argp->fh); |
| 43 | if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) | 43 | if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) |
| 44 | RETURN_STATUS(nfserr_inval); | 44 | RETURN_STATUS(nfserr); |
| 45 | 45 | ||
| 46 | if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) | 46 | if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) |
| 47 | RETURN_STATUS(nfserr_inval); | 47 | RETURN_STATUS(nfserr_inval); |
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 3e3f2de82c36..b647f2f872dc 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c | |||
| @@ -37,7 +37,7 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp, | |||
| 37 | 37 | ||
| 38 | fh = fh_copy(&resp->fh, &argp->fh); | 38 | fh = fh_copy(&resp->fh, &argp->fh); |
| 39 | if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) | 39 | if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) |
| 40 | RETURN_STATUS(nfserr_inval); | 40 | RETURN_STATUS(nfserr); |
| 41 | 41 | ||
| 42 | if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) | 42 | if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) |
| 43 | RETURN_STATUS(nfserr_inval); | 43 | RETURN_STATUS(nfserr_inval); |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 4f712e970584..468f17a78441 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
| @@ -95,6 +95,22 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) | |||
| 95 | return 0; | 95 | return 0; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, | ||
| 99 | struct svc_export *exp) | ||
| 100 | { | ||
| 101 | /* Check if the request originated from a secure port. */ | ||
| 102 | if (!rqstp->rq_secure && EX_SECURE(exp)) { | ||
| 103 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
| 104 | dprintk(KERN_WARNING | ||
| 105 | "nfsd: request from insecure port %s!\n", | ||
| 106 | svc_print_addr(rqstp, buf, sizeof(buf))); | ||
| 107 | return nfserr_perm; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* Set user creds for this exportpoint */ | ||
| 111 | return nfserrno(nfsd_setuser(rqstp, exp)); | ||
| 112 | } | ||
| 113 | |||
| 98 | /* | 114 | /* |
| 99 | * Perform sanity checks on the dentry in a client's file handle. | 115 | * Perform sanity checks on the dentry in a client's file handle. |
| 100 | * | 116 | * |
| @@ -167,18 +183,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
| 167 | goto out; | 183 | goto out; |
| 168 | } | 184 | } |
| 169 | 185 | ||
| 170 | /* Check if the request originated from a secure port. */ | 186 | error = nfsd_setuser_and_check_port(rqstp, exp); |
| 171 | error = nfserr_perm; | ||
| 172 | if (!rqstp->rq_secure && EX_SECURE(exp)) { | ||
| 173 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
| 174 | printk(KERN_WARNING | ||
| 175 | "nfsd: request from insecure port %s!\n", | ||
| 176 | svc_print_addr(rqstp, buf, sizeof(buf))); | ||
| 177 | goto out; | ||
| 178 | } | ||
| 179 | |||
| 180 | /* Set user creds for this exportpoint */ | ||
| 181 | error = nfserrno(nfsd_setuser(rqstp, exp)); | ||
| 182 | if (error) | 187 | if (error) |
| 183 | goto out; | 188 | goto out; |
| 184 | 189 | ||
| @@ -227,18 +232,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
| 227 | fhp->fh_export = exp; | 232 | fhp->fh_export = exp; |
| 228 | nfsd_nr_verified++; | 233 | nfsd_nr_verified++; |
| 229 | } else { | 234 | } else { |
| 230 | /* just rechecking permissions | 235 | /* |
| 231 | * (e.g. nfsproc_create calls fh_verify, then nfsd_create does as well) | 236 | * just rechecking permissions |
| 237 | * (e.g. nfsproc_create calls fh_verify, then nfsd_create | ||
| 238 | * does as well) | ||
| 232 | */ | 239 | */ |
| 233 | dprintk("nfsd: fh_verify - just checking\n"); | 240 | dprintk("nfsd: fh_verify - just checking\n"); |
| 234 | dentry = fhp->fh_dentry; | 241 | dentry = fhp->fh_dentry; |
| 235 | exp = fhp->fh_export; | 242 | exp = fhp->fh_export; |
| 236 | /* Set user creds for this exportpoint; necessary even | 243 | /* |
| 244 | * Set user creds for this exportpoint; necessary even | ||
| 237 | * in the "just checking" case because this may be a | 245 | * in the "just checking" case because this may be a |
| 238 | * filehandle that was created by fh_compose, and that | 246 | * filehandle that was created by fh_compose, and that |
| 239 | * is about to be used in another nfsv4 compound | 247 | * is about to be used in another nfsv4 compound |
| 240 | * operation */ | 248 | * operation. |
| 241 | error = nfserrno(nfsd_setuser(rqstp, exp)); | 249 | */ |
| 250 | error = nfsd_setuser_and_check_port(rqstp, exp); | ||
| 242 | if (error) | 251 | if (error) |
| 243 | goto out; | 252 | goto out; |
| 244 | } | 253 | } |
diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h index 0217b74cc9fc..3a4ffba3d6bc 100644 --- a/include/asm-x86/i387_64.h +++ b/include/asm-x86/i387_64.h | |||
| @@ -203,6 +203,11 @@ static inline void save_init_fpu(struct task_struct *tsk) | |||
| 203 | */ | 203 | */ |
| 204 | static inline int restore_i387(struct _fpstate __user *buf) | 204 | static inline int restore_i387(struct _fpstate __user *buf) |
| 205 | { | 205 | { |
| 206 | set_used_math(); | ||
| 207 | if (!(task_thread_info(current)->status & TS_USEDFPU)) { | ||
| 208 | clts(); | ||
| 209 | task_thread_info(current)->status |= TS_USEDFPU; | ||
| 210 | } | ||
| 206 | return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); | 211 | return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); |
| 207 | } | 212 | } |
| 208 | 213 | ||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 94e49915a8c0..91140fe8c119 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -387,7 +387,9 @@ extern void skb_truesize_bug(struct sk_buff *skb); | |||
| 387 | 387 | ||
| 388 | static inline void skb_truesize_check(struct sk_buff *skb) | 388 | static inline void skb_truesize_check(struct sk_buff *skb) |
| 389 | { | 389 | { |
| 390 | if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len)) | 390 | int len = sizeof(struct sk_buff) + skb->len; |
| 391 | |||
| 392 | if (unlikely((int)skb->truesize < len)) | ||
| 391 | skb_truesize_bug(skb); | 393 | skb_truesize_bug(skb); |
| 392 | } | 394 | } |
| 393 | 395 | ||
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index ac69e7bb5a14..1a4ed49f6478 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h | |||
| @@ -67,7 +67,7 @@ struct vring { | |||
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | /* The standard layout for the ring is a continuous chunk of memory which looks | 69 | /* The standard layout for the ring is a continuous chunk of memory which looks |
| 70 | * like this. The used fields will be aligned to a "num+1" boundary. | 70 | * like this. We assume num is a power of 2. |
| 71 | * | 71 | * |
| 72 | * struct vring | 72 | * struct vring |
| 73 | * { | 73 | * { |
| @@ -79,8 +79,8 @@ struct vring { | |||
| 79 | * __u16 avail_idx; | 79 | * __u16 avail_idx; |
| 80 | * __u16 available[num]; | 80 | * __u16 available[num]; |
| 81 | * | 81 | * |
| 82 | * // Padding so a correctly-chosen num value will cache-align used_idx. | 82 | * // Padding to the next page boundary. |
| 83 | * char pad[sizeof(struct vring_desc) - sizeof(avail_flags)]; | 83 | * char pad[]; |
| 84 | * | 84 | * |
| 85 | * // A ring of used descriptor heads with free-running index. | 85 | * // A ring of used descriptor heads with free-running index. |
| 86 | * __u16 used_flags; | 86 | * __u16 used_flags; |
| @@ -88,18 +88,21 @@ struct vring { | |||
| 88 | * struct vring_used_elem used[num]; | 88 | * struct vring_used_elem used[num]; |
| 89 | * }; | 89 | * }; |
| 90 | */ | 90 | */ |
| 91 | static inline void vring_init(struct vring *vr, unsigned int num, void *p) | 91 | static inline void vring_init(struct vring *vr, unsigned int num, void *p, |
| 92 | unsigned int pagesize) | ||
| 92 | { | 93 | { |
| 93 | vr->num = num; | 94 | vr->num = num; |
| 94 | vr->desc = p; | 95 | vr->desc = p; |
| 95 | vr->avail = p + num*sizeof(struct vring); | 96 | vr->avail = p + num*sizeof(struct vring_desc); |
| 96 | vr->used = p + (num+1)*(sizeof(struct vring) + sizeof(__u16)); | 97 | vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + pagesize-1) |
| 98 | & ~(pagesize - 1)); | ||
| 97 | } | 99 | } |
| 98 | 100 | ||
| 99 | static inline unsigned vring_size(unsigned int num) | 101 | static inline unsigned vring_size(unsigned int num, unsigned int pagesize) |
| 100 | { | 102 | { |
| 101 | return (num + 1) * (sizeof(struct vring_desc) + sizeof(__u16)) | 103 | return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) |
| 102 | + sizeof(__u32) + num * sizeof(struct vring_used_elem); | 104 | + pagesize - 1) & ~(pagesize - 1)) |
| 105 | + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num; | ||
| 103 | } | 106 | } |
| 104 | 107 | ||
| 105 | #ifdef __KERNEL__ | 108 | #ifdef __KERNEL__ |
diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 0864a775de24..a1c805d7f488 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h | |||
| @@ -12,7 +12,7 @@ extern void unix_gc(void); | |||
| 12 | 12 | ||
| 13 | #define UNIX_HASH_SIZE 256 | 13 | #define UNIX_HASH_SIZE 256 |
| 14 | 14 | ||
| 15 | extern atomic_t unix_tot_inflight; | 15 | extern unsigned int unix_tot_inflight; |
| 16 | 16 | ||
| 17 | struct unix_address { | 17 | struct unix_address { |
| 18 | atomic_t refcnt; | 18 | atomic_t refcnt; |
diff --git a/include/net/dst.h b/include/net/dst.h index e9ff4a4caef9..2f65e894b829 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
| @@ -143,6 +143,13 @@ static inline void dst_hold(struct dst_entry * dst) | |||
| 143 | atomic_inc(&dst->__refcnt); | 143 | atomic_inc(&dst->__refcnt); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static inline void dst_use(struct dst_entry *dst, unsigned long time) | ||
| 147 | { | ||
| 148 | dst_hold(dst); | ||
| 149 | dst->__use++; | ||
| 150 | dst->lastuse = time; | ||
| 151 | } | ||
| 152 | |||
| 146 | static inline | 153 | static inline |
| 147 | struct dst_entry * dst_clone(struct dst_entry * dst) | 154 | struct dst_entry * dst_clone(struct dst_entry * dst) |
| 148 | { | 155 | { |
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index 017aebd90683..41a301e38643 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h | |||
| @@ -107,4 +107,7 @@ extern int fib_rules_unregister(struct fib_rules_ops *); | |||
| 107 | extern int fib_rules_lookup(struct fib_rules_ops *, | 107 | extern int fib_rules_lookup(struct fib_rules_ops *, |
| 108 | struct flowi *, int flags, | 108 | struct flowi *, int flags, |
| 109 | struct fib_lookup_arg *); | 109 | struct fib_lookup_arg *); |
| 110 | extern int fib_default_rule_add(struct fib_rules_ops *, | ||
| 111 | u32 pref, u32 table, | ||
| 112 | u32 flags); | ||
| 110 | #endif | 113 | #endif |
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 8461cda37490..469216d93663 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
| 24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
| 25 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
| 26 | #include <linux/vmalloc.h> | ||
| 26 | 27 | ||
| 27 | #include <net/inet_connection_sock.h> | 28 | #include <net/inet_connection_sock.h> |
| 28 | #include <net/inet_sock.h> | 29 | #include <net/inet_sock.h> |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5fcc4c104340..17b60391fcd6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -706,11 +706,16 @@ enum ieee80211_hw_flags { | |||
| 706 | * | 706 | * |
| 707 | * @queues: number of available hardware transmit queues for | 707 | * @queues: number of available hardware transmit queues for |
| 708 | * data packets. WMM/QoS requires at least four. | 708 | * data packets. WMM/QoS requires at least four. |
| 709 | * | ||
| 710 | * @rate_control_algorithm: rate control algorithm for this hardware. | ||
| 711 | * If unset (NULL), the default algorithm will be used. Must be | ||
| 712 | * set before calling ieee80211_register_hw(). | ||
| 709 | */ | 713 | */ |
| 710 | struct ieee80211_hw { | 714 | struct ieee80211_hw { |
| 711 | struct ieee80211_conf conf; | 715 | struct ieee80211_conf conf; |
| 712 | struct wiphy *wiphy; | 716 | struct wiphy *wiphy; |
| 713 | struct workqueue_struct *workqueue; | 717 | struct workqueue_struct *workqueue; |
| 718 | const char *rate_control_algorithm; | ||
| 714 | void *priv; | 719 | void *priv; |
| 715 | u32 flags; | 720 | u32 flags; |
| 716 | unsigned int extra_tx_headroom; | 721 | unsigned int extra_tx_headroom; |
| @@ -936,27 +941,11 @@ enum ieee80211_erp_change_flags { | |||
| 936 | * and remove_interface calls, i.e. while the interface with the | 941 | * and remove_interface calls, i.e. while the interface with the |
| 937 | * given local_address is enabled. | 942 | * given local_address is enabled. |
| 938 | * | 943 | * |
| 939 | * @set_ieee8021x: Enable/disable IEEE 802.1X. This item requests wlan card | ||
| 940 | * to pass unencrypted EAPOL-Key frames even when encryption is | ||
| 941 | * configured. If the wlan card does not require such a configuration, | ||
| 942 | * this function pointer can be set to NULL. | ||
| 943 | * | ||
| 944 | * @set_port_auth: Set port authorization state (IEEE 802.1X PAE) to be | ||
| 945 | * authorized (@authorized=1) or unauthorized (=0). This function can be | ||
| 946 | * used if the wlan hardware or low-level driver implements PAE. | ||
| 947 | * mac80211 will filter frames based on authorization state in any case, | ||
| 948 | * so this function pointer can be NULL if low-level driver does not | ||
| 949 | * require event notification about port state changes. | ||
| 950 | * | ||
| 951 | * @hw_scan: Ask the hardware to service the scan request, no need to start | 944 | * @hw_scan: Ask the hardware to service the scan request, no need to start |
| 952 | * the scan state machine in stack. | 945 | * the scan state machine in stack. |
| 953 | * | 946 | * |
| 954 | * @get_stats: return low-level statistics | 947 | * @get_stats: return low-level statistics |
| 955 | * | 948 | * |
| 956 | * @set_privacy_invoked: For devices that generate their own beacons and probe | ||
| 957 | * response or association responses this updates the state of privacy_invoked | ||
| 958 | * returns 0 for success or an error number. | ||
| 959 | * | ||
| 960 | * @get_sequence_counter: For devices that have internal sequence counters this | 949 | * @get_sequence_counter: For devices that have internal sequence counters this |
| 961 | * callback allows mac80211 to access the current value of a counter. | 950 | * callback allows mac80211 to access the current value of a counter. |
| 962 | * This callback seems not well-defined, tell us if you need it. | 951 | * This callback seems not well-defined, tell us if you need it. |
| @@ -1029,14 +1018,9 @@ struct ieee80211_ops { | |||
| 1029 | int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 1018 | int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| 1030 | const u8 *local_address, const u8 *address, | 1019 | const u8 *local_address, const u8 *address, |
| 1031 | struct ieee80211_key_conf *key); | 1020 | struct ieee80211_key_conf *key); |
| 1032 | int (*set_ieee8021x)(struct ieee80211_hw *hw, int use_ieee8021x); | ||
| 1033 | int (*set_port_auth)(struct ieee80211_hw *hw, u8 *addr, | ||
| 1034 | int authorized); | ||
| 1035 | int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len); | 1021 | int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len); |
| 1036 | int (*get_stats)(struct ieee80211_hw *hw, | 1022 | int (*get_stats)(struct ieee80211_hw *hw, |
| 1037 | struct ieee80211_low_level_stats *stats); | 1023 | struct ieee80211_low_level_stats *stats); |
| 1038 | int (*set_privacy_invoked)(struct ieee80211_hw *hw, | ||
| 1039 | int privacy_invoked); | ||
| 1040 | int (*get_sequence_counter)(struct ieee80211_hw *hw, | 1024 | int (*get_sequence_counter)(struct ieee80211_hw *hw, |
| 1041 | u8* addr, u8 keyidx, u8 txrx, | 1025 | u8* addr, u8 keyidx, u8 txrx, |
| 1042 | u32* iv32, u16* iv16); | 1026 | u32* iv32, u16* iv16); |
diff --git a/kernel/signal.c b/kernel/signal.c index 909a0cc6bc70..afa4f781f924 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -55,7 +55,7 @@ static int sig_ignored(struct task_struct *t, int sig) | |||
| 55 | * signal handler may change by the time it is | 55 | * signal handler may change by the time it is |
| 56 | * unblocked. | 56 | * unblocked. |
| 57 | */ | 57 | */ |
| 58 | if (sigismember(&t->blocked, sig)) | 58 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) |
| 59 | return 0; | 59 | return 0; |
| 60 | 60 | ||
| 61 | /* Is it explicitly or implicitly ignored? */ | 61 | /* Is it explicitly or implicitly ignored? */ |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index da69d833e067..12376ae3f733 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -749,23 +749,6 @@ int move_freepages_block(struct zone *zone, struct page *page, int migratetype) | |||
| 749 | return move_freepages(zone, start_page, end_page, migratetype); | 749 | return move_freepages(zone, start_page, end_page, migratetype); |
| 750 | } | 750 | } |
| 751 | 751 | ||
| 752 | /* Return the page with the lowest PFN in the list */ | ||
| 753 | static struct page *min_page(struct list_head *list) | ||
| 754 | { | ||
| 755 | unsigned long min_pfn = -1UL; | ||
| 756 | struct page *min_page = NULL, *page;; | ||
| 757 | |||
| 758 | list_for_each_entry(page, list, lru) { | ||
| 759 | unsigned long pfn = page_to_pfn(page); | ||
| 760 | if (pfn < min_pfn) { | ||
| 761 | min_pfn = pfn; | ||
| 762 | min_page = page; | ||
| 763 | } | ||
| 764 | } | ||
| 765 | |||
| 766 | return min_page; | ||
| 767 | } | ||
| 768 | |||
| 769 | /* Remove an element from the buddy allocator from the fallback list */ | 752 | /* Remove an element from the buddy allocator from the fallback list */ |
| 770 | static struct page *__rmqueue_fallback(struct zone *zone, int order, | 753 | static struct page *__rmqueue_fallback(struct zone *zone, int order, |
| 771 | int start_migratetype) | 754 | int start_migratetype) |
| @@ -789,11 +772,8 @@ static struct page *__rmqueue_fallback(struct zone *zone, int order, | |||
| 789 | if (list_empty(&area->free_list[migratetype])) | 772 | if (list_empty(&area->free_list[migratetype])) |
| 790 | continue; | 773 | continue; |
| 791 | 774 | ||
| 792 | /* Bias kernel allocations towards low pfns */ | ||
| 793 | page = list_entry(area->free_list[migratetype].next, | 775 | page = list_entry(area->free_list[migratetype].next, |
| 794 | struct page, lru); | 776 | struct page, lru); |
| 795 | if (unlikely(start_migratetype != MIGRATE_MOVABLE)) | ||
| 796 | page = min_page(&area->free_list[migratetype]); | ||
| 797 | area->nr_free--; | 777 | area->nr_free--; |
| 798 | 778 | ||
| 799 | /* | 779 | /* |
| @@ -1080,7 +1080,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) | |||
| 1080 | struct page *page; | 1080 | struct page *page; |
| 1081 | struct kmem_cache_node *n; | 1081 | struct kmem_cache_node *n; |
| 1082 | void *start; | 1082 | void *start; |
| 1083 | void *end; | ||
| 1084 | void *last; | 1083 | void *last; |
| 1085 | void *p; | 1084 | void *p; |
| 1086 | 1085 | ||
| @@ -1101,7 +1100,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) | |||
| 1101 | SetSlabDebug(page); | 1100 | SetSlabDebug(page); |
| 1102 | 1101 | ||
| 1103 | start = page_address(page); | 1102 | start = page_address(page); |
| 1104 | end = start + s->objects * s->size; | ||
| 1105 | 1103 | ||
| 1106 | if (unlikely(s->flags & SLAB_POISON)) | 1104 | if (unlikely(s->flags & SLAB_POISON)) |
| 1107 | memset(start, POISON_INUSE, PAGE_SIZE << s->order); | 1105 | memset(start, POISON_INUSE, PAGE_SIZE << s->order); |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 1037748c14db..6567213959cb 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -376,6 +376,7 @@ void vlan_setup(struct net_device *new_dev) | |||
| 376 | new_dev->init = vlan_dev_init; | 376 | new_dev->init = vlan_dev_init; |
| 377 | new_dev->open = vlan_dev_open; | 377 | new_dev->open = vlan_dev_open; |
| 378 | new_dev->stop = vlan_dev_stop; | 378 | new_dev->stop = vlan_dev_stop; |
| 379 | new_dev->set_mac_address = vlan_set_mac_address; | ||
| 379 | new_dev->set_multicast_list = vlan_dev_set_multicast_list; | 380 | new_dev->set_multicast_list = vlan_dev_set_multicast_list; |
| 380 | new_dev->change_rx_flags = vlan_change_rx_flags; | 381 | new_dev->change_rx_flags = vlan_change_rx_flags; |
| 381 | new_dev->destructor = free_netdev; | 382 | new_dev->destructor = free_netdev; |
| @@ -636,6 +637,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 636 | if (!vlandev) | 637 | if (!vlandev) |
| 637 | continue; | 638 | continue; |
| 638 | 639 | ||
| 640 | flgs = vlandev->flags; | ||
| 641 | if (!(flgs & IFF_UP)) | ||
| 642 | continue; | ||
| 643 | |||
| 639 | vlan_sync_address(dev, vlandev); | 644 | vlan_sync_address(dev, vlandev); |
| 640 | } | 645 | } |
| 641 | break; | 646 | break; |
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index cf4a80d06b35..2cd1393073ec 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
| @@ -60,6 +60,7 @@ int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 60 | int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); | 60 | int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); |
| 61 | int vlan_dev_open(struct net_device* dev); | 61 | int vlan_dev_open(struct net_device* dev); |
| 62 | int vlan_dev_stop(struct net_device* dev); | 62 | int vlan_dev_stop(struct net_device* dev); |
| 63 | int vlan_set_mac_address(struct net_device *dev, void *p); | ||
| 63 | int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); | 64 | int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); |
| 64 | void vlan_dev_set_ingress_priority(const struct net_device *dev, | 65 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
| 65 | u32 skb_prio, short vlan_prio); | 66 | u32 skb_prio, short vlan_prio); |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 1a1740aa9a8b..7a36878241da 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -665,6 +665,32 @@ int vlan_dev_stop(struct net_device *dev) | |||
| 665 | return 0; | 665 | return 0; |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | int vlan_set_mac_address(struct net_device *dev, void *p) | ||
| 669 | { | ||
| 670 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | ||
| 671 | struct sockaddr *addr = p; | ||
| 672 | int err; | ||
| 673 | |||
| 674 | if (!is_valid_ether_addr(addr->sa_data)) | ||
| 675 | return -EADDRNOTAVAIL; | ||
| 676 | |||
| 677 | if (!(dev->flags & IFF_UP)) | ||
| 678 | goto out; | ||
| 679 | |||
| 680 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { | ||
| 681 | err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN); | ||
| 682 | if (err < 0) | ||
| 683 | return err; | ||
| 684 | } | ||
| 685 | |||
| 686 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | ||
| 687 | dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); | ||
| 688 | |||
| 689 | out: | ||
| 690 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | ||
| 691 | return 0; | ||
| 692 | } | ||
| 693 | |||
| 668 | int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 694 | int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
| 669 | { | 695 | { |
| 670 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | 696 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; |
diff --git a/net/core/dev.c b/net/core/dev.c index be6cedab5aa8..dd7e30754cbc 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -4330,7 +4330,6 @@ static struct hlist_head *netdev_create_hash(void) | |||
| 4330 | static int __net_init netdev_init(struct net *net) | 4330 | static int __net_init netdev_init(struct net *net) |
| 4331 | { | 4331 | { |
| 4332 | INIT_LIST_HEAD(&net->dev_base_head); | 4332 | INIT_LIST_HEAD(&net->dev_base_head); |
| 4333 | rwlock_init(&dev_base_lock); | ||
| 4334 | 4333 | ||
| 4335 | net->dev_name_head = netdev_create_hash(); | 4334 | net->dev_name_head = netdev_create_hash(); |
| 4336 | if (net->dev_name_head == NULL) | 4335 | if (net->dev_name_head == NULL) |
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index ae354057d84c..647973daca2b 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c | |||
| @@ -168,13 +168,13 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) | |||
| 168 | da = from->mc_list; | 168 | da = from->mc_list; |
| 169 | while (da != NULL) { | 169 | while (da != NULL) { |
| 170 | next = da->next; | 170 | next = da->next; |
| 171 | if (!da->da_synced) | 171 | if (da->da_synced) { |
| 172 | continue; | 172 | __dev_addr_delete(&to->mc_list, &to->mc_count, |
| 173 | __dev_addr_delete(&to->mc_list, &to->mc_count, | 173 | da->da_addr, da->da_addrlen, 0); |
| 174 | da->da_addr, da->da_addrlen, 0); | 174 | da->da_synced = 0; |
| 175 | da->da_synced = 0; | 175 | __dev_addr_delete(&from->mc_list, &from->mc_count, |
| 176 | __dev_addr_delete(&from->mc_list, &from->mc_count, | 176 | da->da_addr, da->da_addrlen, 0); |
| 177 | da->da_addr, da->da_addrlen, 0); | 177 | } |
| 178 | da = next; | 178 | da = next; |
| 179 | } | 179 | } |
| 180 | __dev_set_rx_mode(to); | 180 | __dev_set_rx_mode(to); |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 13de6f53f098..848132b6cb73 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
| @@ -18,6 +18,28 @@ | |||
| 18 | static LIST_HEAD(rules_ops); | 18 | static LIST_HEAD(rules_ops); |
| 19 | static DEFINE_SPINLOCK(rules_mod_lock); | 19 | static DEFINE_SPINLOCK(rules_mod_lock); |
| 20 | 20 | ||
| 21 | int fib_default_rule_add(struct fib_rules_ops *ops, | ||
| 22 | u32 pref, u32 table, u32 flags) | ||
| 23 | { | ||
| 24 | struct fib_rule *r; | ||
| 25 | |||
| 26 | r = kzalloc(ops->rule_size, GFP_KERNEL); | ||
| 27 | if (r == NULL) | ||
| 28 | return -ENOMEM; | ||
| 29 | |||
| 30 | atomic_set(&r->refcnt, 1); | ||
| 31 | r->action = FR_ACT_TO_TBL; | ||
| 32 | r->pref = pref; | ||
| 33 | r->table = table; | ||
| 34 | r->flags = flags; | ||
| 35 | |||
| 36 | /* The lock is not required here, the list in unreacheable | ||
| 37 | * at the moment this function is called */ | ||
| 38 | list_add_tail(&r->list, &ops->rules_list); | ||
| 39 | return 0; | ||
| 40 | } | ||
| 41 | EXPORT_SYMBOL(fib_default_rule_add); | ||
| 42 | |||
| 21 | static void notify_rule_change(int event, struct fib_rule *rule, | 43 | static void notify_rule_change(int event, struct fib_rule *rule, |
| 22 | struct fib_rules_ops *ops, struct nlmsghdr *nlh, | 44 | struct fib_rules_ops *ops, struct nlmsghdr *nlh, |
| 23 | u32 pid); | 45 | u32 pid); |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 97eee5e8fbbe..66663e5d7acd 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
| @@ -293,9 +293,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route * | |||
| 293 | dn_rt_hash_table[hash].chain); | 293 | dn_rt_hash_table[hash].chain); |
| 294 | rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth); | 294 | rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth); |
| 295 | 295 | ||
| 296 | rth->u.dst.__use++; | 296 | dst_use(&rth->u.dst, now); |
| 297 | dst_hold(&rth->u.dst); | ||
| 298 | rth->u.dst.lastuse = now; | ||
| 299 | spin_unlock_bh(&dn_rt_hash_table[hash].lock); | 297 | spin_unlock_bh(&dn_rt_hash_table[hash].lock); |
| 300 | 298 | ||
| 301 | dnrt_drop(rt); | 299 | dnrt_drop(rt); |
| @@ -308,9 +306,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route * | |||
| 308 | rcu_assign_pointer(rt->u.dst.dn_next, dn_rt_hash_table[hash].chain); | 306 | rcu_assign_pointer(rt->u.dst.dn_next, dn_rt_hash_table[hash].chain); |
| 309 | rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt); | 307 | rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt); |
| 310 | 308 | ||
| 311 | dst_hold(&rt->u.dst); | 309 | dst_use(&rt->u.dst, now); |
| 312 | rt->u.dst.__use++; | ||
| 313 | rt->u.dst.lastuse = now; | ||
| 314 | spin_unlock_bh(&dn_rt_hash_table[hash].lock); | 310 | spin_unlock_bh(&dn_rt_hash_table[hash].lock); |
| 315 | *rp = rt; | 311 | *rp = rt; |
| 316 | return 0; | 312 | return 0; |
| @@ -1182,9 +1178,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl | |||
| 1182 | (flp->mark == rt->fl.mark) && | 1178 | (flp->mark == rt->fl.mark) && |
| 1183 | (rt->fl.iif == 0) && | 1179 | (rt->fl.iif == 0) && |
| 1184 | (rt->fl.oif == flp->oif)) { | 1180 | (rt->fl.oif == flp->oif)) { |
| 1185 | rt->u.dst.lastuse = jiffies; | 1181 | dst_use(&rt->u.dst, jiffies); |
| 1186 | dst_hold(&rt->u.dst); | ||
| 1187 | rt->u.dst.__use++; | ||
| 1188 | rcu_read_unlock_bh(); | 1182 | rcu_read_unlock_bh(); |
| 1189 | *pprt = &rt->u.dst; | 1183 | *pprt = &rt->u.dst; |
| 1190 | return 0; | 1184 | return 0; |
| @@ -1456,9 +1450,7 @@ int dn_route_input(struct sk_buff *skb) | |||
| 1456 | (rt->fl.oif == 0) && | 1450 | (rt->fl.oif == 0) && |
| 1457 | (rt->fl.mark == skb->mark) && | 1451 | (rt->fl.mark == skb->mark) && |
| 1458 | (rt->fl.iif == cb->iif)) { | 1452 | (rt->fl.iif == cb->iif)) { |
| 1459 | rt->u.dst.lastuse = jiffies; | 1453 | dst_use(&rt->u.dst, jiffies); |
| 1460 | dst_hold(&rt->u.dst); | ||
| 1461 | rt->u.dst.__use++; | ||
| 1462 | rcu_read_unlock(); | 1454 | rcu_read_unlock(); |
| 1463 | skb->dst = (struct dst_entry *)rt; | 1455 | skb->dst = (struct dst_entry *)rt; |
| 1464 | return 0; | 1456 | return 0; |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index ddd3f04f0919..ffebea04cc99 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
| @@ -48,15 +48,6 @@ struct dn_fib_rule | |||
| 48 | u8 flags; | 48 | u8 flags; |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | static struct dn_fib_rule default_rule = { | ||
| 52 | .common = { | ||
| 53 | .refcnt = ATOMIC_INIT(2), | ||
| 54 | .pref = 0x7fff, | ||
| 55 | .table = RT_TABLE_MAIN, | ||
| 56 | .action = FR_ACT_TO_TBL, | ||
| 57 | }, | ||
| 58 | }; | ||
| 59 | |||
| 60 | 51 | ||
| 61 | int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res) | 52 | int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res) |
| 62 | { | 53 | { |
| @@ -262,8 +253,8 @@ static struct fib_rules_ops dn_fib_rules_ops = { | |||
| 262 | 253 | ||
| 263 | void __init dn_fib_rules_init(void) | 254 | void __init dn_fib_rules_init(void) |
| 264 | { | 255 | { |
| 265 | list_add_tail(&default_rule.common.list, | 256 | BUG_ON(fib_default_rule_add(&dn_fib_rules_ops, 0x7fff, |
| 266 | &dn_fib_rules_ops.rules_list); | 257 | RT_TABLE_MAIN, 0)); |
| 267 | fib_rules_register(&dn_fib_rules_ops); | 258 | fib_rules_register(&dn_fib_rules_ops); |
| 268 | } | 259 | } |
| 269 | 260 | ||
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index ac36767b56e8..e01b59aedc54 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
| @@ -470,7 +470,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, | |||
| 470 | { | 470 | { |
| 471 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); | 471 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); |
| 472 | struct iw_mlme *mlme = (struct iw_mlme *)extra; | 472 | struct iw_mlme *mlme = (struct iw_mlme *)extra; |
| 473 | u16 reason = cpu_to_le16(mlme->reason_code); | 473 | u16 reason = mlme->reason_code; |
| 474 | struct ieee80211softmac_network *net; | 474 | struct ieee80211softmac_network *net; |
| 475 | int err = -EINVAL; | 475 | int err = -EINVAL; |
| 476 | 476 | ||
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index f16839c6a721..a0ada3a8d8dd 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
| @@ -49,33 +49,6 @@ struct fib4_rule | |||
| 49 | #endif | 49 | #endif |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | static struct fib4_rule default_rule = { | ||
| 53 | .common = { | ||
| 54 | .refcnt = ATOMIC_INIT(2), | ||
| 55 | .pref = 0x7FFF, | ||
| 56 | .table = RT_TABLE_DEFAULT, | ||
| 57 | .action = FR_ACT_TO_TBL, | ||
| 58 | }, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static struct fib4_rule main_rule = { | ||
| 62 | .common = { | ||
| 63 | .refcnt = ATOMIC_INIT(2), | ||
| 64 | .pref = 0x7FFE, | ||
| 65 | .table = RT_TABLE_MAIN, | ||
| 66 | .action = FR_ACT_TO_TBL, | ||
| 67 | }, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct fib4_rule local_rule = { | ||
| 71 | .common = { | ||
| 72 | .refcnt = ATOMIC_INIT(2), | ||
| 73 | .table = RT_TABLE_LOCAL, | ||
| 74 | .action = FR_ACT_TO_TBL, | ||
| 75 | .flags = FIB_RULE_PERMANENT, | ||
| 76 | }, | ||
| 77 | }; | ||
| 78 | |||
| 79 | #ifdef CONFIG_NET_CLS_ROUTE | 52 | #ifdef CONFIG_NET_CLS_ROUTE |
| 80 | u32 fib_rules_tclass(struct fib_result *res) | 53 | u32 fib_rules_tclass(struct fib_result *res) |
| 81 | { | 54 | { |
| @@ -319,11 +292,27 @@ static struct fib_rules_ops fib4_rules_ops = { | |||
| 319 | .owner = THIS_MODULE, | 292 | .owner = THIS_MODULE, |
| 320 | }; | 293 | }; |
| 321 | 294 | ||
| 322 | void __init fib4_rules_init(void) | 295 | static int __init fib_default_rules_init(void) |
| 323 | { | 296 | { |
| 324 | list_add_tail(&local_rule.common.list, &fib4_rules_ops.rules_list); | 297 | int err; |
| 325 | list_add_tail(&main_rule.common.list, &fib4_rules_ops.rules_list); | 298 | |
| 326 | list_add_tail(&default_rule.common.list, &fib4_rules_ops.rules_list); | 299 | err = fib_default_rule_add(&fib4_rules_ops, 0, |
| 300 | RT_TABLE_LOCAL, FIB_RULE_PERMANENT); | ||
| 301 | if (err < 0) | ||
| 302 | return err; | ||
| 303 | err = fib_default_rule_add(&fib4_rules_ops, 0x7FFE, | ||
| 304 | RT_TABLE_MAIN, 0); | ||
| 305 | if (err < 0) | ||
| 306 | return err; | ||
| 307 | err = fib_default_rule_add(&fib4_rules_ops, 0x7FFF, | ||
| 308 | RT_TABLE_DEFAULT, 0); | ||
| 309 | if (err < 0) | ||
| 310 | return err; | ||
| 311 | return 0; | ||
| 312 | } | ||
| 327 | 313 | ||
| 314 | void __init fib4_rules_init(void) | ||
| 315 | { | ||
| 316 | BUG_ON(fib_default_rules_init()); | ||
| 328 | fib_rules_register(&fib4_rules_ops); | 317 | fib_rules_register(&fib4_rules_ops); |
| 329 | } | 318 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 21b12de9e653..45651834e1e2 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -851,9 +851,7 @@ restart: | |||
| 851 | */ | 851 | */ |
| 852 | rcu_assign_pointer(rt_hash_table[hash].chain, rth); | 852 | rcu_assign_pointer(rt_hash_table[hash].chain, rth); |
| 853 | 853 | ||
| 854 | rth->u.dst.__use++; | 854 | dst_use(&rth->u.dst, now); |
| 855 | dst_hold(&rth->u.dst); | ||
| 856 | rth->u.dst.lastuse = now; | ||
| 857 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 855 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
| 858 | 856 | ||
| 859 | rt_drop(rt); | 857 | rt_drop(rt); |
| @@ -1813,11 +1811,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1813 | goto martian_destination; | 1811 | goto martian_destination; |
| 1814 | 1812 | ||
| 1815 | err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos); | 1813 | err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos); |
| 1816 | if (err == -ENOBUFS) | ||
| 1817 | goto e_nobufs; | ||
| 1818 | if (err == -EINVAL) | ||
| 1819 | goto e_inval; | ||
| 1820 | |||
| 1821 | done: | 1814 | done: |
| 1822 | in_dev_put(in_dev); | 1815 | in_dev_put(in_dev); |
| 1823 | if (free_res) | 1816 | if (free_res) |
| @@ -1935,9 +1928,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1935 | rth->fl.oif == 0 && | 1928 | rth->fl.oif == 0 && |
| 1936 | rth->fl.mark == skb->mark && | 1929 | rth->fl.mark == skb->mark && |
| 1937 | rth->fl.fl4_tos == tos) { | 1930 | rth->fl.fl4_tos == tos) { |
| 1938 | rth->u.dst.lastuse = jiffies; | 1931 | dst_use(&rth->u.dst, jiffies); |
| 1939 | dst_hold(&rth->u.dst); | ||
| 1940 | rth->u.dst.__use++; | ||
| 1941 | RT_CACHE_STAT_INC(in_hit); | 1932 | RT_CACHE_STAT_INC(in_hit); |
| 1942 | rcu_read_unlock(); | 1933 | rcu_read_unlock(); |
| 1943 | skb->dst = (struct dst_entry*)rth; | 1934 | skb->dst = (struct dst_entry*)rth; |
| @@ -2331,9 +2322,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp) | |||
| 2331 | rth->fl.mark == flp->mark && | 2322 | rth->fl.mark == flp->mark && |
| 2332 | !((rth->fl.fl4_tos ^ flp->fl4_tos) & | 2323 | !((rth->fl.fl4_tos ^ flp->fl4_tos) & |
| 2333 | (IPTOS_RT_MASK | RTO_ONLINK))) { | 2324 | (IPTOS_RT_MASK | RTO_ONLINK))) { |
| 2334 | rth->u.dst.lastuse = jiffies; | 2325 | dst_use(&rth->u.dst, jiffies); |
| 2335 | dst_hold(&rth->u.dst); | ||
| 2336 | rth->u.dst.__use++; | ||
| 2337 | RT_CACHE_STAT_INC(out_hit); | 2326 | RT_CACHE_STAT_INC(out_hit); |
| 2338 | rcu_read_unlock_bh(); | 2327 | rcu_read_unlock_bh(); |
| 2339 | *rp = rth; | 2328 | *rp = rth; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ca9590f4f520..20c9440ab85e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -1400,11 +1400,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
| 1400 | /* DSACK info lost if out-of-mem, try SACK still */ | 1400 | /* DSACK info lost if out-of-mem, try SACK still */ |
| 1401 | if (in_sack <= 0) | 1401 | if (in_sack <= 0) |
| 1402 | in_sack = tcp_match_skb_to_sack(sk, skb, start_seq, end_seq); | 1402 | in_sack = tcp_match_skb_to_sack(sk, skb, start_seq, end_seq); |
| 1403 | if (in_sack < 0) | 1403 | if (unlikely(in_sack < 0)) |
| 1404 | break; | 1404 | break; |
| 1405 | 1405 | ||
| 1406 | fack_count += tcp_skb_pcount(skb); | ||
| 1407 | |||
| 1408 | sacked = TCP_SKB_CB(skb)->sacked; | 1406 | sacked = TCP_SKB_CB(skb)->sacked; |
| 1409 | 1407 | ||
| 1410 | /* Account D-SACK for retransmitted packet. */ | 1408 | /* Account D-SACK for retransmitted packet. */ |
| @@ -1419,19 +1417,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
| 1419 | if ((dup_sack && in_sack) && | 1417 | if ((dup_sack && in_sack) && |
| 1420 | (sacked&TCPCB_SACKED_ACKED)) | 1418 | (sacked&TCPCB_SACKED_ACKED)) |
| 1421 | reord = min(fack_count, reord); | 1419 | reord = min(fack_count, reord); |
| 1422 | } else { | ||
| 1423 | /* If it was in a hole, we detected reordering. */ | ||
| 1424 | if (fack_count < prior_fackets && | ||
| 1425 | !(sacked&TCPCB_SACKED_ACKED)) | ||
| 1426 | reord = min(fack_count, reord); | ||
| 1427 | } | 1420 | } |
| 1428 | 1421 | ||
| 1429 | /* Nothing to do; acked frame is about to be dropped. */ | 1422 | /* Nothing to do; acked frame is about to be dropped. */ |
| 1423 | fack_count += tcp_skb_pcount(skb); | ||
| 1430 | continue; | 1424 | continue; |
| 1431 | } | 1425 | } |
| 1432 | 1426 | ||
| 1433 | if (!in_sack) | 1427 | if (!in_sack) { |
| 1428 | fack_count += tcp_skb_pcount(skb); | ||
| 1434 | continue; | 1429 | continue; |
| 1430 | } | ||
| 1435 | 1431 | ||
| 1436 | if (!(sacked&TCPCB_SACKED_ACKED)) { | 1432 | if (!(sacked&TCPCB_SACKED_ACKED)) { |
| 1437 | if (sacked & TCPCB_SACKED_RETRANS) { | 1433 | if (sacked & TCPCB_SACKED_RETRANS) { |
| @@ -1448,12 +1444,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
| 1448 | tp->retransmit_skb_hint = NULL; | 1444 | tp->retransmit_skb_hint = NULL; |
| 1449 | } | 1445 | } |
| 1450 | } else { | 1446 | } else { |
| 1451 | /* New sack for not retransmitted frame, | 1447 | if (!(sacked & TCPCB_RETRANS)) { |
| 1452 | * which was in hole. It is reordering. | 1448 | /* New sack for not retransmitted frame, |
| 1453 | */ | 1449 | * which was in hole. It is reordering. |
| 1454 | if (!(sacked & TCPCB_RETRANS) && | 1450 | */ |
| 1455 | fack_count < prior_fackets) | 1451 | if (fack_count < prior_fackets) |
| 1456 | reord = min(fack_count, reord); | 1452 | reord = min(fack_count, reord); |
| 1453 | |||
| 1454 | /* SACK enhanced F-RTO (RFC4138; Appendix B) */ | ||
| 1455 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) | ||
| 1456 | flag |= FLAG_ONLY_ORIG_SACKED; | ||
| 1457 | } | ||
| 1457 | 1458 | ||
| 1458 | if (sacked & TCPCB_LOST) { | 1459 | if (sacked & TCPCB_LOST) { |
| 1459 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; | 1460 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; |
| @@ -1462,24 +1463,13 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
| 1462 | /* clear lost hint */ | 1463 | /* clear lost hint */ |
| 1463 | tp->retransmit_skb_hint = NULL; | 1464 | tp->retransmit_skb_hint = NULL; |
| 1464 | } | 1465 | } |
| 1465 | /* SACK enhanced F-RTO detection. | ||
| 1466 | * Set flag if and only if non-rexmitted | ||
| 1467 | * segments below frto_highmark are | ||
| 1468 | * SACKed (RFC4138; Appendix B). | ||
| 1469 | * Clearing correct due to in-order walk | ||
| 1470 | */ | ||
| 1471 | if (after(end_seq, tp->frto_highmark)) { | ||
| 1472 | flag &= ~FLAG_ONLY_ORIG_SACKED; | ||
| 1473 | } else { | ||
| 1474 | if (!(sacked & TCPCB_RETRANS)) | ||
| 1475 | flag |= FLAG_ONLY_ORIG_SACKED; | ||
| 1476 | } | ||
| 1477 | } | 1466 | } |
| 1478 | 1467 | ||
| 1479 | TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED; | 1468 | TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED; |
| 1480 | flag |= FLAG_DATA_SACKED; | 1469 | flag |= FLAG_DATA_SACKED; |
| 1481 | tp->sacked_out += tcp_skb_pcount(skb); | 1470 | tp->sacked_out += tcp_skb_pcount(skb); |
| 1482 | 1471 | ||
| 1472 | fack_count += tcp_skb_pcount(skb); | ||
| 1483 | if (fack_count > tp->fackets_out) | 1473 | if (fack_count > tp->fackets_out) |
| 1484 | tp->fackets_out = fack_count; | 1474 | tp->fackets_out = fack_count; |
| 1485 | 1475 | ||
| @@ -1490,6 +1480,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
| 1490 | } else { | 1480 | } else { |
| 1491 | if (dup_sack && (sacked&TCPCB_RETRANS)) | 1481 | if (dup_sack && (sacked&TCPCB_RETRANS)) |
| 1492 | reord = min(fack_count, reord); | 1482 | reord = min(fack_count, reord); |
| 1483 | |||
| 1484 | fack_count += tcp_skb_pcount(skb); | ||
| 1493 | } | 1485 | } |
| 1494 | 1486 | ||
| 1495 | /* D-SACK. We can detect redundant retransmission | 1487 | /* D-SACK. We can detect redundant retransmission |
| @@ -1504,6 +1496,12 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
| 1504 | tp->retransmit_skb_hint = NULL; | 1496 | tp->retransmit_skb_hint = NULL; |
| 1505 | } | 1497 | } |
| 1506 | } | 1498 | } |
| 1499 | |||
| 1500 | /* SACK enhanced FRTO (RFC4138, Appendix B): Clearing correct | ||
| 1501 | * due to in-order walk | ||
| 1502 | */ | ||
| 1503 | if (after(end_seq, tp->frto_highmark)) | ||
| 1504 | flag &= ~FLAG_ONLY_ORIG_SACKED; | ||
| 1507 | } | 1505 | } |
| 1508 | 1506 | ||
| 1509 | if (tp->retrans_out && | 1507 | if (tp->retrans_out && |
| @@ -1515,7 +1513,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
| 1515 | 1513 | ||
| 1516 | if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss && | 1514 | if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss && |
| 1517 | (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) | 1515 | (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) |
| 1518 | tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0); | 1516 | tcp_update_reordering(sk, tp->fackets_out - reord, 0); |
| 1519 | 1517 | ||
| 1520 | #if FASTRETRANS_DEBUG > 0 | 1518 | #if FASTRETRANS_DEBUG > 0 |
| 1521 | BUG_TRAP((int)tp->sacked_out >= 0); | 1519 | BUG_TRAP((int)tp->sacked_out >= 0); |
| @@ -2630,7 +2628,8 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) | |||
| 2630 | * is before the ack sequence we can discard it as it's confirmed to have | 2628 | * is before the ack sequence we can discard it as it's confirmed to have |
| 2631 | * arrived at the other end. | 2629 | * arrived at the other end. |
| 2632 | */ | 2630 | */ |
| 2633 | static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | 2631 | static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, |
| 2632 | int prior_fackets) | ||
| 2634 | { | 2633 | { |
| 2635 | struct tcp_sock *tp = tcp_sk(sk); | 2634 | struct tcp_sock *tp = tcp_sk(sk); |
| 2636 | const struct inet_connection_sock *icsk = inet_csk(sk); | 2635 | const struct inet_connection_sock *icsk = inet_csk(sk); |
| @@ -2639,6 +2638,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
| 2639 | int fully_acked = 1; | 2638 | int fully_acked = 1; |
| 2640 | int flag = 0; | 2639 | int flag = 0; |
| 2641 | int prior_packets = tp->packets_out; | 2640 | int prior_packets = tp->packets_out; |
| 2641 | u32 cnt = 0; | ||
| 2642 | u32 reord = tp->packets_out; | ||
| 2642 | s32 seq_rtt = -1; | 2643 | s32 seq_rtt = -1; |
| 2643 | ktime_t last_ackt = net_invalid_timestamp(); | 2644 | ktime_t last_ackt = net_invalid_timestamp(); |
| 2644 | 2645 | ||
| @@ -2679,10 +2680,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
| 2679 | if ((flag & FLAG_DATA_ACKED) || | 2680 | if ((flag & FLAG_DATA_ACKED) || |
| 2680 | (packets_acked > 1)) | 2681 | (packets_acked > 1)) |
| 2681 | flag |= FLAG_NONHEAD_RETRANS_ACKED; | 2682 | flag |= FLAG_NONHEAD_RETRANS_ACKED; |
| 2682 | } else if (seq_rtt < 0) { | 2683 | } else { |
| 2683 | seq_rtt = now - scb->when; | 2684 | if (seq_rtt < 0) { |
| 2684 | if (fully_acked) | 2685 | seq_rtt = now - scb->when; |
| 2685 | last_ackt = skb->tstamp; | 2686 | if (fully_acked) |
| 2687 | last_ackt = skb->tstamp; | ||
| 2688 | } | ||
| 2689 | if (!(sacked & TCPCB_SACKED_ACKED)) | ||
| 2690 | reord = min(cnt, reord); | ||
| 2686 | } | 2691 | } |
| 2687 | 2692 | ||
| 2688 | if (sacked & TCPCB_SACKED_ACKED) | 2693 | if (sacked & TCPCB_SACKED_ACKED) |
| @@ -2693,12 +2698,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
| 2693 | if ((sacked & TCPCB_URG) && tp->urg_mode && | 2698 | if ((sacked & TCPCB_URG) && tp->urg_mode && |
| 2694 | !before(end_seq, tp->snd_up)) | 2699 | !before(end_seq, tp->snd_up)) |
| 2695 | tp->urg_mode = 0; | 2700 | tp->urg_mode = 0; |
| 2696 | } else if (seq_rtt < 0) { | 2701 | } else { |
| 2697 | seq_rtt = now - scb->when; | 2702 | if (seq_rtt < 0) { |
| 2698 | if (fully_acked) | 2703 | seq_rtt = now - scb->when; |
| 2699 | last_ackt = skb->tstamp; | 2704 | if (fully_acked) |
| 2705 | last_ackt = skb->tstamp; | ||
| 2706 | } | ||
| 2707 | reord = min(cnt, reord); | ||
| 2700 | } | 2708 | } |
| 2701 | tp->packets_out -= packets_acked; | 2709 | tp->packets_out -= packets_acked; |
| 2710 | cnt += packets_acked; | ||
| 2702 | 2711 | ||
| 2703 | /* Initial outgoing SYN's get put onto the write_queue | 2712 | /* Initial outgoing SYN's get put onto the write_queue |
| 2704 | * just like anything else we transmit. It is not | 2713 | * just like anything else we transmit. It is not |
| @@ -2730,13 +2739,18 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
| 2730 | tcp_ack_update_rtt(sk, flag, seq_rtt); | 2739 | tcp_ack_update_rtt(sk, flag, seq_rtt); |
| 2731 | tcp_rearm_rto(sk); | 2740 | tcp_rearm_rto(sk); |
| 2732 | 2741 | ||
| 2742 | if (tcp_is_reno(tp)) { | ||
| 2743 | tcp_remove_reno_sacks(sk, pkts_acked); | ||
| 2744 | } else { | ||
| 2745 | /* Non-retransmitted hole got filled? That's reordering */ | ||
| 2746 | if (reord < prior_fackets) | ||
| 2747 | tcp_update_reordering(sk, tp->fackets_out - reord, 0); | ||
| 2748 | } | ||
| 2749 | |||
| 2733 | tp->fackets_out -= min(pkts_acked, tp->fackets_out); | 2750 | tp->fackets_out -= min(pkts_acked, tp->fackets_out); |
| 2734 | /* hint's skb might be NULL but we don't need to care */ | 2751 | /* hint's skb might be NULL but we don't need to care */ |
| 2735 | tp->fastpath_cnt_hint -= min_t(u32, pkts_acked, | 2752 | tp->fastpath_cnt_hint -= min_t(u32, pkts_acked, |
| 2736 | tp->fastpath_cnt_hint); | 2753 | tp->fastpath_cnt_hint); |
| 2737 | if (tcp_is_reno(tp)) | ||
| 2738 | tcp_remove_reno_sacks(sk, pkts_acked); | ||
| 2739 | |||
| 2740 | if (ca_ops->pkts_acked) { | 2754 | if (ca_ops->pkts_acked) { |
| 2741 | s32 rtt_us = -1; | 2755 | s32 rtt_us = -1; |
| 2742 | 2756 | ||
| @@ -3019,6 +3033,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
| 3019 | u32 ack_seq = TCP_SKB_CB(skb)->seq; | 3033 | u32 ack_seq = TCP_SKB_CB(skb)->seq; |
| 3020 | u32 ack = TCP_SKB_CB(skb)->ack_seq; | 3034 | u32 ack = TCP_SKB_CB(skb)->ack_seq; |
| 3021 | u32 prior_in_flight; | 3035 | u32 prior_in_flight; |
| 3036 | u32 prior_fackets; | ||
| 3022 | s32 seq_rtt; | 3037 | s32 seq_rtt; |
| 3023 | int prior_packets; | 3038 | int prior_packets; |
| 3024 | int frto_cwnd = 0; | 3039 | int frto_cwnd = 0; |
| @@ -3043,6 +3058,8 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
| 3043 | tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache); | 3058 | tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache); |
| 3044 | } | 3059 | } |
| 3045 | 3060 | ||
| 3061 | prior_fackets = tp->fackets_out; | ||
| 3062 | |||
| 3046 | if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { | 3063 | if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { |
| 3047 | /* Window is constant, pure forward advance. | 3064 | /* Window is constant, pure forward advance. |
| 3048 | * No more checks are required. | 3065 | * No more checks are required. |
| @@ -3084,7 +3101,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
| 3084 | prior_in_flight = tcp_packets_in_flight(tp); | 3101 | prior_in_flight = tcp_packets_in_flight(tp); |
| 3085 | 3102 | ||
| 3086 | /* See if we can take anything off of the retransmit queue. */ | 3103 | /* See if we can take anything off of the retransmit queue. */ |
| 3087 | flag |= tcp_clean_rtx_queue(sk, &seq_rtt); | 3104 | flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets); |
| 3088 | 3105 | ||
| 3089 | /* Guarantee sacktag reordering detection against wrap-arounds */ | 3106 | /* Guarantee sacktag reordering detection against wrap-arounds */ |
| 3090 | if (before(tp->frto_highmark, tp->snd_una)) | 3107 | if (before(tp->frto_highmark, tp->snd_una)) |
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index a794a8ca8b4f..978b3fd61e65 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c | |||
| @@ -17,6 +17,11 @@ static struct xfrm_tunnel *tunnel4_handlers; | |||
| 17 | static struct xfrm_tunnel *tunnel64_handlers; | 17 | static struct xfrm_tunnel *tunnel64_handlers; |
| 18 | static DEFINE_MUTEX(tunnel4_mutex); | 18 | static DEFINE_MUTEX(tunnel4_mutex); |
| 19 | 19 | ||
| 20 | static inline struct xfrm_tunnel **fam_handlers(unsigned short family) | ||
| 21 | { | ||
| 22 | return (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; | ||
| 23 | } | ||
| 24 | |||
| 20 | int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) | 25 | int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) |
| 21 | { | 26 | { |
| 22 | struct xfrm_tunnel **pprev; | 27 | struct xfrm_tunnel **pprev; |
| @@ -25,8 +30,7 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) | |||
| 25 | 30 | ||
| 26 | mutex_lock(&tunnel4_mutex); | 31 | mutex_lock(&tunnel4_mutex); |
| 27 | 32 | ||
| 28 | for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; | 33 | for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) { |
| 29 | *pprev; pprev = &(*pprev)->next) { | ||
| 30 | if ((*pprev)->priority > priority) | 34 | if ((*pprev)->priority > priority) |
| 31 | break; | 35 | break; |
| 32 | if ((*pprev)->priority == priority) | 36 | if ((*pprev)->priority == priority) |
| @@ -53,8 +57,7 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family) | |||
| 53 | 57 | ||
| 54 | mutex_lock(&tunnel4_mutex); | 58 | mutex_lock(&tunnel4_mutex); |
| 55 | 59 | ||
| 56 | for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; | 60 | for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) { |
| 57 | *pprev; pprev = &(*pprev)->next) { | ||
| 58 | if (*pprev == handler) { | 61 | if (*pprev == handler) { |
| 59 | *pprev = handler->next; | 62 | *pprev = handler->next; |
| 60 | ret = 0; | 63 | ret = 0; |
| @@ -118,6 +121,17 @@ static void tunnel4_err(struct sk_buff *skb, u32 info) | |||
| 118 | break; | 121 | break; |
| 119 | } | 122 | } |
| 120 | 123 | ||
| 124 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 125 | static void tunnel64_err(struct sk_buff *skb, u32 info) | ||
| 126 | { | ||
| 127 | struct xfrm_tunnel *handler; | ||
| 128 | |||
| 129 | for (handler = tunnel64_handlers; handler; handler = handler->next) | ||
| 130 | if (!handler->err_handler(skb, info)) | ||
| 131 | break; | ||
| 132 | } | ||
| 133 | #endif | ||
| 134 | |||
| 121 | static struct net_protocol tunnel4_protocol = { | 135 | static struct net_protocol tunnel4_protocol = { |
| 122 | .handler = tunnel4_rcv, | 136 | .handler = tunnel4_rcv, |
| 123 | .err_handler = tunnel4_err, | 137 | .err_handler = tunnel4_err, |
| @@ -127,7 +141,7 @@ static struct net_protocol tunnel4_protocol = { | |||
| 127 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 141 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 128 | static struct net_protocol tunnel64_protocol = { | 142 | static struct net_protocol tunnel64_protocol = { |
| 129 | .handler = tunnel64_rcv, | 143 | .handler = tunnel64_rcv, |
| 130 | .err_handler = tunnel4_err, | 144 | .err_handler = tunnel64_err, |
| 131 | .no_policy = 1, | 145 | .no_policy = 1, |
| 132 | }; | 146 | }; |
| 133 | #endif | 147 | #endif |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 706622af206f..428c6b0e26d8 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
| @@ -31,25 +31,6 @@ struct fib6_rule | |||
| 31 | 31 | ||
| 32 | static struct fib_rules_ops fib6_rules_ops; | 32 | static struct fib_rules_ops fib6_rules_ops; |
| 33 | 33 | ||
| 34 | static struct fib6_rule main_rule = { | ||
| 35 | .common = { | ||
| 36 | .refcnt = ATOMIC_INIT(2), | ||
| 37 | .pref = 0x7FFE, | ||
| 38 | .action = FR_ACT_TO_TBL, | ||
| 39 | .table = RT6_TABLE_MAIN, | ||
| 40 | }, | ||
| 41 | }; | ||
| 42 | |||
| 43 | static struct fib6_rule local_rule = { | ||
| 44 | .common = { | ||
| 45 | .refcnt = ATOMIC_INIT(2), | ||
| 46 | .pref = 0, | ||
| 47 | .action = FR_ACT_TO_TBL, | ||
| 48 | .table = RT6_TABLE_LOCAL, | ||
| 49 | .flags = FIB_RULE_PERMANENT, | ||
| 50 | }, | ||
| 51 | }; | ||
| 52 | |||
| 53 | struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, | 34 | struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, |
| 54 | pol_lookup_t lookup) | 35 | pol_lookup_t lookup) |
| 55 | { | 36 | { |
| @@ -270,11 +251,23 @@ static struct fib_rules_ops fib6_rules_ops = { | |||
| 270 | .owner = THIS_MODULE, | 251 | .owner = THIS_MODULE, |
| 271 | }; | 252 | }; |
| 272 | 253 | ||
| 273 | void __init fib6_rules_init(void) | 254 | static int __init fib6_default_rules_init(void) |
| 274 | { | 255 | { |
| 275 | list_add_tail(&local_rule.common.list, &fib6_rules_ops.rules_list); | 256 | int err; |
| 276 | list_add_tail(&main_rule.common.list, &fib6_rules_ops.rules_list); | 257 | |
| 258 | err = fib_default_rule_add(&fib6_rules_ops, 0, | ||
| 259 | RT6_TABLE_LOCAL, FIB_RULE_PERMANENT); | ||
| 260 | if (err < 0) | ||
| 261 | return err; | ||
| 262 | err = fib_default_rule_add(&fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0); | ||
| 263 | if (err < 0) | ||
| 264 | return err; | ||
| 265 | return 0; | ||
| 266 | } | ||
| 277 | 267 | ||
| 268 | void __init fib6_rules_init(void) | ||
| 269 | { | ||
| 270 | BUG_ON(fib6_default_rules_init()); | ||
| 278 | fib_rules_register(&fib6_rules_ops); | 271 | fib_rules_register(&fib6_rules_ops); |
| 279 | } | 272 | } |
| 280 | 273 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 973a97abc446..6ecb5e6fae2e 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -544,12 +544,8 @@ restart: | |||
| 544 | rt = rt6_device_match(rt, fl->oif, flags); | 544 | rt = rt6_device_match(rt, fl->oif, flags); |
| 545 | BACKTRACK(&fl->fl6_src); | 545 | BACKTRACK(&fl->fl6_src); |
| 546 | out: | 546 | out: |
| 547 | dst_hold(&rt->u.dst); | 547 | dst_use(&rt->u.dst, jiffies); |
| 548 | read_unlock_bh(&table->tb6_lock); | 548 | read_unlock_bh(&table->tb6_lock); |
| 549 | |||
| 550 | rt->u.dst.lastuse = jiffies; | ||
| 551 | rt->u.dst.__use++; | ||
| 552 | |||
| 553 | return rt; | 549 | return rt; |
| 554 | 550 | ||
| 555 | } | 551 | } |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index a195a66e0cc7..c76a9523091b 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
| @@ -92,11 +92,6 @@ extern int ipxrtr_route_skb(struct sk_buff *skb); | |||
| 92 | extern struct ipx_route *ipxrtr_lookup(__be32 net); | 92 | extern struct ipx_route *ipxrtr_lookup(__be32 net); |
| 93 | extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg); | 93 | extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg); |
| 94 | 94 | ||
| 95 | #undef IPX_REFCNT_DEBUG | ||
| 96 | #ifdef IPX_REFCNT_DEBUG | ||
| 97 | atomic_t ipx_sock_nr; | ||
| 98 | #endif | ||
| 99 | |||
| 100 | struct ipx_interface *ipx_interfaces_head(void) | 95 | struct ipx_interface *ipx_interfaces_head(void) |
| 101 | { | 96 | { |
| 102 | struct ipx_interface *rc = NULL; | 97 | struct ipx_interface *rc = NULL; |
| @@ -151,14 +146,7 @@ static void ipx_destroy_socket(struct sock *sk) | |||
| 151 | { | 146 | { |
| 152 | ipx_remove_socket(sk); | 147 | ipx_remove_socket(sk); |
| 153 | skb_queue_purge(&sk->sk_receive_queue); | 148 | skb_queue_purge(&sk->sk_receive_queue); |
| 154 | #ifdef IPX_REFCNT_DEBUG | 149 | sk_refcnt_debug_dec(sk); |
| 155 | atomic_dec(&ipx_sock_nr); | ||
| 156 | printk(KERN_DEBUG "IPX socket %p released, %d are still alive\n", sk, | ||
| 157 | atomic_read(&ipx_sock_nr)); | ||
| 158 | if (atomic_read(&sk->sk_refcnt) != 1) | ||
| 159 | printk(KERN_DEBUG "Destruction sock ipx %p delayed, cnt=%d\n", | ||
| 160 | sk, atomic_read(&sk->sk_refcnt)); | ||
| 161 | #endif | ||
| 162 | sock_put(sk); | 150 | sock_put(sk); |
| 163 | } | 151 | } |
| 164 | 152 | ||
| @@ -1384,11 +1372,8 @@ static int ipx_create(struct net *net, struct socket *sock, int protocol) | |||
| 1384 | sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto); | 1372 | sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto); |
| 1385 | if (!sk) | 1373 | if (!sk) |
| 1386 | goto out; | 1374 | goto out; |
| 1387 | #ifdef IPX_REFCNT_DEBUG | 1375 | |
| 1388 | atomic_inc(&ipx_sock_nr); | 1376 | sk_refcnt_debug_inc(sk); |
| 1389 | printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk, | ||
| 1390 | atomic_read(&ipx_sock_nr)); | ||
| 1391 | #endif | ||
| 1392 | sock_init_data(sock, sk); | 1377 | sock_init_data(sock, sk); |
| 1393 | sk->sk_no_check = 1; /* Checksum off by default */ | 1378 | sk->sk_no_check = 1; /* Checksum off by default */ |
| 1394 | sock->ops = &ipx_dgram_ops; | 1379 | sock->ops = &ipx_dgram_ops; |
| @@ -1409,6 +1394,7 @@ static int ipx_release(struct socket *sock) | |||
| 1409 | 1394 | ||
| 1410 | sock_set_flag(sk, SOCK_DEAD); | 1395 | sock_set_flag(sk, SOCK_DEAD); |
| 1411 | sock->sk = NULL; | 1396 | sock->sk = NULL; |
| 1397 | sk_refcnt_debug_release(sk); | ||
| 1412 | ipx_destroy_socket(sk); | 1398 | ipx_destroy_socket(sk); |
| 1413 | out: | 1399 | out: |
| 1414 | return 0; | 1400 | return 0; |
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 6fffb3845ab6..ce176e691afe 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
| @@ -13,6 +13,18 @@ config MAC80211 | |||
| 13 | This option enables the hardware independent IEEE 802.11 | 13 | This option enables the hardware independent IEEE 802.11 |
| 14 | networking stack. | 14 | networking stack. |
| 15 | 15 | ||
| 16 | config MAC80211_RCSIMPLE | ||
| 17 | bool "'simple' rate control algorithm" if EMBEDDED | ||
| 18 | default y | ||
| 19 | depends on MAC80211 | ||
| 20 | help | ||
| 21 | This option allows you to turn off the 'simple' rate | ||
| 22 | control algorithm in mac80211. If you do turn it off, | ||
| 23 | you absolutely need another rate control algorithm. | ||
| 24 | |||
| 25 | Say Y unless you know you will have another algorithm | ||
| 26 | available. | ||
| 27 | |||
| 16 | config MAC80211_LEDS | 28 | config MAC80211_LEDS |
| 17 | bool "Enable LED triggers" | 29 | bool "Enable LED triggers" |
| 18 | depends on MAC80211 && LEDS_TRIGGERS | 30 | depends on MAC80211 && LEDS_TRIGGERS |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 219cd9f9341f..1e6237b34846 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o | 1 | obj-$(CONFIG_MAC80211) += mac80211.o |
| 2 | 2 | ||
| 3 | mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o | 3 | mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o |
| 4 | mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o | 4 | mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o |
| 5 | mac80211-objs-$(CONFIG_NET_SCHED) += wme.o | 5 | mac80211-objs-$(CONFIG_NET_SCHED) += wme.o |
| 6 | mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o | ||
| 6 | 7 | ||
| 7 | mac80211-objs := \ | 8 | mac80211-objs := \ |
| 8 | ieee80211.o \ | 9 | ieee80211.o \ |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index f484ca7ade9c..e0ee65a969bc 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
| @@ -1072,7 +1072,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1072 | ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); | 1072 | ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); |
| 1073 | ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); | 1073 | ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); |
| 1074 | 1074 | ||
| 1075 | result = ieee80211_init_rate_ctrl_alg(local, NULL); | 1075 | result = ieee80211_init_rate_ctrl_alg(local, |
| 1076 | hw->rate_control_algorithm); | ||
| 1076 | if (result < 0) { | 1077 | if (result < 0) { |
| 1077 | printk(KERN_DEBUG "%s: Failed to initialize rate control " | 1078 | printk(KERN_DEBUG "%s: Failed to initialize rate control " |
| 1078 | "algorithm\n", wiphy_name(local->hw.wiphy)); | 1079 | "algorithm\n", wiphy_name(local->hw.wiphy)); |
| @@ -1233,8 +1234,17 @@ static int __init ieee80211_init(void) | |||
| 1233 | 1234 | ||
| 1234 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1235 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); |
| 1235 | 1236 | ||
| 1237 | #ifdef CONFIG_MAC80211_RCSIMPLE | ||
| 1238 | ret = ieee80211_rate_control_register(&mac80211_rcsimple); | ||
| 1239 | if (ret) | ||
| 1240 | return ret; | ||
| 1241 | #endif | ||
| 1242 | |||
| 1236 | ret = ieee80211_wme_register(); | 1243 | ret = ieee80211_wme_register(); |
| 1237 | if (ret) { | 1244 | if (ret) { |
| 1245 | #ifdef CONFIG_MAC80211_RCSIMPLE | ||
| 1246 | ieee80211_rate_control_unregister(&mac80211_rcsimple); | ||
| 1247 | #endif | ||
| 1238 | printk(KERN_DEBUG "ieee80211_init: failed to " | 1248 | printk(KERN_DEBUG "ieee80211_init: failed to " |
| 1239 | "initialize WME (err=%d)\n", ret); | 1249 | "initialize WME (err=%d)\n", ret); |
| 1240 | return ret; | 1250 | return ret; |
| @@ -1248,6 +1258,10 @@ static int __init ieee80211_init(void) | |||
| 1248 | 1258 | ||
| 1249 | static void __exit ieee80211_exit(void) | 1259 | static void __exit ieee80211_exit(void) |
| 1250 | { | 1260 | { |
| 1261 | #ifdef CONFIG_MAC80211_RCSIMPLE | ||
| 1262 | ieee80211_rate_control_unregister(&mac80211_rcsimple); | ||
| 1263 | #endif | ||
| 1264 | |||
| 1251 | ieee80211_wme_unregister(); | 1265 | ieee80211_wme_unregister(); |
| 1252 | ieee80211_debugfs_netdev_exit(); | 1266 | ieee80211_debugfs_netdev_exit(); |
| 1253 | } | 1267 | } |
diff --git a/net/mac80211/ieee80211_common.h b/net/mac80211/ieee80211_common.h deleted file mode 100644 index c15295d43d87..000000000000 --- a/net/mac80211/ieee80211_common.h +++ /dev/null | |||
| @@ -1,91 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * IEEE 802.11 driver (80211.o) -- hostapd interface | ||
| 3 | * Copyright 2002-2004, Instant802 Networks, Inc. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef IEEE80211_COMMON_H | ||
| 11 | #define IEEE80211_COMMON_H | ||
| 12 | |||
| 13 | #include <linux/types.h> | ||
| 14 | |||
| 15 | /* | ||
| 16 | * This is common header information with user space. It is used on all | ||
| 17 | * frames sent to wlan#ap interface. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #define IEEE80211_FI_VERSION 0x80211001 | ||
| 21 | |||
| 22 | struct ieee80211_frame_info { | ||
| 23 | __be32 version; | ||
| 24 | __be32 length; | ||
| 25 | __be64 mactime; | ||
| 26 | __be64 hosttime; | ||
| 27 | __be32 phytype; | ||
| 28 | __be32 channel; | ||
| 29 | __be32 datarate; | ||
| 30 | __be32 antenna; | ||
| 31 | __be32 priority; | ||
| 32 | __be32 ssi_type; | ||
| 33 | __be32 ssi_signal; | ||
| 34 | __be32 ssi_noise; | ||
| 35 | __be32 preamble; | ||
| 36 | __be32 encoding; | ||
| 37 | |||
| 38 | /* Note: this structure is otherwise identical to capture format used | ||
| 39 | * in linux-wlan-ng, but this additional field is used to provide meta | ||
| 40 | * data about the frame to hostapd. This was the easiest method for | ||
| 41 | * providing this information, but this might change in the future. */ | ||
| 42 | __be32 msg_type; | ||
| 43 | } __attribute__ ((packed)); | ||
| 44 | |||
| 45 | |||
| 46 | enum ieee80211_msg_type { | ||
| 47 | ieee80211_msg_normal = 0, | ||
| 48 | ieee80211_msg_tx_callback_ack = 1, | ||
| 49 | ieee80211_msg_tx_callback_fail = 2, | ||
| 50 | /* hole at 3, was ieee80211_msg_passive_scan but unused */ | ||
| 51 | /* hole at 4, was ieee80211_msg_wep_frame_unknown_key but now unused */ | ||
| 52 | ieee80211_msg_michael_mic_failure = 5, | ||
| 53 | /* hole at 6, was monitor but never sent to userspace */ | ||
| 54 | ieee80211_msg_sta_not_assoc = 7, | ||
| 55 | /* 8 was ieee80211_msg_set_aid_for_sta */ | ||
| 56 | /* 9 was ieee80211_msg_key_threshold_notification */ | ||
| 57 | /* 11 was ieee80211_msg_radar */ | ||
| 58 | }; | ||
| 59 | |||
| 60 | struct ieee80211_msg_key_notification { | ||
| 61 | int tx_rx_count; | ||
| 62 | char ifname[IFNAMSIZ]; | ||
| 63 | u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */ | ||
| 64 | }; | ||
| 65 | |||
| 66 | |||
| 67 | enum ieee80211_phytype { | ||
| 68 | ieee80211_phytype_fhss_dot11_97 = 1, | ||
| 69 | ieee80211_phytype_dsss_dot11_97 = 2, | ||
| 70 | ieee80211_phytype_irbaseband = 3, | ||
| 71 | ieee80211_phytype_dsss_dot11_b = 4, | ||
| 72 | ieee80211_phytype_pbcc_dot11_b = 5, | ||
| 73 | ieee80211_phytype_ofdm_dot11_g = 6, | ||
| 74 | ieee80211_phytype_pbcc_dot11_g = 7, | ||
| 75 | ieee80211_phytype_ofdm_dot11_a = 8, | ||
| 76 | }; | ||
| 77 | |||
| 78 | enum ieee80211_ssi_type { | ||
| 79 | ieee80211_ssi_none = 0, | ||
| 80 | ieee80211_ssi_norm = 1, /* normalized, 0-1000 */ | ||
| 81 | ieee80211_ssi_dbm = 2, | ||
| 82 | ieee80211_ssi_raw = 3, /* raw SSI */ | ||
| 83 | }; | ||
| 84 | |||
| 85 | struct ieee80211_radar_info { | ||
| 86 | int channel; | ||
| 87 | int radar; | ||
| 88 | int radar_type; | ||
| 89 | }; | ||
| 90 | |||
| 91 | #endif /* IEEE80211_COMMON_H */ | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4b4ed2a5803c..b4e32ab3664d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -230,6 +230,7 @@ struct ieee80211_if_vlan { | |||
| 230 | #define IEEE80211_STA_AUTO_SSID_SEL BIT(10) | 230 | #define IEEE80211_STA_AUTO_SSID_SEL BIT(10) |
| 231 | #define IEEE80211_STA_AUTO_BSSID_SEL BIT(11) | 231 | #define IEEE80211_STA_AUTO_BSSID_SEL BIT(11) |
| 232 | #define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) | 232 | #define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) |
| 233 | #define IEEE80211_STA_PRIVACY_INVOKED BIT(13) | ||
| 233 | struct ieee80211_if_sta { | 234 | struct ieee80211_if_sta { |
| 234 | enum { | 235 | enum { |
| 235 | IEEE80211_DISABLED, IEEE80211_AUTHENTICATE, | 236 | IEEE80211_DISABLED, IEEE80211_AUTHENTICATE, |
| @@ -259,7 +260,6 @@ struct ieee80211_if_sta { | |||
| 259 | unsigned long request; | 260 | unsigned long request; |
| 260 | struct sk_buff_head skb_queue; | 261 | struct sk_buff_head skb_queue; |
| 261 | 262 | ||
| 262 | int key_management_enabled; | ||
| 263 | unsigned long last_probe; | 263 | unsigned long last_probe; |
| 264 | 264 | ||
| 265 | #define IEEE80211_AUTH_ALG_OPEN BIT(0) | 265 | #define IEEE80211_AUTH_ALG_OPEN BIT(0) |
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 6caa3ec2cff7..7027eed4d4ae 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c | |||
| @@ -917,7 +917,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev, | |||
| 917 | struct iw_request_info *info, | 917 | struct iw_request_info *info, |
| 918 | struct iw_param *data, char *extra) | 918 | struct iw_param *data, char *extra) |
| 919 | { | 919 | { |
| 920 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 921 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 920 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 922 | int ret = 0; | 921 | int ret = 0; |
| 923 | 922 | ||
| @@ -927,18 +926,21 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev, | |||
| 927 | case IW_AUTH_CIPHER_GROUP: | 926 | case IW_AUTH_CIPHER_GROUP: |
| 928 | case IW_AUTH_WPA_ENABLED: | 927 | case IW_AUTH_WPA_ENABLED: |
| 929 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: | 928 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: |
| 930 | break; | ||
| 931 | case IW_AUTH_KEY_MGMT: | 929 | case IW_AUTH_KEY_MGMT: |
| 930 | break; | ||
| 931 | case IW_AUTH_PRIVACY_INVOKED: | ||
| 932 | if (sdata->type != IEEE80211_IF_TYPE_STA) | 932 | if (sdata->type != IEEE80211_IF_TYPE_STA) |
| 933 | ret = -EINVAL; | 933 | ret = -EINVAL; |
| 934 | else { | 934 | else { |
| 935 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | ||
| 935 | /* | 936 | /* |
| 936 | * Key management was set by wpa_supplicant, | 937 | * Privacy invoked by wpa_supplicant, store the |
| 937 | * we only need this to associate to a network | 938 | * value and allow associating to a protected |
| 938 | * that has privacy enabled regardless of not | 939 | * network without having a key up front. |
| 939 | * having a key. | ||
| 940 | */ | 940 | */ |
| 941 | sdata->u.sta.key_management_enabled = !!data->value; | 941 | if (data->value) |
| 942 | sdata->u.sta.flags |= | ||
| 943 | IEEE80211_STA_PRIVACY_INVOKED; | ||
| 942 | } | 944 | } |
| 943 | break; | 945 | break; |
| 944 | case IW_AUTH_80211_AUTH_ALG: | 946 | case IW_AUTH_80211_AUTH_ALG: |
| @@ -948,11 +950,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev, | |||
| 948 | else | 950 | else |
| 949 | ret = -EOPNOTSUPP; | 951 | ret = -EOPNOTSUPP; |
| 950 | break; | 952 | break; |
| 951 | case IW_AUTH_PRIVACY_INVOKED: | ||
| 952 | if (local->ops->set_privacy_invoked) | ||
| 953 | ret = local->ops->set_privacy_invoked( | ||
| 954 | local_to_hw(local), data->value); | ||
| 955 | break; | ||
| 956 | default: | 953 | default: |
| 957 | ret = -EOPNOTSUPP; | 954 | ret = -EOPNOTSUPP; |
| 958 | break; | 955 | break; |
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c index 93abb8fff141..7254bd609839 100644 --- a/net/mac80211/ieee80211_rate.c +++ b/net/mac80211/ieee80211_rate.c | |||
| @@ -25,13 +25,25 @@ int ieee80211_rate_control_register(struct rate_control_ops *ops) | |||
| 25 | { | 25 | { |
| 26 | struct rate_control_alg *alg; | 26 | struct rate_control_alg *alg; |
| 27 | 27 | ||
| 28 | if (!ops->name) | ||
| 29 | return -EINVAL; | ||
| 30 | |||
| 31 | mutex_lock(&rate_ctrl_mutex); | ||
| 32 | list_for_each_entry(alg, &rate_ctrl_algs, list) { | ||
| 33 | if (!strcmp(alg->ops->name, ops->name)) { | ||
| 34 | /* don't register an algorithm twice */ | ||
| 35 | WARN_ON(1); | ||
| 36 | return -EALREADY; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 28 | alg = kzalloc(sizeof(*alg), GFP_KERNEL); | 40 | alg = kzalloc(sizeof(*alg), GFP_KERNEL); |
| 29 | if (alg == NULL) { | 41 | if (alg == NULL) { |
| 42 | mutex_unlock(&rate_ctrl_mutex); | ||
| 30 | return -ENOMEM; | 43 | return -ENOMEM; |
| 31 | } | 44 | } |
| 32 | alg->ops = ops; | 45 | alg->ops = ops; |
| 33 | 46 | ||
| 34 | mutex_lock(&rate_ctrl_mutex); | ||
| 35 | list_add_tail(&alg->list, &rate_ctrl_algs); | 47 | list_add_tail(&alg->list, &rate_ctrl_algs); |
| 36 | mutex_unlock(&rate_ctrl_mutex); | 48 | mutex_unlock(&rate_ctrl_mutex); |
| 37 | 49 | ||
| @@ -61,9 +73,12 @@ ieee80211_try_rate_control_ops_get(const char *name) | |||
| 61 | struct rate_control_alg *alg; | 73 | struct rate_control_alg *alg; |
| 62 | struct rate_control_ops *ops = NULL; | 74 | struct rate_control_ops *ops = NULL; |
| 63 | 75 | ||
| 76 | if (!name) | ||
| 77 | return NULL; | ||
| 78 | |||
| 64 | mutex_lock(&rate_ctrl_mutex); | 79 | mutex_lock(&rate_ctrl_mutex); |
| 65 | list_for_each_entry(alg, &rate_ctrl_algs, list) { | 80 | list_for_each_entry(alg, &rate_ctrl_algs, list) { |
| 66 | if (!name || !strcmp(alg->ops->name, name)) | 81 | if (!strcmp(alg->ops->name, name)) |
| 67 | if (try_module_get(alg->ops->module)) { | 82 | if (try_module_get(alg->ops->module)) { |
| 68 | ops = alg->ops; | 83 | ops = alg->ops; |
| 69 | break; | 84 | break; |
| @@ -80,9 +95,12 @@ ieee80211_rate_control_ops_get(const char *name) | |||
| 80 | { | 95 | { |
| 81 | struct rate_control_ops *ops; | 96 | struct rate_control_ops *ops; |
| 82 | 97 | ||
| 98 | if (!name) | ||
| 99 | name = "simple"; | ||
| 100 | |||
| 83 | ops = ieee80211_try_rate_control_ops_get(name); | 101 | ops = ieee80211_try_rate_control_ops_get(name); |
| 84 | if (!ops) { | 102 | if (!ops) { |
| 85 | request_module("rc80211_%s", name ? name : "default"); | 103 | request_module("rc80211_%s", name); |
| 86 | ops = ieee80211_try_rate_control_ops_get(name); | 104 | ops = ieee80211_try_rate_control_ops_get(name); |
| 87 | } | 105 | } |
| 88 | return ops; | 106 | return ops; |
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h index 7cd1ebab4f83..23688139ffb3 100644 --- a/net/mac80211/ieee80211_rate.h +++ b/net/mac80211/ieee80211_rate.h | |||
| @@ -65,6 +65,9 @@ struct rate_control_ref { | |||
| 65 | struct kref kref; | 65 | struct kref kref; |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | /* default 'simple' algorithm */ | ||
| 69 | extern struct rate_control_ops mac80211_rcsimple; | ||
| 70 | |||
| 68 | int ieee80211_rate_control_register(struct rate_control_ops *ops); | 71 | int ieee80211_rate_control_register(struct rate_control_ops *ops); |
| 69 | void ieee80211_rate_control_unregister(struct rate_control_ops *ops); | 72 | void ieee80211_rate_control_unregister(struct rate_control_ops *ops); |
| 70 | 73 | ||
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index fda0e06453e8..2079e988fc56 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
| @@ -704,10 +704,11 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
| 704 | { | 704 | { |
| 705 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 705 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 706 | struct ieee80211_sta_bss *bss; | 706 | struct ieee80211_sta_bss *bss; |
| 707 | int res = 0; | 707 | int bss_privacy; |
| 708 | int wep_privacy; | ||
| 709 | int privacy_invoked; | ||
| 708 | 710 | ||
| 709 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) || | 711 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) |
| 710 | ifsta->key_management_enabled) | ||
| 711 | return 0; | 712 | return 0; |
| 712 | 713 | ||
| 713 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, | 714 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, |
| @@ -715,13 +716,16 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
| 715 | if (!bss) | 716 | if (!bss) |
| 716 | return 0; | 717 | return 0; |
| 717 | 718 | ||
| 718 | if (ieee80211_sta_wep_configured(dev) != | 719 | bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); |
| 719 | !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) | 720 | wep_privacy = !!ieee80211_sta_wep_configured(dev); |
| 720 | res = 1; | 721 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); |
| 721 | 722 | ||
| 722 | ieee80211_rx_bss_put(dev, bss); | 723 | ieee80211_rx_bss_put(dev, bss); |
| 723 | 724 | ||
| 724 | return res; | 725 | if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) |
| 726 | return 0; | ||
| 727 | |||
| 728 | return 1; | ||
| 725 | } | 729 | } |
| 726 | 730 | ||
| 727 | 731 | ||
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c index 314b8de88862..da72737364e4 100644 --- a/net/mac80211/rc80211_simple.c +++ b/net/mac80211/rc80211_simple.c | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/init.h> | 10 | #include <linux/init.h> |
| 12 | #include <linux/netdevice.h> | 11 | #include <linux/netdevice.h> |
| 13 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| @@ -29,8 +28,6 @@ | |||
| 29 | #define RATE_CONTROL_INTERVAL (HZ / 20) | 28 | #define RATE_CONTROL_INTERVAL (HZ / 20) |
| 30 | #define RATE_CONTROL_MIN_TX 10 | 29 | #define RATE_CONTROL_MIN_TX 10 |
| 31 | 30 | ||
| 32 | MODULE_ALIAS("rc80211_default"); | ||
| 33 | |||
| 34 | static void rate_control_rate_inc(struct ieee80211_local *local, | 31 | static void rate_control_rate_inc(struct ieee80211_local *local, |
| 35 | struct sta_info *sta) | 32 | struct sta_info *sta) |
| 36 | { | 33 | { |
| @@ -394,8 +391,7 @@ static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta) | |||
| 394 | } | 391 | } |
| 395 | #endif | 392 | #endif |
| 396 | 393 | ||
| 397 | static struct rate_control_ops rate_control_simple = { | 394 | struct rate_control_ops mac80211_rcsimple = { |
| 398 | .module = THIS_MODULE, | ||
| 399 | .name = "simple", | 395 | .name = "simple", |
| 400 | .tx_status = rate_control_simple_tx_status, | 396 | .tx_status = rate_control_simple_tx_status, |
| 401 | .get_rate = rate_control_simple_get_rate, | 397 | .get_rate = rate_control_simple_get_rate, |
| @@ -410,22 +406,3 @@ static struct rate_control_ops rate_control_simple = { | |||
| 410 | .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs, | 406 | .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs, |
| 411 | #endif | 407 | #endif |
| 412 | }; | 408 | }; |
| 413 | |||
| 414 | |||
| 415 | static int __init rate_control_simple_init(void) | ||
| 416 | { | ||
| 417 | return ieee80211_rate_control_register(&rate_control_simple); | ||
| 418 | } | ||
| 419 | |||
| 420 | |||
| 421 | static void __exit rate_control_simple_exit(void) | ||
| 422 | { | ||
| 423 | ieee80211_rate_control_unregister(&rate_control_simple); | ||
| 424 | } | ||
| 425 | |||
| 426 | |||
| 427 | subsys_initcall(rate_control_simple_init); | ||
| 428 | module_exit(rate_control_simple_exit); | ||
| 429 | |||
| 430 | MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211"); | ||
| 431 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index ece77766ea2b..428a9fcf57d6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -509,9 +509,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx) | |||
| 509 | rx->key->tx_rx_count++; | 509 | rx->key->tx_rx_count++; |
| 510 | /* TODO: add threshold stuff again */ | 510 | /* TODO: add threshold stuff again */ |
| 511 | } else { | 511 | } else { |
| 512 | #ifdef CONFIG_MAC80211_DEBUG | ||
| 512 | if (net_ratelimit()) | 513 | if (net_ratelimit()) |
| 513 | printk(KERN_DEBUG "%s: RX protected frame," | 514 | printk(KERN_DEBUG "%s: RX protected frame," |
| 514 | " but have no key\n", rx->dev->name); | 515 | " but have no key\n", rx->dev->name); |
| 516 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 515 | return TXRX_DROP; | 517 | return TXRX_DROP; |
| 516 | } | 518 | } |
| 517 | 519 | ||
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index a84a23310ff4..9bf0e1cc530a 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
| @@ -314,9 +314,11 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx) | |||
| 314 | 314 | ||
| 315 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { | 315 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { |
| 316 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { | 316 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { |
| 317 | #ifdef CONFIG_MAC80211_DEBUG | ||
| 317 | if (net_ratelimit()) | 318 | if (net_ratelimit()) |
| 318 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " | 319 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " |
| 319 | "failed\n", rx->dev->name); | 320 | "failed\n", rx->dev->name); |
| 321 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 320 | return TXRX_DROP; | 322 | return TXRX_DROP; |
| 321 | } | 323 | } |
| 322 | } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { | 324 | } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 6695efba57ec..20cec1cb956f 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
| @@ -323,9 +323,12 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) | |||
| 323 | &rx->u.rx.tkip_iv32, | 323 | &rx->u.rx.tkip_iv32, |
| 324 | &rx->u.rx.tkip_iv16); | 324 | &rx->u.rx.tkip_iv16); |
| 325 | if (res != TKIP_DECRYPT_OK || wpa_test) { | 325 | if (res != TKIP_DECRYPT_OK || wpa_test) { |
| 326 | printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from " | 326 | #ifdef CONFIG_MAC80211_DEBUG |
| 327 | "%s (res=%d)\n", | 327 | if (net_ratelimit()) |
| 328 | rx->dev->name, print_mac(mac, rx->sta->addr), res); | 328 | printk(KERN_DEBUG "%s: TKIP decrypt failed for RX " |
| 329 | "frame from %s (res=%d)\n", rx->dev->name, | ||
| 330 | print_mac(mac, rx->sta->addr), res); | ||
| 331 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 329 | return TXRX_DROP; | 332 | return TXRX_DROP; |
| 330 | } | 333 | } |
| 331 | 334 | ||
| @@ -594,9 +597,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) | |||
| 594 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 597 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, |
| 595 | skb->data + skb->len - CCMP_MIC_LEN, | 598 | skb->data + skb->len - CCMP_MIC_LEN, |
| 596 | skb->data + hdrlen + CCMP_HDR_LEN)) { | 599 | skb->data + hdrlen + CCMP_HDR_LEN)) { |
| 597 | printk(KERN_DEBUG "%s: CCMP decrypt failed for RX " | 600 | #ifdef CONFIG_MAC80211_DEBUG |
| 598 | "frame from %s\n", rx->dev->name, | 601 | if (net_ratelimit()) |
| 599 | print_mac(mac, rx->sta->addr)); | 602 | printk(KERN_DEBUG "%s: CCMP decrypt failed " |
| 603 | "for RX frame from %s\n", rx->dev->name, | ||
| 604 | print_mac(mac, rx->sta->addr)); | ||
| 605 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 600 | return TXRX_DROP; | 606 | return TXRX_DROP; |
| 601 | } | 607 | } |
| 602 | } | 608 | } |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 4cb2dfba0993..eb6be5030c70 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -139,9 +139,6 @@ dev->hard_header == NULL (ll header is added by device, we cannot control it) | |||
| 139 | static HLIST_HEAD(packet_sklist); | 139 | static HLIST_HEAD(packet_sklist); |
| 140 | static DEFINE_RWLOCK(packet_sklist_lock); | 140 | static DEFINE_RWLOCK(packet_sklist_lock); |
| 141 | 141 | ||
| 142 | static atomic_t packet_socks_nr; | ||
| 143 | |||
| 144 | |||
| 145 | /* Private packet socket structures. */ | 142 | /* Private packet socket structures. */ |
| 146 | 143 | ||
| 147 | struct packet_mclist | 144 | struct packet_mclist |
| @@ -236,10 +233,7 @@ static void packet_sock_destruct(struct sock *sk) | |||
| 236 | return; | 233 | return; |
| 237 | } | 234 | } |
| 238 | 235 | ||
| 239 | atomic_dec(&packet_socks_nr); | 236 | sk_refcnt_debug_dec(sk); |
| 240 | #ifdef PACKET_REFCNT_DEBUG | ||
| 241 | printk(KERN_DEBUG "PACKET socket %p is free, %d are alive\n", sk, atomic_read(&packet_socks_nr)); | ||
| 242 | #endif | ||
| 243 | } | 237 | } |
| 244 | 238 | ||
| 245 | 239 | ||
| @@ -515,7 +509,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet | |||
| 515 | sll->sll_hatype = dev->type; | 509 | sll->sll_hatype = dev->type; |
| 516 | sll->sll_protocol = skb->protocol; | 510 | sll->sll_protocol = skb->protocol; |
| 517 | sll->sll_pkttype = skb->pkt_type; | 511 | sll->sll_pkttype = skb->pkt_type; |
| 518 | if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST) | 512 | if (unlikely(po->origdev)) |
| 519 | sll->sll_ifindex = orig_dev->ifindex; | 513 | sll->sll_ifindex = orig_dev->ifindex; |
| 520 | else | 514 | else |
| 521 | sll->sll_ifindex = dev->ifindex; | 515 | sll->sll_ifindex = dev->ifindex; |
| @@ -661,7 +655,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe | |||
| 661 | sll->sll_hatype = dev->type; | 655 | sll->sll_hatype = dev->type; |
| 662 | sll->sll_protocol = skb->protocol; | 656 | sll->sll_protocol = skb->protocol; |
| 663 | sll->sll_pkttype = skb->pkt_type; | 657 | sll->sll_pkttype = skb->pkt_type; |
| 664 | if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST) | 658 | if (unlikely(po->origdev)) |
| 665 | sll->sll_ifindex = orig_dev->ifindex; | 659 | sll->sll_ifindex = orig_dev->ifindex; |
| 666 | else | 660 | else |
| 667 | sll->sll_ifindex = dev->ifindex; | 661 | sll->sll_ifindex = dev->ifindex; |
| @@ -849,6 +843,7 @@ static int packet_release(struct socket *sock) | |||
| 849 | /* Purge queues */ | 843 | /* Purge queues */ |
| 850 | 844 | ||
| 851 | skb_queue_purge(&sk->sk_receive_queue); | 845 | skb_queue_purge(&sk->sk_receive_queue); |
| 846 | sk_refcnt_debug_release(sk); | ||
| 852 | 847 | ||
| 853 | sock_put(sk); | 848 | sock_put(sk); |
| 854 | return 0; | 849 | return 0; |
| @@ -1010,7 +1005,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol) | |||
| 1010 | po->num = proto; | 1005 | po->num = proto; |
| 1011 | 1006 | ||
| 1012 | sk->sk_destruct = packet_sock_destruct; | 1007 | sk->sk_destruct = packet_sock_destruct; |
| 1013 | atomic_inc(&packet_socks_nr); | 1008 | sk_refcnt_debug_inc(sk); |
| 1014 | 1009 | ||
| 1015 | /* | 1010 | /* |
| 1016 | * Attach a protocol block | 1011 | * Attach a protocol block |
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 51d151c0e962..73d60a307129 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
| @@ -27,6 +27,10 @@ | |||
| 27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
| 28 | #include <linux/rfkill.h> | 28 | #include <linux/rfkill.h> |
| 29 | 29 | ||
| 30 | /* Get declaration of rfkill_switch_all() to shut up sparse. */ | ||
| 31 | #include "rfkill-input.h" | ||
| 32 | |||
| 33 | |||
| 30 | MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>"); | 34 | MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>"); |
| 31 | MODULE_VERSION("1.0"); | 35 | MODULE_VERSION("1.0"); |
| 32 | MODULE_DESCRIPTION("RF switch support"); | 36 | MODULE_DESCRIPTION("RF switch support"); |
| @@ -276,21 +280,17 @@ static struct class rfkill_class = { | |||
| 276 | 280 | ||
| 277 | static int rfkill_add_switch(struct rfkill *rfkill) | 281 | static int rfkill_add_switch(struct rfkill *rfkill) |
| 278 | { | 282 | { |
| 279 | int retval; | 283 | int error; |
| 280 | |||
| 281 | retval = mutex_lock_interruptible(&rfkill_mutex); | ||
| 282 | if (retval) | ||
| 283 | return retval; | ||
| 284 | 284 | ||
| 285 | retval = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); | 285 | mutex_lock(&rfkill_mutex); |
| 286 | if (retval) | ||
| 287 | goto out; | ||
| 288 | 286 | ||
| 289 | list_add_tail(&rfkill->node, &rfkill_list); | 287 | error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); |
| 288 | if (!error) | ||
| 289 | list_add_tail(&rfkill->node, &rfkill_list); | ||
| 290 | 290 | ||
| 291 | out: | ||
| 292 | mutex_unlock(&rfkill_mutex); | 291 | mutex_unlock(&rfkill_mutex); |
| 293 | return retval; | 292 | |
| 293 | return error; | ||
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | static void rfkill_remove_switch(struct rfkill *rfkill) | 296 | static void rfkill_remove_switch(struct rfkill *rfkill) |
| @@ -387,20 +387,23 @@ int rfkill_register(struct rfkill *rfkill) | |||
| 387 | 387 | ||
| 388 | if (!rfkill->toggle_radio) | 388 | if (!rfkill->toggle_radio) |
| 389 | return -EINVAL; | 389 | return -EINVAL; |
| 390 | if (rfkill->type >= RFKILL_TYPE_MAX) | ||
| 391 | return -EINVAL; | ||
| 392 | |||
| 393 | snprintf(dev->bus_id, sizeof(dev->bus_id), | ||
| 394 | "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1); | ||
| 395 | |||
| 396 | rfkill_led_trigger_register(rfkill); | ||
| 390 | 397 | ||
| 391 | error = rfkill_add_switch(rfkill); | 398 | error = rfkill_add_switch(rfkill); |
| 392 | if (error) | 399 | if (error) |
| 393 | return error; | 400 | return error; |
| 394 | 401 | ||
| 395 | snprintf(dev->bus_id, sizeof(dev->bus_id), | ||
| 396 | "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1); | ||
| 397 | |||
| 398 | error = device_add(dev); | 402 | error = device_add(dev); |
| 399 | if (error) { | 403 | if (error) { |
| 400 | rfkill_remove_switch(rfkill); | 404 | rfkill_remove_switch(rfkill); |
| 401 | return error; | 405 | return error; |
| 402 | } | 406 | } |
| 403 | rfkill_led_trigger_register(rfkill); | ||
| 404 | 407 | ||
| 405 | return 0; | 408 | return 0; |
| 406 | } | 409 | } |
| @@ -416,9 +419,9 @@ EXPORT_SYMBOL(rfkill_register); | |||
| 416 | */ | 419 | */ |
| 417 | void rfkill_unregister(struct rfkill *rfkill) | 420 | void rfkill_unregister(struct rfkill *rfkill) |
| 418 | { | 421 | { |
| 419 | rfkill_led_trigger_unregister(rfkill); | ||
| 420 | device_del(&rfkill->dev); | 422 | device_del(&rfkill->dev); |
| 421 | rfkill_remove_switch(rfkill); | 423 | rfkill_remove_switch(rfkill); |
| 424 | rfkill_led_trigger_unregister(rfkill); | ||
| 422 | put_device(&rfkill->dev); | 425 | put_device(&rfkill->dev); |
| 423 | } | 426 | } |
| 424 | EXPORT_SYMBOL(rfkill_unregister); | 427 | EXPORT_SYMBOL(rfkill_unregister); |
| @@ -448,5 +451,5 @@ static void __exit rfkill_exit(void) | |||
| 448 | class_unregister(&rfkill_class); | 451 | class_unregister(&rfkill_class); |
| 449 | } | 452 | } |
| 450 | 453 | ||
| 451 | module_init(rfkill_init); | 454 | subsys_initcall(rfkill_init); |
| 452 | module_exit(rfkill_exit); | 455 | module_exit(rfkill_exit); |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 53171029439f..c39008209164 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
| @@ -613,17 +613,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
| 613 | memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key)); | 613 | memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key)); |
| 614 | n->ht_up = ht; | 614 | n->ht_up = ht; |
| 615 | n->handle = handle; | 615 | n->handle = handle; |
| 616 | { | 616 | n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0; |
| 617 | u8 i = 0; | ||
| 618 | u32 mask = ntohl(s->hmask); | ||
| 619 | if (mask) { | ||
| 620 | while (!(mask & 1)) { | ||
| 621 | i++; | ||
| 622 | mask>>=1; | ||
| 623 | } | ||
| 624 | } | ||
| 625 | n->fshift = i; | ||
| 626 | } | ||
| 627 | 617 | ||
| 628 | #ifdef CONFIG_CLS_U32_MARK | 618 | #ifdef CONFIG_CLS_U32_MARK |
| 629 | if (tb[TCA_U32_MARK-1]) { | 619 | if (tb[TCA_U32_MARK-1]) { |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 515e7a692f9b..e835da8fc091 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -457,7 +457,7 @@ static int unix_release_sock (struct sock *sk, int embrion) | |||
| 457 | * What the above comment does talk about? --ANK(980817) | 457 | * What the above comment does talk about? --ANK(980817) |
| 458 | */ | 458 | */ |
| 459 | 459 | ||
| 460 | if (atomic_read(&unix_tot_inflight)) | 460 | if (unix_tot_inflight) |
| 461 | unix_gc(); /* Garbage collect fds */ | 461 | unix_gc(); /* Garbage collect fds */ |
| 462 | 462 | ||
| 463 | return 0; | 463 | return 0; |
| @@ -599,15 +599,14 @@ static struct sock * unix_create1(struct net *net, struct socket *sock) | |||
| 599 | struct sock *sk = NULL; | 599 | struct sock *sk = NULL; |
| 600 | struct unix_sock *u; | 600 | struct unix_sock *u; |
| 601 | 601 | ||
| 602 | if (atomic_read(&unix_nr_socks) >= 2*get_max_files()) | 602 | atomic_inc(&unix_nr_socks); |
| 603 | if (atomic_read(&unix_nr_socks) > 2 * get_max_files()) | ||
| 603 | goto out; | 604 | goto out; |
| 604 | 605 | ||
| 605 | sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto); | 606 | sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto); |
| 606 | if (!sk) | 607 | if (!sk) |
| 607 | goto out; | 608 | goto out; |
| 608 | 609 | ||
| 609 | atomic_inc(&unix_nr_socks); | ||
| 610 | |||
| 611 | sock_init_data(sock,sk); | 610 | sock_init_data(sock,sk); |
| 612 | lockdep_set_class(&sk->sk_receive_queue.lock, | 611 | lockdep_set_class(&sk->sk_receive_queue.lock, |
| 613 | &af_unix_sk_receive_queue_lock_key); | 612 | &af_unix_sk_receive_queue_lock_key); |
| @@ -625,6 +624,8 @@ static struct sock * unix_create1(struct net *net, struct socket *sock) | |||
| 625 | init_waitqueue_head(&u->peer_wait); | 624 | init_waitqueue_head(&u->peer_wait); |
| 626 | unix_insert_socket(unix_sockets_unbound, sk); | 625 | unix_insert_socket(unix_sockets_unbound, sk); |
| 627 | out: | 626 | out: |
| 627 | if (sk == NULL) | ||
| 628 | atomic_dec(&unix_nr_socks); | ||
| 628 | return sk; | 629 | return sk; |
| 629 | } | 630 | } |
| 630 | 631 | ||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 406b6433e467..ebdff3d877a1 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
| @@ -92,7 +92,7 @@ static LIST_HEAD(gc_inflight_list); | |||
| 92 | static LIST_HEAD(gc_candidates); | 92 | static LIST_HEAD(gc_candidates); |
| 93 | static DEFINE_SPINLOCK(unix_gc_lock); | 93 | static DEFINE_SPINLOCK(unix_gc_lock); |
| 94 | 94 | ||
| 95 | atomic_t unix_tot_inflight = ATOMIC_INIT(0); | 95 | unsigned int unix_tot_inflight; |
| 96 | 96 | ||
| 97 | 97 | ||
| 98 | static struct sock *unix_get_socket(struct file *filp) | 98 | static struct sock *unix_get_socket(struct file *filp) |
| @@ -133,7 +133,7 @@ void unix_inflight(struct file *fp) | |||
| 133 | } else { | 133 | } else { |
| 134 | BUG_ON(list_empty(&u->link)); | 134 | BUG_ON(list_empty(&u->link)); |
| 135 | } | 135 | } |
| 136 | atomic_inc(&unix_tot_inflight); | 136 | unix_tot_inflight++; |
| 137 | spin_unlock(&unix_gc_lock); | 137 | spin_unlock(&unix_gc_lock); |
| 138 | } | 138 | } |
| 139 | } | 139 | } |
| @@ -147,7 +147,7 @@ void unix_notinflight(struct file *fp) | |||
| 147 | BUG_ON(list_empty(&u->link)); | 147 | BUG_ON(list_empty(&u->link)); |
| 148 | if (atomic_dec_and_test(&u->inflight)) | 148 | if (atomic_dec_and_test(&u->inflight)) |
| 149 | list_del_init(&u->link); | 149 | list_del_init(&u->link); |
| 150 | atomic_dec(&unix_tot_inflight); | 150 | unix_tot_inflight--; |
| 151 | spin_unlock(&unix_gc_lock); | 151 | spin_unlock(&unix_gc_lock); |
| 152 | } | 152 | } |
| 153 | } | 153 | } |
| @@ -161,7 +161,7 @@ static inline struct sk_buff *sock_queue_head(struct sock *sk) | |||
| 161 | for (skb = sock_queue_head(sk)->next, next = skb->next; \ | 161 | for (skb = sock_queue_head(sk)->next, next = skb->next; \ |
| 162 | skb != sock_queue_head(sk); skb = next, next = skb->next) | 162 | skb != sock_queue_head(sk); skb = next, next = skb->next) |
| 163 | 163 | ||
| 164 | static void scan_inflight(struct sock *x, void (*func)(struct sock *), | 164 | static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), |
| 165 | struct sk_buff_head *hitlist) | 165 | struct sk_buff_head *hitlist) |
| 166 | { | 166 | { |
| 167 | struct sk_buff *skb; | 167 | struct sk_buff *skb; |
| @@ -185,9 +185,9 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *), | |||
| 185 | * if it indeed does so | 185 | * if it indeed does so |
| 186 | */ | 186 | */ |
| 187 | struct sock *sk = unix_get_socket(*fp++); | 187 | struct sock *sk = unix_get_socket(*fp++); |
| 188 | if(sk) { | 188 | if (sk) { |
| 189 | hit = true; | 189 | hit = true; |
| 190 | func(sk); | 190 | func(unix_sk(sk)); |
| 191 | } | 191 | } |
| 192 | } | 192 | } |
| 193 | if (hit && hitlist != NULL) { | 193 | if (hit && hitlist != NULL) { |
| @@ -199,7 +199,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *), | |||
| 199 | spin_unlock(&x->sk_receive_queue.lock); | 199 | spin_unlock(&x->sk_receive_queue.lock); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static void scan_children(struct sock *x, void (*func)(struct sock *), | 202 | static void scan_children(struct sock *x, void (*func)(struct unix_sock *), |
| 203 | struct sk_buff_head *hitlist) | 203 | struct sk_buff_head *hitlist) |
| 204 | { | 204 | { |
| 205 | if (x->sk_state != TCP_LISTEN) | 205 | if (x->sk_state != TCP_LISTEN) |
| @@ -235,20 +235,18 @@ static void scan_children(struct sock *x, void (*func)(struct sock *), | |||
| 235 | } | 235 | } |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | static void dec_inflight(struct sock *sk) | 238 | static void dec_inflight(struct unix_sock *usk) |
| 239 | { | 239 | { |
| 240 | atomic_dec(&unix_sk(sk)->inflight); | 240 | atomic_dec(&usk->inflight); |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | static void inc_inflight(struct sock *sk) | 243 | static void inc_inflight(struct unix_sock *usk) |
| 244 | { | 244 | { |
| 245 | atomic_inc(&unix_sk(sk)->inflight); | 245 | atomic_inc(&usk->inflight); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | static void inc_inflight_move_tail(struct sock *sk) | 248 | static void inc_inflight_move_tail(struct unix_sock *u) |
| 249 | { | 249 | { |
| 250 | struct unix_sock *u = unix_sk(sk); | ||
| 251 | |||
| 252 | atomic_inc(&u->inflight); | 250 | atomic_inc(&u->inflight); |
| 253 | /* | 251 | /* |
| 254 | * If this is still a candidate, move it to the end of the | 252 | * If this is still a candidate, move it to the end of the |
