Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/825/?format=api
{ "id": 825, "url": "http://patchwork.ozlabs.org/api/patches/825/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1222068117-13401-4-git-send-email-gerrit@erg.abdn.ac.uk/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api", "name": "Linux network development", "link_name": "netdev", "list_id": "netdev.vger.kernel.org", "list_email": "netdev@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1222068117-13401-4-git-send-email-gerrit@erg.abdn.ac.uk>", "list_archive_url": null, "date": "2008-09-22T07:21:55", "name": "[3/5] dccp: List management for new feature negotiation", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": true, "hash": "0bdada0180d3208412ae6dedb0ebcb133d76f952", "submitter": { "id": 386, "url": "http://patchwork.ozlabs.org/api/people/386/?format=api", "name": "Gerrit Renker", "email": "gerrit@erg.abdn.ac.uk" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1222068117-13401-4-git-send-email-gerrit@erg.abdn.ac.uk/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/825/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/825/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.176.167])\n\tby ozlabs.org (Postfix) with ESMTP id 79BFCDDDF5\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon, 22 Sep 2008 17:22:26 +1000 (EST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750950AbYIVHWS (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 22 Sep 2008 03:22:18 -0400", "(majordomo@vger.kernel.org) by vger.kernel.org id S1751695AbYIVHWR\n\t(ORCPT <rfc822; netdev-outgoing>); Mon, 22 Sep 2008 03:22:17 -0400", "from dee.erg.abdn.ac.uk ([139.133.204.82]:40415 \"EHLO\n\terg.abdn.ac.uk\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1751165AbYIVHWM (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tMon, 22 Sep 2008 03:22:12 -0400", "from laptev.erg.abdn.ac.uk (Debian-exim@ra-gerrit.erg.abdn.ac.uk\n\t[139.133.204.38])\n\tby erg.abdn.ac.uk (8.13.4/8.13.4) with ESMTP id m8M7LvcG000578\n\t(version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT);\n\tMon, 22 Sep 2008 08:21:58 +0100 (BST)", "from root by laptev.erg.abdn.ac.uk with local (Exim 4.69)\n\t(envelope-from <root@laptev.erg.abdn.ac.uk>)\n\tid 1Khfk5-0003Uj-3u; Mon, 22 Sep 2008 09:21:57 +0200" ], "From": "Gerrit Renker <gerrit@erg.abdn.ac.uk>", "To": "davem@davemloft.net", "Cc": "dccp@vger.kernel.org, netdev@vger.kernel.org,\n\tGerrit Renker <gerrit@erg.abdn.ac.uk>", "Subject": "[PATCH 3/5] dccp: List management for new feature negotiation", "Date": "Mon, 22 Sep 2008 09:21:55 +0200", "Message-Id": "<1222068117-13401-4-git-send-email-gerrit@erg.abdn.ac.uk>", "X-Mailer": "git-send-email 1.6.0.rc2", "In-Reply-To": "<1222068117-13401-3-git-send-email-gerrit@erg.abdn.ac.uk>", "References": "<20080921.235853.223987556.davem@davemloft.net>\n\t<1222068117-13401-1-git-send-email-gerrit@erg.abdn.ac.uk>\n\t<1222068117-13401-2-git-send-email-gerrit@erg.abdn.ac.uk>\n\t<1222068117-13401-3-git-send-email-gerrit@erg.abdn.ac.uk>", "X-ERG-MailScanner": "Found to be clean", "X-ERG-MailScanner-From": "root@erg.abdn.ac.uk", "X-Spam-Status": "No", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "This adds list fields and list management functions for the new feature\nnegotiation implementation. The new code is kept in parallel to the old\ncode, until removed at the end of the patch set.\n\nThanks to Arnaldo for suggestions to improve the code.\n\nSigned-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>\nAcked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>\n---\n net/dccp/feat.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 129 insertions(+), 0 deletions(-)\n\n--\nTo unsubscribe from this list: send the line \"unsubscribe netdev\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at http://vger.kernel.org/majordomo-info.html", "diff": "--- a/net/dccp/feat.c\n+++ b/net/dccp/feat.c\n@@ -150,6 +150,135 @@ static void dccp_feat_entry_destructor(struct dccp_feat_entry *entry)\n \t}\n }\n \n+/*\n+ * List management functions\n+ *\n+ * Feature negotiation lists rely on and maintain the following invariants:\n+ * - each feat_num in the list is known, i.e. we know its type and default value\n+ * - each feat_num/is_local combination is unique (old entries are overwritten)\n+ * - SP values are always freshly allocated\n+ * - list is sorted in increasing order of feature number (faster lookup)\n+ */\n+static struct dccp_feat_entry *dccp_feat_list_lookup(struct list_head *fn_list,\n+\t\t\t\t\t\t u8 feat_num, bool is_local)\n+{\n+\tstruct dccp_feat_entry *entry;\n+\n+\tlist_for_each_entry(entry, fn_list, node)\n+\t\tif (entry->feat_num == feat_num && entry->is_local == is_local)\n+\t\t\treturn entry;\n+\t\telse if (entry->feat_num > feat_num)\n+\t\t\tbreak;\n+\treturn NULL;\n+}\n+\n+/**\n+ * dccp_feat_entry_new - Central list update routine (called by all others)\n+ * @head: list to add to\n+ * @feat: feature number\n+ * @local: whether the local (1) or remote feature with number @feat is meant\n+ * This is the only constructor and serves to ensure the above invariants.\n+ */\n+static struct dccp_feat_entry *\n+\t dccp_feat_entry_new(struct list_head *head, u8 feat, bool local)\n+{\n+\tstruct dccp_feat_entry *entry;\n+\n+\tlist_for_each_entry(entry, head, node)\n+\t\tif (entry->feat_num == feat && entry->is_local == local) {\n+\t\t\tdccp_feat_val_destructor(entry->feat_num, &entry->val);\n+\t\t\treturn entry;\n+\t\t} else if (entry->feat_num > feat) {\n+\t\t\thead = &entry->node;\n+\t\t\tbreak;\n+\t\t}\n+\n+\tentry = kmalloc(sizeof(*entry), gfp_any());\n+\tif (entry != NULL) {\n+\t\tentry->feat_num = feat;\n+\t\tentry->is_local = local;\n+\t\tlist_add_tail(&entry->node, head);\n+\t}\n+\treturn entry;\n+}\n+\n+/**\n+ * dccp_feat_push_change - Add/overwrite a Change option in the list\n+ * @fn_list: feature-negotiation list to update\n+ * @feat: one of %dccp_feature_numbers\n+ * @local: whether local (1) or remote (0) @feat_num is meant\n+ * @needs_mandatory: whether to use Mandatory feature negotiation options\n+ * @fval: pointer to NN/SP value to be inserted (will be copied)\n+ */\n+static int dccp_feat_push_change(struct list_head *fn_list, u8 feat, u8 local,\n+\t\t\t\t u8 mandatory, dccp_feat_val *fval)\n+{\n+\tstruct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);\n+\n+\tif (new == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tnew->feat_num\t = feat;\n+\tnew->is_local\t = local;\n+\tnew->state\t = FEAT_INITIALISING;\n+\tnew->needs_confirm = 0;\n+\tnew->empty_confirm = 0;\n+\tnew->val\t = *fval;\n+\tnew->needs_mandatory = mandatory;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * dccp_feat_push_confirm - Add a Confirm entry to the FN list\n+ * @fn_list: feature-negotiation list to add to\n+ * @feat: one of %dccp_feature_numbers\n+ * @local: whether local (1) or remote (0) @feat_num is being confirmed\n+ * @fval: pointer to NN/SP value to be inserted or NULL\n+ * Returns 0 on success, a Reset code for further processing otherwise.\n+ */\n+static int dccp_feat_push_confirm(struct list_head *fn_list, u8 feat, u8 local,\n+\t\t\t\t dccp_feat_val *fval)\n+{\n+\tstruct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);\n+\n+\tif (new == NULL)\n+\t\treturn DCCP_RESET_CODE_TOO_BUSY;\n+\n+\tnew->feat_num\t = feat;\n+\tnew->is_local\t = local;\n+\tnew->state\t = FEAT_STABLE;\t/* transition in 6.6.2 */\n+\tnew->needs_confirm = 1;\n+\tnew->empty_confirm = (fval == NULL);\n+\tnew->val.nn\t = 0;\t\t/* zeroes the whole structure */\n+\tif (!new->empty_confirm)\n+\t\tnew->val = *fval;\n+\tnew->needs_mandatory = 0;\n+\n+\treturn 0;\n+}\n+\n+static int dccp_push_empty_confirm(struct list_head *fn_list, u8 feat, u8 local)\n+{\n+\treturn dccp_feat_push_confirm(fn_list, feat, local, NULL);\n+}\n+\n+static inline void dccp_feat_list_pop(struct dccp_feat_entry *entry)\n+{\n+\tlist_del(&entry->node);\n+\tdccp_feat_entry_destructor(entry);\n+}\n+\n+void dccp_feat_list_purge(struct list_head *fn_list)\n+{\n+\tstruct dccp_feat_entry *entry, *next;\n+\n+\tlist_for_each_entry_safe(entry, next, fn_list, node)\n+\t\tdccp_feat_entry_destructor(entry);\n+\tINIT_LIST_HEAD(fn_list);\n+}\n+EXPORT_SYMBOL_GPL(dccp_feat_list_purge);\n+\n int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,\n \t\t u8 *val, u8 len, gfp_t gfp)\n {\n", "prefixes": [ "3/5" ] }