mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-26 16:51:48 +00:00
1738 lines
56 KiB
Diff
1738 lines
56 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index d7c0a3833a2b..05ace57061d6 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 3
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 70
|
|
+SUBLEVEL = 71
|
|
EXTRAVERSION =
|
|
NAME = Saber-toothed Squirrel
|
|
|
|
diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h
|
|
index ac12ae2b9286..db9a16c704f3 100644
|
|
--- a/arch/cris/include/asm/io.h
|
|
+++ b/arch/cris/include/asm/io.h
|
|
@@ -3,6 +3,7 @@
|
|
|
|
#include <asm/page.h> /* for __va, __pa */
|
|
#include <arch/io.h>
|
|
+#include <asm-generic/iomap.h>
|
|
#include <linux/kernel.h>
|
|
|
|
struct cris_io_operations
|
|
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h
|
|
index 483f6c6a4238..2d0cb8e8eedd 100644
|
|
--- a/arch/ia64/include/asm/processor.h
|
|
+++ b/arch/ia64/include/asm/processor.h
|
|
@@ -322,7 +322,7 @@ struct thread_struct {
|
|
regs->loadrs = 0; \
|
|
regs->r8 = get_dumpable(current->mm); /* set "don't zap registers" flag */ \
|
|
regs->r12 = new_sp - 16; /* allocate 16 byte scratch area */ \
|
|
- if (unlikely(!get_dumpable(current->mm))) { \
|
|
+ if (unlikely(get_dumpable(current->mm) != SUID_DUMP_USER)) { \
|
|
/* \
|
|
* Zap scratch regs to avoid leaking bits between processes with different \
|
|
* uid/privileges. \
|
|
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
|
|
index 45eb998557f8..e6de787956ce 100644
|
|
--- a/arch/powerpc/kernel/signal_32.c
|
|
+++ b/arch/powerpc/kernel/signal_32.c
|
|
@@ -459,7 +459,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
|
if (copy_vsx_to_user(&frame->mc_vsregs, current))
|
|
return 1;
|
|
msr |= MSR_VSX;
|
|
- }
|
|
+ } else if (!ctx_has_vsx_region)
|
|
+ /*
|
|
+ * With a small context structure we can't hold the VSX
|
|
+ * registers, hence clear the MSR value to indicate the state
|
|
+ * was not saved.
|
|
+ */
|
|
+ msr &= ~MSR_VSX;
|
|
+
|
|
+
|
|
#endif /* CONFIG_VSX */
|
|
#ifdef CONFIG_SPE
|
|
/* save spe registers */
|
|
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
|
|
index cfe0069bcfc8..fcf89bff1177 100644
|
|
--- a/arch/powerpc/kernel/vio.c
|
|
+++ b/arch/powerpc/kernel/vio.c
|
|
@@ -1342,12 +1342,12 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
|
|
|
|
dn = dev->of_node;
|
|
if (!dn) {
|
|
- strcat(buf, "\n");
|
|
+ strcpy(buf, "\n");
|
|
return strlen(buf);
|
|
}
|
|
cp = of_get_property(dn, "compatible", NULL);
|
|
if (!cp) {
|
|
- strcat(buf, "\n");
|
|
+ strcpy(buf, "\n");
|
|
return strlen(buf);
|
|
}
|
|
|
|
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
|
|
index fbdd74dac3ac..5da8e8df5922 100644
|
|
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
|
|
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
|
|
@@ -613,13 +613,23 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb,
|
|
rid_end = pe->rid + 1;
|
|
}
|
|
|
|
- /* Associate PE in PELT */
|
|
+ /*
|
|
+ * Associate PE in PELT. We need add the PE into the
|
|
+ * corresponding PELT-V as well. Otherwise, the error
|
|
+ * originated from the PE might contribute to other
|
|
+ * PEs.
|
|
+ */
|
|
rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid,
|
|
bcomp, dcomp, fcomp, OPAL_MAP_PE);
|
|
if (rc) {
|
|
pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc);
|
|
return -ENXIO;
|
|
}
|
|
+
|
|
+ rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number,
|
|
+ pe->pe_number, OPAL_ADD_PE_TO_DOMAIN);
|
|
+ if (rc)
|
|
+ pe_warn(pe, "OPAL error %d adding self to PELTV\n", rc);
|
|
opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,
|
|
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
|
|
|
|
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
|
|
index 5d8cf0d6796c..b316ffe8ab59 100644
|
|
--- a/arch/x86/kernel/microcode_amd.c
|
|
+++ b/arch/x86/kernel/microcode_amd.c
|
|
@@ -338,7 +338,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device)
|
|
snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86);
|
|
|
|
if (request_firmware(&fw, (const char *)fw_name, device)) {
|
|
- pr_err("failed to load file %s\n", fw_name);
|
|
+ pr_debug("failed to load file %s\n", fw_name);
|
|
goto out;
|
|
}
|
|
|
|
diff --git a/block/blk-core.c b/block/blk-core.c
|
|
index 85fd41003434..a02cfb7e4123 100644
|
|
--- a/block/blk-core.c
|
|
+++ b/block/blk-core.c
|
|
@@ -2041,6 +2041,7 @@ void blk_start_request(struct request *req)
|
|
if (unlikely(blk_bidi_rq(req)))
|
|
req->next_rq->resid_len = blk_rq_bytes(req->next_rq);
|
|
|
|
+ BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
|
|
blk_add_timer(req);
|
|
}
|
|
EXPORT_SYMBOL(blk_start_request);
|
|
diff --git a/block/blk-settings.c b/block/blk-settings.c
|
|
index d3234fc494ad..b74cc58bc038 100644
|
|
--- a/block/blk-settings.c
|
|
+++ b/block/blk-settings.c
|
|
@@ -143,6 +143,7 @@ void blk_set_stacking_limits(struct queue_limits *lim)
|
|
lim->discard_zeroes_data = 1;
|
|
lim->max_segments = USHRT_MAX;
|
|
lim->max_hw_sectors = UINT_MAX;
|
|
+ lim->max_segment_size = UINT_MAX;
|
|
|
|
lim->max_sectors = BLK_DEF_MAX_SECTORS;
|
|
}
|
|
diff --git a/block/blk-timeout.c b/block/blk-timeout.c
|
|
index 780354888958..b1182ea52427 100644
|
|
--- a/block/blk-timeout.c
|
|
+++ b/block/blk-timeout.c
|
|
@@ -90,8 +90,8 @@ static void blk_rq_timed_out(struct request *req)
|
|
__blk_complete_request(req);
|
|
break;
|
|
case BLK_EH_RESET_TIMER:
|
|
- blk_clear_rq_complete(req);
|
|
blk_add_timer(req);
|
|
+ blk_clear_rq_complete(req);
|
|
break;
|
|
case BLK_EH_NOT_HANDLED:
|
|
/*
|
|
@@ -173,7 +173,6 @@ void blk_add_timer(struct request *req)
|
|
return;
|
|
|
|
BUG_ON(!list_empty(&req->timeout_list));
|
|
- BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
|
|
|
|
/*
|
|
* Some LLDs, like scsi, peek at the timeout to prevent a
|
|
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
|
|
index 6ddd99e6114b..c21f761b65b5 100644
|
|
--- a/crypto/ansi_cprng.c
|
|
+++ b/crypto/ansi_cprng.c
|
|
@@ -230,11 +230,11 @@ remainder:
|
|
*/
|
|
if (byte_count < DEFAULT_BLK_SZ) {
|
|
empty_rbuf:
|
|
- for (; ctx->rand_data_valid < DEFAULT_BLK_SZ;
|
|
- ctx->rand_data_valid++) {
|
|
+ while (ctx->rand_data_valid < DEFAULT_BLK_SZ) {
|
|
*ptr = ctx->rand_data[ctx->rand_data_valid];
|
|
ptr++;
|
|
byte_count--;
|
|
+ ctx->rand_data_valid++;
|
|
if (byte_count == 0)
|
|
goto done;
|
|
}
|
|
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
|
|
index 9ba8c73cea16..fe2f9d95d0f8 100644
|
|
--- a/drivers/acpi/acpica/exoparg1.c
|
|
+++ b/drivers/acpi/acpica/exoparg1.c
|
|
@@ -970,10 +970,17 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
|
*/
|
|
return_desc =
|
|
*(operand[0]->reference.where);
|
|
- if (return_desc) {
|
|
- acpi_ut_add_reference
|
|
- (return_desc);
|
|
+ if (!return_desc) {
|
|
+ /*
|
|
+ * Element is NULL, do not allow the dereference.
|
|
+ * This provides compatibility with other ACPI
|
|
+ * implementations.
|
|
+ */
|
|
+ return_ACPI_STATUS
|
|
+ (AE_AML_UNINITIALIZED_ELEMENT);
|
|
}
|
|
+
|
|
+ acpi_ut_add_reference(return_desc);
|
|
break;
|
|
|
|
default:
|
|
@@ -998,11 +1005,40 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
|
acpi_namespace_node
|
|
*)
|
|
return_desc);
|
|
- }
|
|
+ if (!return_desc) {
|
|
+ break;
|
|
+ }
|
|
|
|
- /* Add another reference to the object! */
|
|
+ /*
|
|
+ * June 2013:
|
|
+ * buffer_fields/field_units require additional resolution
|
|
+ */
|
|
+ switch (return_desc->common.type) {
|
|
+ case ACPI_TYPE_BUFFER_FIELD:
|
|
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
|
|
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
|
|
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
|
|
|
|
- acpi_ut_add_reference(return_desc);
|
|
+ status =
|
|
+ acpi_ex_read_data_from_field
|
|
+ (walk_state, return_desc,
|
|
+ &temp_desc);
|
|
+ if (ACPI_FAILURE(status)) {
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ return_desc = temp_desc;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+
|
|
+ /* Add another reference to the object */
|
|
+
|
|
+ acpi_ut_add_reference
|
|
+ (return_desc);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
break;
|
|
|
|
default:
|
|
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
|
|
index c6cf843cc4c9..9806f4be7b88 100644
|
|
--- a/drivers/acpi/acpica/exstore.c
|
|
+++ b/drivers/acpi/acpica/exstore.c
|
|
@@ -57,6 +57,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
|
|
union acpi_operand_object *dest_desc,
|
|
struct acpi_walk_state *walk_state);
|
|
|
|
+static acpi_status
|
|
+acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
|
|
+ struct acpi_namespace_node *node,
|
|
+ struct acpi_walk_state *walk_state);
|
|
+
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: acpi_ex_store
|
|
@@ -376,7 +381,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
|
|
* When storing into an object the data is converted to the
|
|
* target object type then stored in the object. This means
|
|
* that the target object type (for an initialized target) will
|
|
- * not be changed by a store operation.
|
|
+ * not be changed by a store operation. A copy_object can change
|
|
+ * the target type, however.
|
|
+ *
|
|
+ * The implicit_conversion flag is set to NO/FALSE only when
|
|
+ * storing to an arg_x -- as per the rules of the ACPI spec.
|
|
*
|
|
* Assumes parameters are already validated.
|
|
*
|
|
@@ -400,7 +409,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
|
|
target_type = acpi_ns_get_type(node);
|
|
target_desc = acpi_ns_get_attached_object(node);
|
|
|
|
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
|
|
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
|
|
source_desc,
|
|
acpi_ut_get_object_type_name(source_desc), node,
|
|
acpi_ut_get_type_name(target_type)));
|
|
@@ -414,46 +423,31 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
|
|
return_ACPI_STATUS(status);
|
|
}
|
|
|
|
- /* If no implicit conversion, drop into the default case below */
|
|
-
|
|
- if ((!implicit_conversion) ||
|
|
- ((walk_state->opcode == AML_COPY_OP) &&
|
|
- (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) &&
|
|
- (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) &&
|
|
- (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) {
|
|
- /*
|
|
- * Force execution of default (no implicit conversion). Note:
|
|
- * copy_object does not perform an implicit conversion, as per the ACPI
|
|
- * spec -- except in case of region/bank/index fields -- because these
|
|
- * objects must retain their original type permanently.
|
|
- */
|
|
- target_type = ACPI_TYPE_ANY;
|
|
- }
|
|
-
|
|
/* Do the actual store operation */
|
|
|
|
switch (target_type) {
|
|
- case ACPI_TYPE_BUFFER_FIELD:
|
|
- case ACPI_TYPE_LOCAL_REGION_FIELD:
|
|
- case ACPI_TYPE_LOCAL_BANK_FIELD:
|
|
- case ACPI_TYPE_LOCAL_INDEX_FIELD:
|
|
-
|
|
- /* For fields, copy the source data to the target field. */
|
|
-
|
|
- status = acpi_ex_write_data_to_field(source_desc, target_desc,
|
|
- &walk_state->result_obj);
|
|
- break;
|
|
-
|
|
case ACPI_TYPE_INTEGER:
|
|
case ACPI_TYPE_STRING:
|
|
case ACPI_TYPE_BUFFER:
|
|
|
|
/*
|
|
- * These target types are all of type Integer/String/Buffer, and
|
|
- * therefore support implicit conversion before the store.
|
|
- *
|
|
- * Copy and/or convert the source object to a new target object
|
|
+ * The simple data types all support implicit source operand
|
|
+ * conversion before the store.
|
|
*/
|
|
+
|
|
+ if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) {
|
|
+ /*
|
|
+ * However, copy_object and Stores to arg_x do not perform
|
|
+ * an implicit conversion, as per the ACPI specification.
|
|
+ * A direct store is performed instead.
|
|
+ */
|
|
+ status = acpi_ex_store_direct_to_node(source_desc, node,
|
|
+ walk_state);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* Store with implicit source operand conversion support */
|
|
+
|
|
status =
|
|
acpi_ex_store_object_to_object(source_desc, target_desc,
|
|
&new_desc, walk_state);
|
|
@@ -467,13 +461,12 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
|
|
* the Name's type to that of the value being stored in it.
|
|
* source_desc reference count is incremented by attach_object.
|
|
*
|
|
- * Note: This may change the type of the node if an explicit store
|
|
- * has been performed such that the node/object type has been
|
|
- * changed.
|
|
+ * Note: This may change the type of the node if an explicit
|
|
+ * store has been performed such that the node/object type
|
|
+ * has been changed.
|
|
*/
|
|
- status =
|
|
- acpi_ns_attach_object(node, new_desc,
|
|
- new_desc->common.type);
|
|
+ status = acpi_ns_attach_object(node, new_desc,
|
|
+ new_desc->common.type);
|
|
|
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
"Store %s into %s via Convert/Attach\n",
|
|
@@ -484,19 +477,83 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
|
|
}
|
|
break;
|
|
|
|
+ case ACPI_TYPE_BUFFER_FIELD:
|
|
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
|
|
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
|
|
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
|
|
+ /*
|
|
+ * For all fields, always write the source data to the target
|
|
+ * field. Any required implicit source operand conversion is
|
|
+ * performed in the function below as necessary. Note, field
|
|
+ * objects must retain their original type permanently.
|
|
+ */
|
|
+ status = acpi_ex_write_data_to_field(source_desc, target_desc,
|
|
+ &walk_state->result_obj);
|
|
+ break;
|
|
+
|
|
default:
|
|
+ /*
|
|
+ * No conversions for all other types. Directly store a copy of
|
|
+ * the source object. This is the ACPI spec-defined behavior for
|
|
+ * the copy_object operator.
|
|
+ *
|
|
+ * NOTE: For the Store operator, this is a departure from the
|
|
+ * ACPI spec, which states "If conversion is impossible, abort
|
|
+ * the running control method". Instead, this code implements
|
|
+ * "If conversion is impossible, treat the Store operation as
|
|
+ * a CopyObject".
|
|
+ */
|
|
+ status = acpi_ex_store_direct_to_node(source_desc, node,
|
|
+ walk_state);
|
|
+ break;
|
|
+ }
|
|
|
|
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
- "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
|
|
- acpi_ut_get_object_type_name(source_desc),
|
|
- source_desc, node));
|
|
+ return_ACPI_STATUS(status);
|
|
+}
|
|
|
|
- /* No conversions for all other types. Just attach the source object */
|
|
+/*******************************************************************************
|
|
+ *
|
|
+ * FUNCTION: acpi_ex_store_direct_to_node
|
|
+ *
|
|
+ * PARAMETERS: source_desc - Value to be stored
|
|
+ * node - Named object to receive the value
|
|
+ * walk_state - Current walk state
|
|
+ *
|
|
+ * RETURN: Status
|
|
+ *
|
|
+ * DESCRIPTION: "Store" an object directly to a node. This involves a copy
|
|
+ * and an attach.
|
|
+ *
|
|
+ ******************************************************************************/
|
|
|
|
- status = acpi_ns_attach_object(node, source_desc,
|
|
- source_desc->common.type);
|
|
- break;
|
|
+static acpi_status
|
|
+acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
|
|
+ struct acpi_namespace_node *node,
|
|
+ struct acpi_walk_state *walk_state)
|
|
+{
|
|
+ acpi_status status;
|
|
+ union acpi_operand_object *new_desc;
|
|
+
|
|
+ ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
|
|
+
|
|
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
+ "Storing [%s] (%p) directly into node [%s] (%p)"
|
|
+ " with no implicit conversion\n",
|
|
+ acpi_ut_get_object_type_name(source_desc),
|
|
+ source_desc, acpi_ut_get_type_name(node->type),
|
|
+ node));
|
|
+
|
|
+ /* Copy the source object to a new object */
|
|
+
|
|
+ status =
|
|
+ acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
|
|
+ if (ACPI_FAILURE(status)) {
|
|
+ return_ACPI_STATUS(status);
|
|
}
|
|
|
|
+ /* Attach the new object to the node */
|
|
+
|
|
+ status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
|
|
+ acpi_ut_remove_reference(new_desc);
|
|
return_ACPI_STATUS(status);
|
|
}
|
|
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
|
|
index 4e8213aa02fd..a7d70e2a8d74 100644
|
|
--- a/drivers/block/brd.c
|
|
+++ b/drivers/block/brd.c
|
|
@@ -546,7 +546,7 @@ static struct kobject *brd_probe(dev_t dev, int *part, void *data)
|
|
|
|
mutex_lock(&brd_devices_mutex);
|
|
brd = brd_init_one(MINOR(dev) >> part_shift);
|
|
- kobj = brd ? get_disk(brd->brd_disk) : ERR_PTR(-ENOMEM);
|
|
+ kobj = brd ? get_disk(brd->brd_disk) : NULL;
|
|
mutex_unlock(&brd_devices_mutex);
|
|
|
|
*part = 0;
|
|
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
|
|
index 179b5b408cb3..a4ddbae2e100 100644
|
|
--- a/drivers/block/loop.c
|
|
+++ b/drivers/block/loop.c
|
|
@@ -1743,7 +1743,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)
|
|
if (err < 0)
|
|
err = loop_add(&lo, MINOR(dev) >> part_shift);
|
|
if (err < 0)
|
|
- kobj = ERR_PTR(err);
|
|
+ kobj = NULL;
|
|
else
|
|
kobj = get_disk(lo->lo_disk);
|
|
mutex_unlock(&loop_index_mutex);
|
|
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
|
|
index 22b14a68e35e..1f4f94103c55 100644
|
|
--- a/drivers/hwmon/lm90.c
|
|
+++ b/drivers/hwmon/lm90.c
|
|
@@ -278,7 +278,7 @@ static const struct lm90_params lm90_params[] = {
|
|
[max6696] = {
|
|
.flags = LM90_HAVE_EMERGENCY
|
|
| LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3,
|
|
- .alert_alarms = 0x187c,
|
|
+ .alert_alarms = 0x1c7c,
|
|
.max_convrate = 6,
|
|
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
|
|
},
|
|
@@ -1504,19 +1504,22 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag)
|
|
if ((alarms & 0x7f) == 0 && (alarms2 & 0xfe) == 0) {
|
|
dev_info(&client->dev, "Everything OK\n");
|
|
} else {
|
|
- if (alarms & 0x61)
|
|
+ if ((alarms & 0x61) || (alarms2 & 0x80))
|
|
dev_warn(&client->dev,
|
|
"temp%d out of range, please check!\n", 1);
|
|
- if (alarms & 0x1a)
|
|
+ if ((alarms & 0x1a) || (alarms2 & 0x20))
|
|
dev_warn(&client->dev,
|
|
"temp%d out of range, please check!\n", 2);
|
|
if (alarms & 0x04)
|
|
dev_warn(&client->dev,
|
|
"temp%d diode open, please check!\n", 2);
|
|
|
|
- if (alarms2 & 0x18)
|
|
+ if (alarms2 & 0x5a)
|
|
dev_warn(&client->dev,
|
|
"temp%d out of range, please check!\n", 3);
|
|
+ if (alarms2 & 0x04)
|
|
+ dev_warn(&client->dev,
|
|
+ "temp%d diode open, please check!\n", 3);
|
|
|
|
/*
|
|
* Disable ALERT# output, because these chips don't implement
|
|
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
|
|
index 21a3d77ea7e2..77405b4e8636 100644
|
|
--- a/drivers/net/can/c_can/c_can.c
|
|
+++ b/drivers/net/can/c_can/c_can.c
|
|
@@ -760,9 +760,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota)
|
|
msg_ctrl_save = priv->read_reg(priv,
|
|
&priv->regs->ifregs[0].msg_cntrl);
|
|
|
|
- if (msg_ctrl_save & IF_MCONT_EOB)
|
|
- return num_rx_pkts;
|
|
-
|
|
if (msg_ctrl_save & IF_MCONT_MSGLST) {
|
|
c_can_handle_lost_msg_obj(dev, 0, msg_obj);
|
|
num_rx_pkts++;
|
|
@@ -770,6 +767,9 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota)
|
|
continue;
|
|
}
|
|
|
|
+ if (msg_ctrl_save & IF_MCONT_EOB)
|
|
+ return num_rx_pkts;
|
|
+
|
|
if (!(msg_ctrl_save & IF_MCONT_NEWDAT))
|
|
continue;
|
|
|
|
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
|
|
index 1b4404725b8c..effb3b71ce75 100644
|
|
--- a/drivers/net/ethernet/realtek/8139cp.c
|
|
+++ b/drivers/net/ethernet/realtek/8139cp.c
|
|
@@ -1232,6 +1232,7 @@ static void cp_tx_timeout(struct net_device *dev)
|
|
cp_clean_rings(cp);
|
|
rc = cp_init_rings(cp);
|
|
cp_start_hw(cp);
|
|
+ cp_enable_irq(cp);
|
|
|
|
netif_wake_queue(dev);
|
|
|
|
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
|
|
index a06cc283e23d..0b48430d6ad0 100644
|
|
--- a/drivers/net/wireless/libertas/debugfs.c
|
|
+++ b/drivers/net/wireless/libertas/debugfs.c
|
|
@@ -913,7 +913,10 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
|
|
char *p2;
|
|
struct debug_data *d = f->private_data;
|
|
|
|
- pdata = kmalloc(cnt, GFP_KERNEL);
|
|
+ if (cnt == 0)
|
|
+ return 0;
|
|
+
|
|
+ pdata = kmalloc(cnt + 1, GFP_KERNEL);
|
|
if (pdata == NULL)
|
|
return 0;
|
|
|
|
@@ -922,6 +925,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
|
|
kfree(pdata);
|
|
return 0;
|
|
}
|
|
+ pdata[cnt] = '\0';
|
|
|
|
p0 = pdata;
|
|
for (i = 0; i < num_of_items; i++) {
|
|
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
|
|
index 65cb4250259f..6eec862fea28 100644
|
|
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
|
|
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
|
|
@@ -143,6 +143,8 @@ static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev)
|
|
return false;
|
|
}
|
|
|
|
+#define TXSTATUS_READ_INTERVAL 1000000
|
|
+
|
|
static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
|
|
int urb_status, u32 tx_status)
|
|
{
|
|
@@ -170,8 +172,9 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
|
|
queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
|
|
|
|
if (rt2800usb_txstatus_pending(rt2x00dev)) {
|
|
- /* Read register after 250 us */
|
|
- hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000),
|
|
+ /* Read register after 1 ms */
|
|
+ hrtimer_start(&rt2x00dev->txstatus_timer,
|
|
+ ktime_set(0, TXSTATUS_READ_INTERVAL),
|
|
HRTIMER_MODE_REL);
|
|
return false;
|
|
}
|
|
@@ -196,8 +199,9 @@ static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev)
|
|
if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
|
|
return;
|
|
|
|
- /* Read TX_STA_FIFO register after 500 us */
|
|
- hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000),
|
|
+ /* Read TX_STA_FIFO register after 2 ms */
|
|
+ hrtimer_start(&rt2x00dev->txstatus_timer,
|
|
+ ktime_set(0, 2*TXSTATUS_READ_INTERVAL),
|
|
HRTIMER_MODE_REL);
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
|
|
index a8885f060060..6701f2d71274 100644
|
|
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
|
|
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
|
|
@@ -771,6 +771,9 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
|
|
struct rt2x00_dev *rt2x00dev = hw->priv;
|
|
struct data_queue *queue;
|
|
|
|
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
|
|
+ return;
|
|
+
|
|
tx_queue_for_each(rt2x00dev, queue)
|
|
rt2x00queue_flush_queue(queue, drop);
|
|
}
|
|
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
|
|
index 0bd38da4ada0..05fbc3ded9b5 100644
|
|
--- a/drivers/scsi/aacraid/commctrl.c
|
|
+++ b/drivers/scsi/aacraid/commctrl.c
|
|
@@ -508,7 +508,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
|
goto cleanup;
|
|
}
|
|
|
|
- if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) {
|
|
+ if ((fibsize < (sizeof(struct user_aac_srb) - sizeof(struct user_sgentry))) ||
|
|
+ (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))) {
|
|
rcode = -EINVAL;
|
|
goto cleanup;
|
|
}
|
|
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
|
|
index a783d533a1a6..715075291834 100644
|
|
--- a/drivers/uio/uio.c
|
|
+++ b/drivers/uio/uio.c
|
|
@@ -650,16 +650,30 @@ static int uio_mmap_physical(struct vm_area_struct *vma)
|
|
{
|
|
struct uio_device *idev = vma->vm_private_data;
|
|
int mi = uio_find_mem_index(vma);
|
|
+ struct uio_mem *mem;
|
|
if (mi < 0)
|
|
return -EINVAL;
|
|
+ mem = idev->info->mem + mi;
|
|
+
|
|
+ if (vma->vm_end - vma->vm_start > mem->size)
|
|
+ return -EINVAL;
|
|
|
|
vma->vm_flags |= VM_IO | VM_RESERVED;
|
|
|
|
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
|
|
|
+ /*
|
|
+ * We cannot use the vm_iomap_memory() helper here,
|
|
+ * because vma->vm_pgoff is the map index we looked
|
|
+ * up above in uio_find_mem_index(), rather than an
|
|
+ * actual page offset into the mmap.
|
|
+ *
|
|
+ * So we just do the physical mmap without a page
|
|
+ * offset.
|
|
+ */
|
|
return remap_pfn_range(vma,
|
|
vma->vm_start,
|
|
- idev->info->mem[mi].addr >> PAGE_SHIFT,
|
|
+ mem->addr >> PAGE_SHIFT,
|
|
vma->vm_end - vma->vm_start,
|
|
vma->vm_page_prot);
|
|
}
|
|
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
|
|
index c8542356898b..91293b68df5a 100644
|
|
--- a/drivers/usb/serial/mos7840.c
|
|
+++ b/drivers/usb/serial/mos7840.c
|
|
@@ -1664,7 +1664,11 @@ static int mos7840_tiocmget(struct tty_struct *tty)
|
|
return -ENODEV;
|
|
|
|
status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
|
|
+ if (status != 1)
|
|
+ return -EIO;
|
|
status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
|
|
+ if (status != 1)
|
|
+ return -EIO;
|
|
result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
|
|
| ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
|
|
| ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
|
|
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
|
|
index ffbce4525468..612c1c7cb31b 100644
|
|
--- a/drivers/video/au1100fb.c
|
|
+++ b/drivers/video/au1100fb.c
|
|
@@ -375,39 +375,15 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
|
|
int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
|
|
{
|
|
struct au1100fb_device *fbdev;
|
|
- unsigned int len;
|
|
- unsigned long start=0, off;
|
|
|
|
fbdev = to_au1100fb_device(fbi);
|
|
|
|
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- start = fbdev->fb_phys & PAGE_MASK;
|
|
- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
|
|
-
|
|
- off = vma->vm_pgoff << PAGE_SHIFT;
|
|
-
|
|
- if ((vma->vm_end - vma->vm_start + off) > len) {
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- off += start;
|
|
- vma->vm_pgoff = off >> PAGE_SHIFT;
|
|
-
|
|
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
|
pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
|
|
|
|
vma->vm_flags |= VM_IO;
|
|
|
|
- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
|
|
- vma->vm_end - vma->vm_start,
|
|
- vma->vm_page_prot)) {
|
|
- return -EAGAIN;
|
|
- }
|
|
-
|
|
- return 0;
|
|
+ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
|
|
}
|
|
|
|
static struct fb_ops au1100fb_ops =
|
|
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
|
|
index 7ca79f02056e..117be3d9b854 100644
|
|
--- a/drivers/video/au1200fb.c
|
|
+++ b/drivers/video/au1200fb.c
|
|
@@ -1233,36 +1233,15 @@ static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
|
|
* method mainly to allow the use of the TLB streaming flag (CCA=6)
|
|
*/
|
|
static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
|
-
|
|
{
|
|
- unsigned int len;
|
|
- unsigned long start=0, off;
|
|
struct au1200fb_device *fbdev = info->par;
|
|
|
|
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- start = fbdev->fb_phys & PAGE_MASK;
|
|
- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
|
|
-
|
|
- off = vma->vm_pgoff << PAGE_SHIFT;
|
|
-
|
|
- if ((vma->vm_end - vma->vm_start + off) > len) {
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- off += start;
|
|
- vma->vm_pgoff = off >> PAGE_SHIFT;
|
|
-
|
|
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
|
pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
|
|
|
|
vma->vm_flags |= VM_IO;
|
|
|
|
- return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
|
|
- vma->vm_end - vma->vm_start,
|
|
- vma->vm_page_prot);
|
|
+ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
|
|
index 7e6c52d8a207..c91f6d1bf64f 100644
|
|
--- a/fs/configfs/dir.c
|
|
+++ b/fs/configfs/dir.c
|
|
@@ -56,10 +56,19 @@ static void configfs_d_iput(struct dentry * dentry,
|
|
struct configfs_dirent *sd = dentry->d_fsdata;
|
|
|
|
if (sd) {
|
|
- BUG_ON(sd->s_dentry != dentry);
|
|
/* Coordinate with configfs_readdir */
|
|
spin_lock(&configfs_dirent_lock);
|
|
- sd->s_dentry = NULL;
|
|
+ /* Coordinate with configfs_attach_attr where will increase
|
|
+ * sd->s_count and update sd->s_dentry to new allocated one.
|
|
+ * Only set sd->dentry to null when this dentry is the only
|
|
+ * sd owner.
|
|
+ * If not do so, configfs_d_iput may run just after
|
|
+ * configfs_attach_attr and set sd->s_dentry to null
|
|
+ * even it's still in use.
|
|
+ */
|
|
+ if (atomic_read(&sd->s_count) <= 2)
|
|
+ sd->s_dentry = NULL;
|
|
+
|
|
spin_unlock(&configfs_dirent_lock);
|
|
configfs_put(sd);
|
|
}
|
|
@@ -426,8 +435,11 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
|
|
struct configfs_attribute * attr = sd->s_element;
|
|
int error;
|
|
|
|
+ spin_lock(&configfs_dirent_lock);
|
|
dentry->d_fsdata = configfs_get(sd);
|
|
sd->s_dentry = dentry;
|
|
+ spin_unlock(&configfs_dirent_lock);
|
|
+
|
|
error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG,
|
|
configfs_init_file);
|
|
if (error) {
|
|
diff --git a/fs/dcache.c b/fs/dcache.c
|
|
index 9d39de40909d..09e2eda55c57 100644
|
|
--- a/fs/dcache.c
|
|
+++ b/fs/dcache.c
|
|
@@ -2513,7 +2513,6 @@ static int prepend_path(const struct path *path,
|
|
bool slash = false;
|
|
int error = 0;
|
|
|
|
- br_read_lock(vfsmount_lock);
|
|
while (dentry != root->dentry || vfsmnt != root->mnt) {
|
|
struct dentry * parent;
|
|
|
|
@@ -2543,8 +2542,6 @@ static int prepend_path(const struct path *path,
|
|
if (!error && !slash)
|
|
error = prepend(buffer, buflen, "/", 1);
|
|
|
|
-out:
|
|
- br_read_unlock(vfsmount_lock);
|
|
return error;
|
|
|
|
global_root:
|
|
@@ -2561,7 +2558,7 @@ global_root:
|
|
error = prepend(buffer, buflen, "/", 1);
|
|
if (!error)
|
|
error = real_mount(vfsmnt)->mnt_ns ? 1 : 2;
|
|
- goto out;
|
|
+ return error;
|
|
}
|
|
|
|
/**
|
|
@@ -2588,9 +2585,11 @@ char *__d_path(const struct path *path,
|
|
int error;
|
|
|
|
prepend(&res, &buflen, "\0", 1);
|
|
+ br_read_lock(vfsmount_lock);
|
|
write_seqlock(&rename_lock);
|
|
error = prepend_path(path, root, &res, &buflen);
|
|
write_sequnlock(&rename_lock);
|
|
+ br_read_unlock(vfsmount_lock);
|
|
|
|
if (error < 0)
|
|
return ERR_PTR(error);
|
|
@@ -2607,9 +2606,11 @@ char *d_absolute_path(const struct path *path,
|
|
int error;
|
|
|
|
prepend(&res, &buflen, "\0", 1);
|
|
+ br_read_lock(vfsmount_lock);
|
|
write_seqlock(&rename_lock);
|
|
error = prepend_path(path, &root, &res, &buflen);
|
|
write_sequnlock(&rename_lock);
|
|
+ br_read_unlock(vfsmount_lock);
|
|
|
|
if (error > 1)
|
|
error = -EINVAL;
|
|
@@ -2673,11 +2674,13 @@ char *d_path(const struct path *path, char *buf, int buflen)
|
|
return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
|
|
|
|
get_fs_root(current->fs, &root);
|
|
+ br_read_lock(vfsmount_lock);
|
|
write_seqlock(&rename_lock);
|
|
error = path_with_deleted(path, &root, &res, &buflen);
|
|
+ write_sequnlock(&rename_lock);
|
|
+ br_read_unlock(vfsmount_lock);
|
|
if (error < 0)
|
|
res = ERR_PTR(error);
|
|
- write_sequnlock(&rename_lock);
|
|
path_put(&root);
|
|
return res;
|
|
}
|
|
@@ -2832,6 +2835,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|
get_fs_root_and_pwd(current->fs, &root, &pwd);
|
|
|
|
error = -ENOENT;
|
|
+ br_read_lock(vfsmount_lock);
|
|
write_seqlock(&rename_lock);
|
|
if (!d_unlinked(pwd.dentry)) {
|
|
unsigned long len;
|
|
@@ -2841,6 +2845,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|
prepend(&cwd, &buflen, "\0", 1);
|
|
error = prepend_path(&pwd, &root, &cwd, &buflen);
|
|
write_sequnlock(&rename_lock);
|
|
+ br_read_unlock(vfsmount_lock);
|
|
|
|
if (error < 0)
|
|
goto out;
|
|
@@ -2861,6 +2866,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|
}
|
|
} else {
|
|
write_sequnlock(&rename_lock);
|
|
+ br_read_unlock(vfsmount_lock);
|
|
}
|
|
|
|
out:
|
|
diff --git a/fs/exec.c b/fs/exec.c
|
|
index 0ea0b4c476d8..5b9dfbe84b19 100644
|
|
--- a/fs/exec.c
|
|
+++ b/fs/exec.c
|
|
@@ -909,11 +909,13 @@ static int de_thread(struct task_struct *tsk)
|
|
|
|
sig->notify_count = -1; /* for exit_notify() */
|
|
for (;;) {
|
|
+ threadgroup_change_begin(tsk);
|
|
write_lock_irq(&tasklist_lock);
|
|
if (likely(leader->exit_state))
|
|
break;
|
|
__set_current_state(TASK_UNINTERRUPTIBLE);
|
|
write_unlock_irq(&tasklist_lock);
|
|
+ threadgroup_change_end(tsk);
|
|
schedule();
|
|
}
|
|
|
|
@@ -969,6 +971,7 @@ static int de_thread(struct task_struct *tsk)
|
|
if (unlikely(leader->ptrace))
|
|
__wake_up_parent(leader, leader->parent);
|
|
write_unlock_irq(&tasklist_lock);
|
|
+ threadgroup_change_end(tsk);
|
|
|
|
release_task(leader);
|
|
}
|
|
@@ -2024,6 +2027,12 @@ static int __get_dumpable(unsigned long mm_flags)
|
|
return (ret >= 2) ? 2 : ret;
|
|
}
|
|
|
|
+/*
|
|
+ * This returns the actual value of the suid_dumpable flag. For things
|
|
+ * that are using this for checking for privilege transitions, it must
|
|
+ * test against SUID_DUMP_USER rather than treating it as a boolean
|
|
+ * value.
|
|
+ */
|
|
int get_dumpable(struct mm_struct *mm)
|
|
{
|
|
return __get_dumpable(mm->flags);
|
|
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
|
|
index edf411988bf3..9bb4e5c541b0 100644
|
|
--- a/fs/nfs/inode.c
|
|
+++ b/fs/nfs/inode.c
|
|
@@ -224,6 +224,8 @@ nfs_find_actor(struct inode *inode, void *opaque)
|
|
|
|
if (NFS_FILEID(inode) != fattr->fileid)
|
|
return 0;
|
|
+ if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode))
|
|
+ return 0;
|
|
if (nfs_compare_fh(NFS_FH(inode), fh))
|
|
return 0;
|
|
if (is_bad_inode(inode) || NFS_STALE(inode))
|
|
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
|
|
index a7a043d272da..51017baa67af 100644
|
|
--- a/fs/nfs/nfs3proc.c
|
|
+++ b/fs/nfs/nfs3proc.c
|
|
@@ -24,14 +24,14 @@
|
|
|
|
#define NFSDBG_FACILITY NFSDBG_PROC
|
|
|
|
-/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */
|
|
+/* A wrapper to handle the EJUKEBOX error messages */
|
|
static int
|
|
nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
|
{
|
|
int res;
|
|
do {
|
|
res = rpc_call_sync(clnt, msg, flags);
|
|
- if (res != -EJUKEBOX && res != -EKEYEXPIRED)
|
|
+ if (res != -EJUKEBOX)
|
|
break;
|
|
freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
|
res = -ERESTARTSYS;
|
|
@@ -44,7 +44,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
|
static int
|
|
nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
|
|
{
|
|
- if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED)
|
|
+ if (task->tk_status != -EJUKEBOX)
|
|
return 0;
|
|
if (task->tk_status == -EJUKEBOX)
|
|
nfs_inc_stats(inode, NFSIOS_DELAY);
|
|
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
|
|
index 5acfd9ea8a31..4d64d5b85e56 100644
|
|
--- a/fs/nfs/nfs4filelayout.c
|
|
+++ b/fs/nfs/nfs4filelayout.c
|
|
@@ -122,7 +122,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
|
|
break;
|
|
case -NFS4ERR_DELAY:
|
|
case -NFS4ERR_GRACE:
|
|
- case -EKEYEXPIRED:
|
|
rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX);
|
|
break;
|
|
case -NFS4ERR_RETRY_UNCACHED_REP:
|
|
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
|
index d121c67f87d0..cabddb5da071 100644
|
|
--- a/fs/nfs/nfs4proc.c
|
|
+++ b/fs/nfs/nfs4proc.c
|
|
@@ -319,7 +319,6 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
|
|
}
|
|
case -NFS4ERR_GRACE:
|
|
case -NFS4ERR_DELAY:
|
|
- case -EKEYEXPIRED:
|
|
ret = nfs4_delay(server->client, &exception->timeout);
|
|
if (ret != 0)
|
|
break;
|
|
@@ -1352,13 +1351,6 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
|
|
nfs_inode_find_state_and_recover(state->inode,
|
|
stateid);
|
|
nfs4_schedule_stateid_recovery(server, state);
|
|
- case -EKEYEXPIRED:
|
|
- /*
|
|
- * User RPCSEC_GSS context has expired.
|
|
- * We cannot recover this stateid now, so
|
|
- * skip it and allow recovery thread to
|
|
- * proceed.
|
|
- */
|
|
case -ENOMEM:
|
|
err = 0;
|
|
goto out;
|
|
@@ -3924,7 +3916,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
|
|
case -NFS4ERR_DELAY:
|
|
nfs_inc_server_stats(server, NFSIOS_DELAY);
|
|
case -NFS4ERR_GRACE:
|
|
- case -EKEYEXPIRED:
|
|
rpc_delay(task, NFS4_POLL_RETRY_MAX);
|
|
task->tk_status = 0;
|
|
return -EAGAIN;
|
|
@@ -4216,6 +4207,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
|
|
status = 0;
|
|
}
|
|
request->fl_ops->fl_release_private(request);
|
|
+ request->fl_ops = NULL;
|
|
out:
|
|
return status;
|
|
}
|
|
@@ -4871,15 +4863,6 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
|
|
nfs4_schedule_stateid_recovery(server, state);
|
|
err = 0;
|
|
goto out;
|
|
- case -EKEYEXPIRED:
|
|
- /*
|
|
- * User RPCSEC_GSS context has expired.
|
|
- * We cannot recover this stateid now, so
|
|
- * skip it and allow recovery thread to
|
|
- * proceed.
|
|
- */
|
|
- err = 0;
|
|
- goto out;
|
|
case -ENOMEM:
|
|
case -NFS4ERR_DENIED:
|
|
/* kill_proc(fl->fl_pid, SIGLOST, 1); */
|
|
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
|
|
index 7f0fcfc1fe9d..e46579471ccc 100644
|
|
--- a/fs/nfs/nfs4state.c
|
|
+++ b/fs/nfs/nfs4state.c
|
|
@@ -1298,14 +1298,6 @@ restart:
|
|
/* Mark the file as being 'closed' */
|
|
state->state = 0;
|
|
break;
|
|
- case -EKEYEXPIRED:
|
|
- /*
|
|
- * User RPCSEC_GSS context has expired.
|
|
- * We cannot recover this stateid now, so
|
|
- * skip it and allow recovery thread to
|
|
- * proceed.
|
|
- */
|
|
- break;
|
|
case -NFS4ERR_ADMIN_REVOKED:
|
|
case -NFS4ERR_STALE_STATEID:
|
|
case -NFS4ERR_BAD_STATEID:
|
|
@@ -1458,14 +1450,6 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp)
|
|
nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce);
|
|
}
|
|
|
|
-static void nfs4_warn_keyexpired(const char *s)
|
|
-{
|
|
- printk_ratelimited(KERN_WARNING "Error: state manager"
|
|
- " encountered RPCSEC_GSS session"
|
|
- " expired against NFSv4 server %s.\n",
|
|
- s);
|
|
-}
|
|
-
|
|
static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
|
|
{
|
|
switch (error) {
|
|
@@ -1497,10 +1481,6 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
|
|
set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
|
|
/* Zero session reset errors */
|
|
break;
|
|
- case -EKEYEXPIRED:
|
|
- /* Nothing we can do */
|
|
- nfs4_warn_keyexpired(clp->cl_hostname);
|
|
- break;
|
|
default:
|
|
return error;
|
|
}
|
|
@@ -1745,7 +1725,6 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
|
|
break;
|
|
|
|
case -EKEYEXPIRED:
|
|
- nfs4_warn_keyexpired(clp->cl_hostname);
|
|
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
|
|
* in nfs4_exchange_id */
|
|
default:
|
|
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
|
|
index b63b6f4d14fb..af9947e35fcb 100644
|
|
--- a/fs/nfs/proc.c
|
|
+++ b/fs/nfs/proc.c
|
|
@@ -47,39 +47,6 @@
|
|
#define NFSDBG_FACILITY NFSDBG_PROC
|
|
|
|
/*
|
|
- * wrapper to handle the -EKEYEXPIRED error message. This should generally
|
|
- * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't
|
|
- * support the NFSERR_JUKEBOX error code, but we handle this situation in the
|
|
- * same way that we handle that error with NFSv3.
|
|
- */
|
|
-static int
|
|
-nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
|
-{
|
|
- int res;
|
|
- do {
|
|
- res = rpc_call_sync(clnt, msg, flags);
|
|
- if (res != -EKEYEXPIRED)
|
|
- break;
|
|
- freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
|
- res = -ERESTARTSYS;
|
|
- } while (!fatal_signal_pending(current));
|
|
- return res;
|
|
-}
|
|
-
|
|
-#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags)
|
|
-
|
|
-static int
|
|
-nfs_async_handle_expired_key(struct rpc_task *task)
|
|
-{
|
|
- if (task->tk_status != -EKEYEXPIRED)
|
|
- return 0;
|
|
- task->tk_status = 0;
|
|
- rpc_restart_call(task);
|
|
- rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
|
|
- return 1;
|
|
-}
|
|
-
|
|
-/*
|
|
* Bare-bones access to getattr: this is for nfs_read_super.
|
|
*/
|
|
static int
|
|
@@ -365,8 +332,6 @@ static void nfs_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlink
|
|
|
|
static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
|
|
{
|
|
- if (nfs_async_handle_expired_key(task))
|
|
- return 0;
|
|
nfs_mark_for_revalidate(dir);
|
|
return 1;
|
|
}
|
|
@@ -386,8 +351,6 @@ static int
|
|
nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
|
|
struct inode *new_dir)
|
|
{
|
|
- if (nfs_async_handle_expired_key(task))
|
|
- return 0;
|
|
nfs_mark_for_revalidate(old_dir);
|
|
nfs_mark_for_revalidate(new_dir);
|
|
return 1;
|
|
@@ -641,9 +604,6 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
|
|
|
|
static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
|
|
{
|
|
- if (nfs_async_handle_expired_key(task))
|
|
- return -EAGAIN;
|
|
-
|
|
nfs_invalidate_atime(data->inode);
|
|
if (task->tk_status >= 0) {
|
|
nfs_refresh_inode(data->inode, data->res.fattr);
|
|
@@ -668,9 +628,6 @@ static void nfs_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_dat
|
|
|
|
static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
|
|
{
|
|
- if (nfs_async_handle_expired_key(task))
|
|
- return -EAGAIN;
|
|
-
|
|
if (task->tk_status >= 0)
|
|
nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
|
|
return 0;
|
|
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
|
|
index f03160106b95..026a873e3f6c 100644
|
|
--- a/fs/nfsd/vfs.c
|
|
+++ b/fs/nfsd/vfs.c
|
|
@@ -297,41 +297,12 @@ commit_metadata(struct svc_fh *fhp)
|
|
}
|
|
|
|
/*
|
|
- * Set various file attributes.
|
|
- * N.B. After this call fhp needs an fh_put
|
|
+ * Go over the attributes and take care of the small differences between
|
|
+ * NFS semantics and what Linux expects.
|
|
*/
|
|
-__be32
|
|
-nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|
- int check_guard, time_t guardtime)
|
|
+static void
|
|
+nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
|
|
{
|
|
- struct dentry *dentry;
|
|
- struct inode *inode;
|
|
- int accmode = NFSD_MAY_SATTR;
|
|
- umode_t ftype = 0;
|
|
- __be32 err;
|
|
- int host_err;
|
|
- int size_change = 0;
|
|
-
|
|
- if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
|
|
- accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
|
|
- if (iap->ia_valid & ATTR_SIZE)
|
|
- ftype = S_IFREG;
|
|
-
|
|
- /* Get inode */
|
|
- err = fh_verify(rqstp, fhp, ftype, accmode);
|
|
- if (err)
|
|
- goto out;
|
|
-
|
|
- dentry = fhp->fh_dentry;
|
|
- inode = dentry->d_inode;
|
|
-
|
|
- /* Ignore any mode updates on symlinks */
|
|
- if (S_ISLNK(inode->i_mode))
|
|
- iap->ia_valid &= ~ATTR_MODE;
|
|
-
|
|
- if (!iap->ia_valid)
|
|
- goto out;
|
|
-
|
|
/*
|
|
* NFSv2 does not differentiate between "set-[ac]time-to-now"
|
|
* which only requires access, and "set-[ac]time-to-X" which
|
|
@@ -341,8 +312,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|
* convert to "set to now" instead of "set to explicit time"
|
|
*
|
|
* We only call inode_change_ok as the last test as technically
|
|
- * it is not an interface that we should be using. It is only
|
|
- * valid if the filesystem does not define it's own i_op->setattr.
|
|
+ * it is not an interface that we should be using.
|
|
*/
|
|
#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
|
|
#define MAX_TOUCH_TIME_ERROR (30*60)
|
|
@@ -368,30 +338,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|
iap->ia_valid &= ~BOTH_TIME_SET;
|
|
}
|
|
}
|
|
-
|
|
- /*
|
|
- * The size case is special.
|
|
- * It changes the file as well as the attributes.
|
|
- */
|
|
- if (iap->ia_valid & ATTR_SIZE) {
|
|
- if (iap->ia_size < inode->i_size) {
|
|
- err = nfsd_permission(rqstp, fhp->fh_export, dentry,
|
|
- NFSD_MAY_TRUNC|NFSD_MAY_OWNER_OVERRIDE);
|
|
- if (err)
|
|
- goto out;
|
|
- }
|
|
-
|
|
- host_err = get_write_access(inode);
|
|
- if (host_err)
|
|
- goto out_nfserr;
|
|
-
|
|
- size_change = 1;
|
|
- host_err = locks_verify_truncate(inode, NULL, iap->ia_size);
|
|
- if (host_err) {
|
|
- put_write_access(inode);
|
|
- goto out_nfserr;
|
|
- }
|
|
- }
|
|
|
|
/* sanitize the mode change */
|
|
if (iap->ia_valid & ATTR_MODE) {
|
|
@@ -414,32 +360,111 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|
iap->ia_valid |= (ATTR_KILL_SUID | ATTR_KILL_SGID);
|
|
}
|
|
}
|
|
+}
|
|
|
|
- /* Change the attributes. */
|
|
+static __be32
|
|
+nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|
+ struct iattr *iap)
|
|
+{
|
|
+ struct inode *inode = fhp->fh_dentry->d_inode;
|
|
+ int host_err;
|
|
|
|
- iap->ia_valid |= ATTR_CTIME;
|
|
+ if (iap->ia_size < inode->i_size) {
|
|
+ __be32 err;
|
|
|
|
- err = nfserr_notsync;
|
|
- if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
|
|
- host_err = nfsd_break_lease(inode);
|
|
- if (host_err)
|
|
- goto out_nfserr;
|
|
- fh_lock(fhp);
|
|
+ err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry,
|
|
+ NFSD_MAY_TRUNC | NFSD_MAY_OWNER_OVERRIDE);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
|
|
- host_err = notify_change(dentry, iap);
|
|
- err = nfserrno(host_err);
|
|
- fh_unlock(fhp);
|
|
+ host_err = get_write_access(inode);
|
|
+ if (host_err)
|
|
+ goto out_nfserrno;
|
|
+
|
|
+ host_err = locks_verify_truncate(inode, NULL, iap->ia_size);
|
|
+ if (host_err)
|
|
+ goto out_put_write_access;
|
|
+ return 0;
|
|
+
|
|
+out_put_write_access:
|
|
+ put_write_access(inode);
|
|
+out_nfserrno:
|
|
+ return nfserrno(host_err);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Set various file attributes. After this call fhp needs an fh_put.
|
|
+ */
|
|
+__be32
|
|
+nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|
+ int check_guard, time_t guardtime)
|
|
+{
|
|
+ struct dentry *dentry;
|
|
+ struct inode *inode;
|
|
+ int accmode = NFSD_MAY_SATTR;
|
|
+ umode_t ftype = 0;
|
|
+ __be32 err;
|
|
+ int host_err;
|
|
+ int size_change = 0;
|
|
+
|
|
+ if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
|
|
+ accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
|
|
+ if (iap->ia_valid & ATTR_SIZE)
|
|
+ ftype = S_IFREG;
|
|
+
|
|
+ /* Get inode */
|
|
+ err = fh_verify(rqstp, fhp, ftype, accmode);
|
|
+ if (err)
|
|
+ goto out;
|
|
+
|
|
+ dentry = fhp->fh_dentry;
|
|
+ inode = dentry->d_inode;
|
|
+
|
|
+ /* Ignore any mode updates on symlinks */
|
|
+ if (S_ISLNK(inode->i_mode))
|
|
+ iap->ia_valid &= ~ATTR_MODE;
|
|
+
|
|
+ if (!iap->ia_valid)
|
|
+ goto out;
|
|
+
|
|
+ nfsd_sanitize_attrs(inode, iap);
|
|
+
|
|
+ /*
|
|
+ * The size case is special, it changes the file in addition to the
|
|
+ * attributes.
|
|
+ */
|
|
+ if (iap->ia_valid & ATTR_SIZE) {
|
|
+ err = nfsd_get_write_access(rqstp, fhp, iap);
|
|
+ if (err)
|
|
+ goto out;
|
|
+ size_change = 1;
|
|
}
|
|
+
|
|
+ iap->ia_valid |= ATTR_CTIME;
|
|
+
|
|
+ if (check_guard && guardtime != inode->i_ctime.tv_sec) {
|
|
+ err = nfserr_notsync;
|
|
+ goto out_put_write_access;
|
|
+ }
|
|
+
|
|
+ host_err = nfsd_break_lease(inode);
|
|
+ if (host_err)
|
|
+ goto out_put_write_access_nfserror;
|
|
+
|
|
+ fh_lock(fhp);
|
|
+ host_err = notify_change(dentry, iap);
|
|
+ fh_unlock(fhp);
|
|
+
|
|
+out_put_write_access_nfserror:
|
|
+ err = nfserrno(host_err);
|
|
+out_put_write_access:
|
|
if (size_change)
|
|
put_write_access(inode);
|
|
if (!err)
|
|
commit_metadata(fhp);
|
|
out:
|
|
return err;
|
|
-
|
|
-out_nfserr:
|
|
- err = nfserrno(host_err);
|
|
- goto out;
|
|
}
|
|
|
|
#if defined(CONFIG_NFSD_V2_ACL) || \
|
|
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
|
|
index 205c92280838..6c61f119f608 100644
|
|
--- a/fs/proc/inode.c
|
|
+++ b/fs/proc/inode.c
|
|
@@ -443,12 +443,10 @@ static const struct file_operations proc_reg_file_ops_no_compat = {
|
|
|
|
struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
|
|
{
|
|
- struct inode * inode;
|
|
+ struct inode *inode = new_inode_pseudo(sb);
|
|
|
|
- inode = iget_locked(sb, de->low_ino);
|
|
- if (!inode)
|
|
- return NULL;
|
|
- if (inode->i_state & I_NEW) {
|
|
+ if (inode) {
|
|
+ inode->i_ino = de->low_ino;
|
|
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
|
PROC_I(inode)->fd = 0;
|
|
PROC_I(inode)->pde = de;
|
|
@@ -477,9 +475,7 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
|
|
inode->i_fop = de->proc_fops;
|
|
}
|
|
}
|
|
- unlock_new_inode(inode);
|
|
- } else
|
|
- pde_put(de);
|
|
+ }
|
|
return inode;
|
|
}
|
|
|
|
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
|
|
index 5bab59b1034e..424b381c96f1 100644
|
|
--- a/include/linux/binfmts.h
|
|
+++ b/include/linux/binfmts.h
|
|
@@ -113,9 +113,6 @@ extern void setup_new_exec(struct linux_binprm * bprm);
|
|
extern void would_dump(struct linux_binprm *, struct file *);
|
|
|
|
extern int suid_dumpable;
|
|
-#define SUID_DUMP_DISABLE 0 /* No setuid dumping */
|
|
-#define SUID_DUMP_USER 1 /* Dump as user of process */
|
|
-#define SUID_DUMP_ROOT 2 /* Dump as root */
|
|
|
|
/* Stack area protections */
|
|
#define EXSTACK_DEFAULT 0 /* Whatever the arch defaults to */
|
|
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
|
index 25c40b9f848a..210c347425e8 100644
|
|
--- a/include/linux/fs.h
|
|
+++ b/include/linux/fs.h
|
|
@@ -915,9 +915,11 @@ static inline loff_t i_size_read(const struct inode *inode)
|
|
static inline void i_size_write(struct inode *inode, loff_t i_size)
|
|
{
|
|
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
|
|
+ preempt_disable();
|
|
write_seqcount_begin(&inode->i_size_seqcount);
|
|
inode->i_size = i_size;
|
|
write_seqcount_end(&inode->i_size_seqcount);
|
|
+ preempt_enable();
|
|
#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT)
|
|
preempt_disable();
|
|
inode->i_size = i_size;
|
|
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
|
index 3dd0efbb70f2..e132a2d24740 100644
|
|
--- a/include/linux/sched.h
|
|
+++ b/include/linux/sched.h
|
|
@@ -404,6 +404,10 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
|
|
extern void set_dumpable(struct mm_struct *mm, int value);
|
|
extern int get_dumpable(struct mm_struct *mm);
|
|
|
|
+#define SUID_DUMP_DISABLE 0 /* No setuid dumping */
|
|
+#define SUID_DUMP_USER 1 /* Dump as user of process */
|
|
+#define SUID_DUMP_ROOT 2 /* Dump as root */
|
|
+
|
|
/* mm flags */
|
|
/* dumpable bits */
|
|
#define MMF_DUMPABLE 0 /* core dump is permitted */
|
|
@@ -2466,27 +2470,18 @@ static inline void threadgroup_change_end(struct task_struct *tsk)
|
|
*
|
|
* Lock the threadgroup @tsk belongs to. No new task is allowed to enter
|
|
* and member tasks aren't allowed to exit (as indicated by PF_EXITING) or
|
|
- * perform exec. This is useful for cases where the threadgroup needs to
|
|
- * stay stable across blockable operations.
|
|
+ * change ->group_leader/pid. This is useful for cases where the threadgroup
|
|
+ * needs to stay stable across blockable operations.
|
|
*
|
|
* fork and exit paths explicitly call threadgroup_change_{begin|end}() for
|
|
* synchronization. While held, no new task will be added to threadgroup
|
|
* and no existing live task will have its PF_EXITING set.
|
|
*
|
|
- * During exec, a task goes and puts its thread group through unusual
|
|
- * changes. After de-threading, exclusive access is assumed to resources
|
|
- * which are usually shared by tasks in the same group - e.g. sighand may
|
|
- * be replaced with a new one. Also, the exec'ing task takes over group
|
|
- * leader role including its pid. Exclude these changes while locked by
|
|
- * grabbing cred_guard_mutex which is used to synchronize exec path.
|
|
+ * de_thread() does threadgroup_change_{begin|end}() when a non-leader
|
|
+ * sub-thread becomes a new leader.
|
|
*/
|
|
static inline void threadgroup_lock(struct task_struct *tsk)
|
|
{
|
|
- /*
|
|
- * exec uses exit for de-threading nesting group_rwsem inside
|
|
- * cred_guard_mutex. Grab cred_guard_mutex first.
|
|
- */
|
|
- mutex_lock(&tsk->signal->cred_guard_mutex);
|
|
down_write(&tsk->signal->group_rwsem);
|
|
}
|
|
|
|
@@ -2499,7 +2494,6 @@ static inline void threadgroup_lock(struct task_struct *tsk)
|
|
static inline void threadgroup_unlock(struct task_struct *tsk)
|
|
{
|
|
up_write(&tsk->signal->group_rwsem);
|
|
- mutex_unlock(&tsk->signal->cred_guard_mutex);
|
|
}
|
|
#else
|
|
static inline void threadgroup_change_begin(struct task_struct *tsk) {}
|
|
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
|
index daf4394d1aba..a1432369be50 100644
|
|
--- a/kernel/ptrace.c
|
|
+++ b/kernel/ptrace.c
|
|
@@ -254,7 +254,8 @@ ok:
|
|
smp_rmb();
|
|
if (task->mm)
|
|
dumpable = get_dumpable(task->mm);
|
|
- if (!dumpable && !ptrace_has_cap(task_user_ns(task), mode))
|
|
+ if (dumpable != SUID_DUMP_USER &&
|
|
+ !ptrace_has_cap(task_user_ns(task), mode))
|
|
return -EPERM;
|
|
|
|
return security_ptrace_access_check(task, mode);
|
|
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
|
|
index fee3752ae8f6..d01adb77449c 100644
|
|
--- a/kernel/trace/trace_event_perf.c
|
|
+++ b/kernel/trace/trace_event_perf.c
|
|
@@ -26,7 +26,7 @@ static int perf_trace_event_perm(struct ftrace_event_call *tp_event,
|
|
{
|
|
/* The ftrace function trace is allowed only for root. */
|
|
if (ftrace_event_is_function(tp_event) &&
|
|
- perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
|
|
+ perf_paranoid_tracepoint_raw() && !capable(CAP_SYS_ADMIN))
|
|
return -EPERM;
|
|
|
|
/* No tracing, just counting, so no obvious leak */
|
|
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
|
|
index a28a2111297e..f21486a2ac48 100644
|
|
--- a/net/sunrpc/clnt.c
|
|
+++ b/net/sunrpc/clnt.c
|
|
@@ -1338,6 +1338,7 @@ call_refreshresult(struct rpc_task *task)
|
|
rpc_delay(task, 3*HZ);
|
|
case -EAGAIN:
|
|
status = -EACCES;
|
|
+ case -EKEYEXPIRED:
|
|
if (!task->tk_cred_retry)
|
|
break;
|
|
task->tk_cred_retry--;
|
|
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
|
|
index 79064471cd01..31f981d700a3 100644
|
|
--- a/net/sunrpc/xprtsock.c
|
|
+++ b/net/sunrpc/xprtsock.c
|
|
@@ -390,8 +390,10 @@ static int xs_send_kvec(struct socket *sock, struct sockaddr *addr, int addrlen,
|
|
return kernel_sendmsg(sock, &msg, NULL, 0, 0);
|
|
}
|
|
|
|
-static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more)
|
|
+static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more, bool zerocopy)
|
|
{
|
|
+ ssize_t (*do_sendpage)(struct socket *sock, struct page *page,
|
|
+ int offset, size_t size, int flags);
|
|
struct page **ppage;
|
|
unsigned int remainder;
|
|
int err, sent = 0;
|
|
@@ -400,6 +402,9 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i
|
|
base += xdr->page_base;
|
|
ppage = xdr->pages + (base >> PAGE_SHIFT);
|
|
base &= ~PAGE_MASK;
|
|
+ do_sendpage = sock->ops->sendpage;
|
|
+ if (!zerocopy)
|
|
+ do_sendpage = sock_no_sendpage;
|
|
for(;;) {
|
|
unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder);
|
|
int flags = XS_SENDMSG_FLAGS;
|
|
@@ -407,7 +412,7 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i
|
|
remainder -= len;
|
|
if (remainder != 0 || more)
|
|
flags |= MSG_MORE;
|
|
- err = sock->ops->sendpage(sock, *ppage, base, len, flags);
|
|
+ err = do_sendpage(sock, *ppage, base, len, flags);
|
|
if (remainder == 0 || err != len)
|
|
break;
|
|
sent += err;
|
|
@@ -428,9 +433,10 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i
|
|
* @addrlen: UDP only -- length of destination address
|
|
* @xdr: buffer containing this request
|
|
* @base: starting position in the buffer
|
|
+ * @zerocopy: true if it is safe to use sendpage()
|
|
*
|
|
*/
|
|
-static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
|
|
+static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, bool zerocopy)
|
|
{
|
|
unsigned int remainder = xdr->len - base;
|
|
int err, sent = 0;
|
|
@@ -458,7 +464,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
|
|
if (base < xdr->page_len) {
|
|
unsigned int len = xdr->page_len - base;
|
|
remainder -= len;
|
|
- err = xs_send_pagedata(sock, xdr, base, remainder != 0);
|
|
+ err = xs_send_pagedata(sock, xdr, base, remainder != 0, zerocopy);
|
|
if (remainder == 0 || err != len)
|
|
goto out;
|
|
sent += err;
|
|
@@ -561,7 +567,7 @@ static int xs_local_send_request(struct rpc_task *task)
|
|
req->rq_svec->iov_base, req->rq_svec->iov_len);
|
|
|
|
status = xs_sendpages(transport->sock, NULL, 0,
|
|
- xdr, req->rq_bytes_sent);
|
|
+ xdr, req->rq_bytes_sent, true);
|
|
dprintk("RPC: %s(%u) = %d\n",
|
|
__func__, xdr->len - req->rq_bytes_sent, status);
|
|
if (likely(status >= 0)) {
|
|
@@ -617,7 +623,7 @@ static int xs_udp_send_request(struct rpc_task *task)
|
|
status = xs_sendpages(transport->sock,
|
|
xs_addr(xprt),
|
|
xprt->addrlen, xdr,
|
|
- req->rq_bytes_sent);
|
|
+ req->rq_bytes_sent, true);
|
|
|
|
dprintk("RPC: xs_udp_send_request(%u) = %d\n",
|
|
xdr->len - req->rq_bytes_sent, status);
|
|
@@ -688,6 +694,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
|
|
struct rpc_xprt *xprt = req->rq_xprt;
|
|
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
struct xdr_buf *xdr = &req->rq_snd_buf;
|
|
+ bool zerocopy = true;
|
|
int status;
|
|
|
|
xs_encode_stream_record_marker(&req->rq_snd_buf);
|
|
@@ -695,13 +702,20 @@ static int xs_tcp_send_request(struct rpc_task *task)
|
|
xs_pktdump("packet data:",
|
|
req->rq_svec->iov_base,
|
|
req->rq_svec->iov_len);
|
|
+ /* Don't use zero copy if this is a resend. If the RPC call
|
|
+ * completes while the socket holds a reference to the pages,
|
|
+ * then we may end up resending corrupted data.
|
|
+ */
|
|
+ if (task->tk_flags & RPC_TASK_SENT)
|
|
+ zerocopy = false;
|
|
|
|
/* Continue transmitting the packet/record. We must be careful
|
|
* to cope with writespace callbacks arriving _after_ we have
|
|
* called sendmsg(). */
|
|
while (1) {
|
|
status = xs_sendpages(transport->sock,
|
|
- NULL, 0, xdr, req->rq_bytes_sent);
|
|
+ NULL, 0, xdr, req->rq_bytes_sent,
|
|
+ zerocopy);
|
|
|
|
dprintk("RPC: xs_tcp_send_request(%u) = %d\n",
|
|
xdr->len - req->rq_bytes_sent, status);
|
|
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
|
|
index d8edff209bf3..d6aab27c8584 100644
|
|
--- a/security/integrity/ima/ima_policy.c
|
|
+++ b/security/integrity/ima/ima_policy.c
|
|
@@ -62,7 +62,6 @@ static struct ima_measure_rule_entry default_rules[] = {
|
|
{.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
|
|
{.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
|
|
{.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
|
|
- {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
|
|
{.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
|
|
{.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
|
|
{.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
|
|
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
|
|
index 29cc8e162b02..a7d6a52a4f81 100644
|
|
--- a/sound/isa/msnd/msnd_pinnacle.c
|
|
+++ b/sound/isa/msnd/msnd_pinnacle.c
|
|
@@ -73,9 +73,11 @@
|
|
#ifdef MSND_CLASSIC
|
|
# include "msnd_classic.h"
|
|
# define LOGNAME "msnd_classic"
|
|
+# define DEV_NAME "msnd-classic"
|
|
#else
|
|
# include "msnd_pinnacle.h"
|
|
# define LOGNAME "snd_msnd_pinnacle"
|
|
+# define DEV_NAME "msnd-pinnacle"
|
|
#endif
|
|
|
|
static void __devinit set_default_audio_parameters(struct snd_msnd *chip)
|
|
@@ -1068,8 +1070,6 @@ static int __devexit snd_msnd_isa_remove(struct device *pdev, unsigned int dev)
|
|
return 0;
|
|
}
|
|
|
|
-#define DEV_NAME "msnd-pinnacle"
|
|
-
|
|
static struct isa_driver snd_msnd_driver = {
|
|
.match = snd_msnd_isa_match,
|
|
.probe = snd_msnd_isa_probe,
|
|
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
|
|
index fc8cc823e438..f8033485db93 100644
|
|
--- a/sound/usb/6fire/chip.c
|
|
+++ b/sound/usb/6fire/chip.c
|
|
@@ -101,7 +101,7 @@ static int __devinit usb6fire_chip_probe(struct usb_interface *intf,
|
|
usb_set_intfdata(intf, chips[i]);
|
|
mutex_unlock(®ister_mutex);
|
|
return 0;
|
|
- } else if (regidx < 0)
|
|
+ } else if (!devices[i] && regidx < 0)
|
|
regidx = i;
|
|
}
|
|
if (regidx < 0) {
|