/* * netsniff-ng - the packet sniffing beast * Copyright 2012 Markus Amend , Deutsche Flugsicherung GmbH * Subject to the GPL, version 2. * * IPv6 Hop-By-Hop Header described in RFC2460 */ #include #include #include /* for ntohs() */ #include "proto.h" #include "dissector_eth.h" #include "built_in.h" #include "pkt_buff.h" struct hop_by_hophdr { uint8_t h_next_header; uint8_t hdr_len; } __packed; static void dissect_opt_hop(struct pkt_buff *pkt __maybe_unused, ssize_t *opt_len) { /* Have to been upgraded. * http://tools.ietf.org/html/rfc2460#section-4.2 * Look also for proto_ipv6_dest_opts.h, it needs * dissect_opt(), too. */ if (*opt_len) tprintf(", Option(s) recognized "); /* If adding dissector reduce opt_len for each using of pkt_pull * to the same size. */ } static void hop_by_hop(struct pkt_buff *pkt) { uint16_t hdr_ext_len; ssize_t opt_len; struct hop_by_hophdr *hop_ops; hop_ops = (struct hop_by_hophdr *) pkt_pull(pkt, sizeof(*hop_ops)); if (hop_ops == NULL) return; /* Total Header Length in Bytes */ hdr_ext_len = (hop_ops->hdr_len + 1) * 8; /* Options length in Bytes */ opt_len = hdr_ext_len - sizeof(*hop_ops); tprintf("\t [ Hop-by-Hop Options "); tprintf("NextHdr (%u), ", hop_ops->h_next_header); if (opt_len > pkt_len(pkt) || opt_len < 0){ tprintf("HdrExtLen (%u, %u Bytes, %s)", hop_ops->hdr_len, hdr_ext_len, colorize_start_full(black, red) "invalid" colorize_end()); return; } tprintf("HdrExtLen (%u, %u Bytes)", hop_ops->hdr_len, hdr_ext_len); dissect_opt_hop(pkt, &opt_len); tprintf(" ]\n"); pkt_pull(pkt, opt_len); pkt_set_dissector(pkt, ð_lay3, hop_ops->h_next_header); } static void hop_by_hop_less(struct pkt_buff *pkt) { uint16_t hdr_ext_len; ssize_t opt_len; struct hop_by_hophdr *hop_ops; hop_ops = (struct hop_by_hophdr *) pkt_pull(pkt, sizeof(*hop_ops)); if (hop_ops == NULL) return; /* Total Header Length in Bytes */ hdr_ext_len = (hop_ops->hdr_len + 1) * 8; /* Options length in Bytes */ opt_len = hdr_ext_len - sizeof(*hop_ops); if (opt_len > pkt_len(pkt) || opt_len < 0) return; tprintf(" Hop Ops"); pkt_pull(pkt, opt_len); pkt_set_dissector(pkt, ð_lay3, hop_ops->h_next_header); } struct protocol ipv6_hop_by_hop_ops = { .key = 0x0, .print_full = hop_by_hop, .print_less = hop_by_hop_less, }; >
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2016-05-12 13:53:36 +0100
committerFilipe Manana <fdmanana@suse.com>2016-05-13 01:59:36 +0100
commit5f9a8a51d8b95505d8de8b7191ae2ed8c504d4af (patch)
treed97a7f5d321694e09c3046e9027c23a02d6a5878
parentf78c436c3931e7df713688028f2b4faf72bf9f2a (diff)
Btrfs: add semaphore to synchronize direct IO writes with fsync
Due to the optimization of lockless direct IO writes (the inode's i_mutex is not held) introduced in commit 38851cc19adb ("Btrfs: implement unlocked dio write"), we started having races between such writes with concurrent fsync operations that use the fast fsync path. These races were addressed in the patches titled "Btrfs: fix race between fsync and lockless direct IO writes" and "Btrfs: fix race between fsync and direct IO writes for prealloc extents". The races happened because the direct IO path, like every other write path, does create extent maps followed by the corresponding ordered extents while the fast fsync path collected first ordered extents and then it collected extent maps. This made it possible to log file extent items (based on the collected extent maps) without waiting for the corresponding ordered extents to complete (get their IO done). The two fixes mentioned before added a solution that consists of making the direct IO path create first the ordered extents and then the extent maps, while the fsync path attempts to collect any new ordered extents once it collects the extent maps. This was simple and did not require adding any synchonization primitive to any data structure (struct btrfs_inode for example) but it makes things more fragile for future development endeavours and adds an exceptional approach compared to the other write paths. This change adds a read-write semaphore to the btrfs inode structure and makes the direct IO path create the extent maps and the ordered extents while holding read access on that semaphore, while the fast fsync path collects extent maps and ordered extents while holding write access on that semaphore. The logic for direct IO write path is encapsulated in a new helper function that is used both for cow and nocow direct IO writes. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Josef Bacik <jbacik@fb.com>