Merge tag 'fallthrough-fixes-clang-5.14-rc1' of git://git.kernel.org/pub/scm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Jun 2021 03:03:38 +0000 (20:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Jun 2021 03:03:38 +0000 (20:03 -0700)
Pull fallthrough fixes from Gustavo Silva:
 "Fix many fall-through warnings when building with Clang 12.0.0 and
  '-Wimplicit-fallthrough' so that we at some point will be able to
  enable that warning by default"

* tag 'fallthrough-fixes-clang-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux: (26 commits)
  rxrpc: Fix fall-through warnings for Clang
  drm/nouveau/clk: Fix fall-through warnings for Clang
  drm/nouveau/therm: Fix fall-through warnings for Clang
  drm/nouveau: Fix fall-through warnings for Clang
  xfs: Fix fall-through warnings for Clang
  xfrm: Fix fall-through warnings for Clang
  tipc: Fix fall-through warnings for Clang
  sctp: Fix fall-through warnings for Clang
  rds: Fix fall-through warnings for Clang
  net/packet: Fix fall-through warnings for Clang
  net: netrom: Fix fall-through warnings for Clang
  ide: Fix fall-through warnings for Clang
  hwmon: (max6621) Fix fall-through warnings for Clang
  hwmon: (corsair-cpro) Fix fall-through warnings for Clang
  firewire: core: Fix fall-through warnings for Clang
  braille_console: Fix fall-through warnings for Clang
  ipv4: Fix fall-through warnings for Clang
  qlcnic: Fix fall-through warnings for Clang
  bnxt_en: Fix fall-through warnings for Clang
  netxen_nic: Fix fall-through warnings for Clang
  ...

1  2 
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
fs/xfs/libxfs/xfs_ag_resv.c
fs/xfs/scrub/common.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_ioctl.c
net/packet/af_packet.c
net/tipc/link.c

@@@ -440,6 -440,7 +440,7 @@@ nouveau_bo_pin(struct nouveau_bo *nvbo
                        break;
                case TTM_PL_TT:
                        error |= !(domain & NOUVEAU_GEM_DOMAIN_GART);
+                       break;
                default:
                        break;
                }
@@@ -546,7 -547,7 +547,7 @@@ nouveau_bo_sync_for_device(struct nouve
        struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm;
        int i, j;
  
 -      if (!ttm_dma)
 +      if (!ttm_dma || !ttm_dma->dma_address)
                return;
        if (!ttm_dma->pages) {
                NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma);
@@@ -582,7 -583,7 +583,7 @@@ nouveau_bo_sync_for_cpu(struct nouveau_
        struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm;
        int i, j;
  
 -      if (!ttm_dma)
 +      if (!ttm_dma || !ttm_dma->dma_address)
                return;
        if (!ttm_dma->pages) {
                NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma);
@@@ -282,8 -282,7 +282,8 @@@ static bool bnxt_vf_pciid(enum board_id
  {
        return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF ||
                idx == NETXTREME_S_VF || idx == NETXTREME_C_VF_HV ||
 -              idx == NETXTREME_E_VF_HV || idx == NETXTREME_E_P5_VF);
 +              idx == NETXTREME_E_VF_HV || idx == NETXTREME_E_P5_VF ||
 +              idx == NETXTREME_E_P5_VF_HV);
  }
  
  #define DB_CP_REARM_FLAGS     (DB_KEY_CP | DB_IDX_VALID)
@@@ -2184,6 -2183,7 +2184,7 @@@ static int bnxt_hwrm_handler(struct bnx
        case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
                bnxt_async_event_process(bp,
                                         (struct hwrm_async_event_cmpl *)txcmp);
+               break;
  
        default:
                break;
@@@ -6933,10 -6933,17 +6934,10 @@@ ctx_err
  static void bnxt_hwrm_set_pg_attr(struct bnxt_ring_mem_info *rmem, u8 *pg_attr,
                                  __le64 *pg_dir)
  {
 -      u8 pg_size = 0;
 -
        if (!rmem->nr_pages)
                return;
  
 -      if (BNXT_PAGE_SHIFT == 13)
 -              pg_size = 1 << 4;
 -      else if (BNXT_PAGE_SIZE == 16)
 -              pg_size = 2 << 4;
 -
 -      *pg_attr = pg_size;
 +      BNXT_SET_CTX_PAGE_ATTR(*pg_attr);
        if (rmem->depth >= 1) {
                if (rmem->depth == 2)
                        *pg_attr |= 2;
@@@ -7308,7 -7315,7 +7309,7 @@@ skip_rdma
        entries_sp = ctx->vnic_max_vnic_entries + ctx->qp_max_l2_entries +
                     2 * (extra_qps + ctx->qp_min_qp1_entries) + min;
        entries_sp = roundup(entries_sp, ctx->tqm_entries_multiple);
 -      entries = ctx->qp_max_l2_entries + extra_qps + ctx->qp_min_qp1_entries;
 +      entries = ctx->qp_max_l2_entries + 2 * (extra_qps + ctx->qp_min_qp1_entries);
        entries = roundup(entries, ctx->tqm_entries_multiple);
        entries = clamp_t(u32, entries, min, ctx->tqm_max_entries_per_ring);
        for (i = 0; i < ctx->tqm_fp_rings_count + 1; i++) {
@@@ -10779,125 -10786,37 +10780,125 @@@ static int bnxt_set_features(struct net
        return rc;
  }
  
 +static bool bnxt_exthdr_check(struct bnxt *bp, struct sk_buff *skb, int nw_off,
 +                            u8 **nextp)
 +{
 +      struct ipv6hdr *ip6h = (struct ipv6hdr *)(skb->data + nw_off);
 +      int hdr_count = 0;
 +      u8 *nexthdr;
 +      int start;
 +
 +      /* Check that there are at most 2 IPv6 extension headers, no
 +       * fragment header, and each is <= 64 bytes.
 +       */
 +      start = nw_off + sizeof(*ip6h);
 +      nexthdr = &ip6h->nexthdr;
 +      while (ipv6_ext_hdr(*nexthdr)) {
 +              struct ipv6_opt_hdr *hp;
 +              int hdrlen;
 +
 +              if (hdr_count >= 3 || *nexthdr == NEXTHDR_NONE ||
 +                  *nexthdr == NEXTHDR_FRAGMENT)
 +                      return false;
 +              hp = __skb_header_pointer(NULL, start, sizeof(*hp), skb->data,
 +                                        skb_headlen(skb), NULL);
 +              if (!hp)
 +                      return false;
 +              if (*nexthdr == NEXTHDR_AUTH)
 +                      hdrlen = ipv6_authlen(hp);
 +              else
 +                      hdrlen = ipv6_optlen(hp);
 +
 +              if (hdrlen > 64)
 +                      return false;
 +              nexthdr = &hp->nexthdr;
 +              start += hdrlen;
 +              hdr_count++;
 +      }
 +      if (nextp) {
 +              /* Caller will check inner protocol */
 +              if (skb->encapsulation) {
 +                      *nextp = nexthdr;
 +                      return true;
 +              }
 +              *nextp = NULL;
 +      }
 +      /* Only support TCP/UDP for non-tunneled ipv6 and inner ipv6 */
 +      return *nexthdr == IPPROTO_TCP || *nexthdr == IPPROTO_UDP;
 +}
 +
 +/* For UDP, we can only handle 1 Vxlan port and 1 Geneve port. */
 +static bool bnxt_udp_tunl_check(struct bnxt *bp, struct sk_buff *skb)
 +{
 +      struct udphdr *uh = udp_hdr(skb);
 +      __be16 udp_port = uh->dest;
 +
 +      if (udp_port != bp->vxlan_port && udp_port != bp->nge_port)
 +              return false;
 +      if (skb->inner_protocol_type == ENCAP_TYPE_ETHER) {
 +              struct ethhdr *eh = inner_eth_hdr(skb);
 +
 +              switch (eh->h_proto) {
 +              case htons(ETH_P_IP):
 +                      return true;
 +              case htons(ETH_P_IPV6):
 +                      return bnxt_exthdr_check(bp, skb,
 +                                               skb_inner_network_offset(skb),
 +                                               NULL);
 +              }
 +      }
 +      return false;
 +}
 +
 +static bool bnxt_tunl_check(struct bnxt *bp, struct sk_buff *skb, u8 l4_proto)
 +{
 +      switch (l4_proto) {
 +      case IPPROTO_UDP:
 +              return bnxt_udp_tunl_check(bp, skb);
 +      case IPPROTO_IPIP:
 +              return true;
 +      case IPPROTO_GRE: {
 +              switch (skb->inner_protocol) {
 +              default:
 +                      return false;
 +              case htons(ETH_P_IP):
 +                      return true;
 +              case htons(ETH_P_IPV6):
 +                      fallthrough;
 +              }
 +      }
 +      case IPPROTO_IPV6:
 +              /* Check ext headers of inner ipv6 */
 +              return bnxt_exthdr_check(bp, skb, skb_inner_network_offset(skb),
 +                                       NULL);
 +      }
 +      return false;
 +}
 +
  static netdev_features_t bnxt_features_check(struct sk_buff *skb,
                                             struct net_device *dev,
                                             netdev_features_t features)
  {
 -      struct bnxt *bp;
 -      __be16 udp_port;
 -      u8 l4_proto = 0;
 +      struct bnxt *bp = netdev_priv(dev);
 +      u8 *l4_proto;
  
        features = vlan_features_check(skb, features);
 -      if (!skb->encapsulation)
 -              return features;
 -
        switch (vlan_get_protocol(skb)) {
        case htons(ETH_P_IP):
 -              l4_proto = ip_hdr(skb)->protocol;
 +              if (!skb->encapsulation)
 +                      return features;
 +              l4_proto = &ip_hdr(skb)->protocol;
 +              if (bnxt_tunl_check(bp, skb, *l4_proto))
 +                      return features;
                break;
        case htons(ETH_P_IPV6):
 -              l4_proto = ipv6_hdr(skb)->nexthdr;
 +              if (!bnxt_exthdr_check(bp, skb, skb_network_offset(skb),
 +                                     &l4_proto))
 +                      break;
 +              if (!l4_proto || bnxt_tunl_check(bp, skb, *l4_proto))
 +                      return features;
                break;
 -      default:
 -              return features;
        }
 -
 -      if (l4_proto != IPPROTO_UDP)
 -              return features;
 -
 -      bp = netdev_priv(dev);
 -      /* For UDP, we can only handle 1 Vxlan port and 1 Geneve port. */
 -      udp_port = udp_hdr(skb)->dest;
 -      if (udp_port == bp->vxlan_port || udp_port == bp->nge_port)
 -              return features;
        return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
  }
  
@@@ -11750,8 -11669,6 +11751,8 @@@ static void bnxt_fw_init_one_p3(struct 
        bnxt_hwrm_coal_params_qcaps(bp);
  }
  
 +static int bnxt_probe_phy(struct bnxt *bp, bool fw_dflt);
 +
  static int bnxt_fw_init_one(struct bnxt *bp)
  {
        int rc;
                netdev_err(bp->dev, "Firmware init phase 2 failed\n");
                return rc;
        }
 +      rc = bnxt_probe_phy(bp, false);
 +      if (rc)
 +              return rc;
        rc = bnxt_approve_mac(bp, bp->dev->dev_addr, false);
        if (rc)
                return rc;
@@@ -13160,7 -13074,6 +13161,7 @@@ init_err_pci_clean
        bnxt_hwrm_func_drv_unrgtr(bp);
        bnxt_free_hwrm_short_cmd_req(bp);
        bnxt_free_hwrm_resources(bp);
 +      bnxt_ethtool_free(bp);
        kfree(bp->fw_health);
        bp->fw_health = NULL;
        bnxt_cleanup_pci(bp);
@@@ -2690,7 -2690,6 +2690,7 @@@ err_out_free_hw_res
        kfree(ahw);
  
  err_out_free_res:
 +      pci_disable_pcie_error_reporting(pdev);
        pci_release_regions(pdev);
  
  err_out_disable_pdev:
@@@ -3456,6 -3455,7 +3456,7 @@@ wait_npar
                        adapter->fw_wait_cnt = 0;
                        return;
                }
+               break;
        case QLCNIC_DEV_FAILED:
                break;
        default:
@@@ -325,22 -325,10 +325,22 @@@ out
                error2 = xfs_alloc_pagf_init(mp, tp, pag->pag_agno, 0);
                if (error2)
                        return error2;
 -              ASSERT(xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
 -                     xfs_perag_resv(pag, XFS_AG_RESV_RMAPBT)->ar_reserved <=
 -                     pag->pagf_freeblks + pag->pagf_flcount);
 +
 +              /*
 +               * If there isn't enough space in the AG to satisfy the
 +               * reservation, let the caller know that there wasn't enough
 +               * space.  Callers are responsible for deciding what to do
 +               * next, since (in theory) we can stumble along with
 +               * insufficient reservation if data blocks are being freed to
 +               * replenish the AG's free space.
 +               */
 +              if (!error &&
 +                  xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
 +                  xfs_perag_resv(pag, XFS_AG_RESV_RMAPBT)->ar_reserved >
 +                  pag->pagf_freeblks + pag->pagf_flcount)
 +                      error = -ENOSPC;
        }
 +
        return error;
  }
  
@@@ -366,7 -354,7 +366,7 @@@ xfs_ag_resv_alloc_extent
                break;
        default:
                ASSERT(0);
-               /* fall through */
+               fallthrough;
        case XFS_AG_RESV_NONE:
                field = args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS :
                                       XFS_TRANS_SB_FDBLOCKS;
@@@ -408,7 -396,7 +408,7 @@@ xfs_ag_resv_free_extent
                break;
        default:
                ASSERT(0);
-               /* fall through */
+               fallthrough;
        case XFS_AG_RESV_NONE:
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (int64_t)len);
                return;
diff --combined fs/xfs/scrub/common.c
@@@ -74,16 -74,14 +74,16 @@@ __xchk_process_error
                return true;
        case -EDEADLOCK:
                /* Used to restart an op with deadlock avoidance. */
 -              trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
 +              trace_xchk_deadlock_retry(
 +                              sc->ip ? sc->ip : XFS_I(file_inode(sc->file)),
 +                              sc->sm, *error);
                break;
        case -EFSBADCRC:
        case -EFSCORRUPTED:
                /* Note the badness but don't abort. */
                sc->sm->sm_flags |= errflag;
                *error = 0;
-               /* fall through */
+               fallthrough;
        default:
                trace_xchk_op_error(sc, agno, bno, *error,
                                ret_ip);
@@@ -136,7 -134,7 +136,7 @@@ __xchk_fblock_process_error
                /* Note the badness but don't abort. */
                sc->sm->sm_flags |= errflag;
                *error = 0;
-               /* fall through */
+               fallthrough;
        default:
                trace_xchk_file_op_error(sc, whichfork, offset, *error,
                                ret_ip);
@@@ -696,7 -694,7 +696,7 @@@ xchk_get_inode
                if (error)
                        return -ENOENT;
                error = -EFSCORRUPTED;
-               /* fall through */
+               fallthrough;
        default:
                trace_xchk_op_error(sc,
                                XFS_INO_TO_AGNO(mp, sc->sm->sm_ino),
diff --combined fs/xfs/xfs_bmap_util.c
@@@ -71,24 -71,18 +71,24 @@@ xfs_zero_extent
  #ifdef CONFIG_XFS_RT
  int
  xfs_bmap_rtalloc(
 -      struct xfs_bmalloca     *ap)    /* bmap alloc argument struct */
 +      struct xfs_bmalloca     *ap)
  {
 -      int             error;          /* error return value */
 -      xfs_mount_t     *mp;            /* mount point structure */
 -      xfs_extlen_t    prod = 0;       /* product factor for allocators */
 -      xfs_extlen_t    mod = 0;        /* product factor for allocators */
 -      xfs_extlen_t    ralen = 0;      /* realtime allocation length */
 -      xfs_extlen_t    align;          /* minimum allocation alignment */
 -      xfs_rtblock_t   rtb;
 -
 -      mp = ap->ip->i_mount;
 +      struct xfs_mount        *mp = ap->ip->i_mount;
 +      xfs_fileoff_t           orig_offset = ap->offset;
 +      xfs_rtblock_t           rtb;
 +      xfs_extlen_t            prod = 0;  /* product factor for allocators */
 +      xfs_extlen_t            mod = 0;   /* product factor for allocators */
 +      xfs_extlen_t            ralen = 0; /* realtime allocation length */
 +      xfs_extlen_t            align;     /* minimum allocation alignment */
 +      xfs_extlen_t            orig_length = ap->length;
 +      xfs_extlen_t            minlen = mp->m_sb.sb_rextsize;
 +      xfs_extlen_t            raminlen;
 +      bool                    rtlocked = false;
 +      bool                    ignore_locality = false;
 +      int                     error;
 +
        align = xfs_get_extsz_hint(ap->ip);
 +retry:
        prod = align / mp->m_sb.sb_rextsize;
        error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
                                        align, 1, ap->eof, 0,
        ASSERT(ap->length);
        ASSERT(ap->length % mp->m_sb.sb_rextsize == 0);
  
 +      /*
 +       * If we shifted the file offset downward to satisfy an extent size
 +       * hint, increase minlen by that amount so that the allocator won't
 +       * give us an allocation that's too short to cover at least one of the
 +       * blocks that the caller asked for.
 +       */
 +      if (ap->offset != orig_offset)
 +              minlen += orig_offset - ap->offset;
 +
        /*
         * If the offset & length are not perfectly aligned
         * then kill prod, it will just get us in trouble.
        /*
         * Lock out modifications to both the RT bitmap and summary inodes
         */
 -      xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
 -      xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
 -      xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
 -      xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL);
 +      if (!rtlocked) {
 +              xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
 +              xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
 +              xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
 +              xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL);
 +              rtlocked = true;
 +      }
  
        /*
         * If it's an allocation to an empty file at offset 0,
        /*
         * Realtime allocation, done through xfs_rtallocate_extent.
         */
 -      do_div(ap->blkno, mp->m_sb.sb_rextsize);
 +      if (ignore_locality)
 +              ap->blkno = 0;
 +      else
 +              do_div(ap->blkno, mp->m_sb.sb_rextsize);
        rtb = ap->blkno;
        ap->length = ralen;
 -      error = xfs_rtallocate_extent(ap->tp, ap->blkno, 1, ap->length,
 -                              &ralen, ap->wasdel, prod, &rtb);
 +      raminlen = max_t(xfs_extlen_t, 1, minlen / mp->m_sb.sb_rextsize);
 +      error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length,
 +                      &ralen, ap->wasdel, prod, &rtb);
        if (error)
                return error;
  
 -      ap->blkno = rtb;
 -      if (ap->blkno != NULLFSBLOCK) {
 -              ap->blkno *= mp->m_sb.sb_rextsize;
 -              ralen *= mp->m_sb.sb_rextsize;
 -              ap->length = ralen;
 -              ap->ip->i_nblocks += ralen;
 +      if (rtb != NULLRTBLOCK) {
 +              ap->blkno = rtb * mp->m_sb.sb_rextsize;
 +              ap->length = ralen * mp->m_sb.sb_rextsize;
 +              ap->ip->i_nblocks += ap->length;
                xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
                if (ap->wasdel)
 -                      ap->ip->i_delayed_blks -= ralen;
 +                      ap->ip->i_delayed_blks -= ap->length;
                /*
                 * Adjust the disk quota also. This was reserved
                 * earlier.
                 */
                xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
                        ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
 -                                      XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
 -      } else {
 -              ap->length = 0;
 +                                      XFS_TRANS_DQ_RTBCOUNT, ap->length);
 +              return 0;
 +      }
 +
 +      if (align > mp->m_sb.sb_rextsize) {
 +              /*
 +               * We previously enlarged the request length to try to satisfy
 +               * an extent size hint.  The allocator didn't return anything,
 +               * so reset the parameters to the original values and try again
 +               * without alignment criteria.
 +               */
 +              ap->offset = orig_offset;
 +              ap->length = orig_length;
 +              minlen = align = mp->m_sb.sb_rextsize;
 +              goto retry;
 +      }
 +
 +      if (!ignore_locality && ap->blkno != 0) {
 +              /*
 +               * If we can't allocate near a specific rt extent, try again
 +               * without locality criteria.
 +               */
 +              ignore_locality = true;
 +              goto retry;
        }
 +
 +      ap->blkno = NULLFSBLOCK;
 +      ap->length = 0;
        return 0;
  }
  #endif /* CONFIG_XFS_RT */
@@@ -286,7 -242,7 +286,7 @@@ xfs_bmap_count_blocks
                 */
                *count += btblocks - 1;
  
-               /* fall through */
+               fallthrough;
        case XFS_DINODE_FMT_EXTENTS:
                *nextents = xfs_bmap_count_leaves(ifp, count);
                break;
diff --combined fs/xfs/xfs_inode.c
@@@ -690,7 -690,6 +690,7 @@@ xfs_inode_inherit_flags
        const struct xfs_inode  *pip)
  {
        unsigned int            di_flags = 0;
 +      xfs_failaddr_t          failaddr;
        umode_t                 mode = VFS_I(ip)->i_mode;
  
        if (S_ISDIR(mode)) {
                di_flags |= XFS_DIFLAG_FILESTREAM;
  
        ip->i_diflags |= di_flags;
 +
 +      /*
 +       * Inode verifiers on older kernels only check that the extent size
 +       * hint is an integer multiple of the rt extent size on realtime files.
 +       * They did not check the hint alignment on a directory with both
 +       * rtinherit and extszinherit flags set.  If the misaligned hint is
 +       * propagated from a directory into a new realtime file, new file
 +       * allocations will fail due to math errors in the rt allocator and/or
 +       * trip the verifiers.  Validate the hint settings in the new file so
 +       * that we don't let broken hints propagate.
 +       */
 +      failaddr = xfs_inode_validate_extsize(ip->i_mount, ip->i_extsize,
 +                      VFS_I(ip)->i_mode, ip->i_diflags);
 +      if (failaddr) {
 +              ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
 +                                 XFS_DIFLAG_EXTSZINHERIT);
 +              ip->i_extsize = 0;
 +      }
  }
  
  /* Propagate di_flags2 from a parent inode to a child inode. */
@@@ -756,22 -737,12 +756,22 @@@ xfs_inode_inherit_flags2
        struct xfs_inode        *ip,
        const struct xfs_inode  *pip)
  {
 +      xfs_failaddr_t          failaddr;
 +
        if (pip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) {
                ip->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE;
                ip->i_cowextsize = pip->i_cowextsize;
        }
        if (pip->i_diflags2 & XFS_DIFLAG2_DAX)
                ip->i_diflags2 |= XFS_DIFLAG2_DAX;
 +
 +      /* Don't let invalid cowextsize hints propagate. */
 +      failaddr = xfs_inode_validate_cowextsize(ip->i_mount, ip->i_cowextsize,
 +                      VFS_I(ip)->i_mode, ip->i_diflags, ip->i_diflags2);
 +      if (failaddr) {
 +              ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
 +              ip->i_cowextsize = 0;
 +      }
  }
  
  /*
@@@ -877,7 -848,7 +877,7 @@@ xfs_init_new_inode
                        xfs_inode_inherit_flags(ip, pip);
                if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY))
                        xfs_inode_inherit_flags2(ip, pip);
-               /* FALLTHROUGH */
+               fallthrough;
        case S_IFLNK:
                ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
                ip->i_df.if_bytes = 0;
diff --combined fs/xfs/xfs_ioctl.c
@@@ -558,7 -558,7 +558,7 @@@ xfs_ioc_attrmulti_one
        case ATTR_OP_REMOVE:
                value = NULL;
                *len = 0;
-               /* fall through */
+               fallthrough;
        case ATTR_OP_SET:
                error = mnt_want_write_file(parfilp);
                if (error)
@@@ -1267,8 -1267,20 +1267,8 @@@ out_error
  }
  
  /*
 - * extent size hint validation is somewhat cumbersome. Rules are:
 - *
 - * 1. extent size hint is only valid for directories and regular files
 - * 2. FS_XFLAG_EXTSIZE is only valid for regular files
 - * 3. FS_XFLAG_EXTSZINHERIT is only valid for directories.
 - * 4. can only be changed on regular files if no extents are allocated
 - * 5. can be changed on directories at any time
 - * 6. extsize hint of 0 turns off hints, clears inode flags.
 - * 7. Extent size must be a multiple of the appropriate block size.
 - * 8. for non-realtime files, the extent size hint must be limited
 - *    to half the AG size to avoid alignment extending the extent beyond the
 - *    limits of the AG.
 - *
 - * Please keep this function in sync with xfs_scrub_inode_extsize.
 + * Validate a proposed extent size hint.  For regular files, the hint can only
 + * be changed if no extents are allocated.
   */
  static int
  xfs_ioctl_setattr_check_extsize(
        struct fileattr         *fa)
  {
        struct xfs_mount        *mp = ip->i_mount;
 -      xfs_extlen_t            size;
 -      xfs_fsblock_t           extsize_fsb;
 +      xfs_failaddr_t          failaddr;
 +      uint16_t                new_diflags;
  
        if (!fa->fsx_valid)
                return 0;
  
        if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents &&
 -          ((ip->i_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
 +          XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize)
                return -EINVAL;
  
 -      if (fa->fsx_extsize == 0)
 -              return 0;
 -
 -      extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
 -      if (extsize_fsb > MAXEXTLEN)
 +      if (fa->fsx_extsize & mp->m_blockmask)
                return -EINVAL;
  
 -      if (XFS_IS_REALTIME_INODE(ip) ||
 -          (fa->fsx_xflags & FS_XFLAG_REALTIME)) {
 -              size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
 -      } else {
 -              size = mp->m_sb.sb_blocksize;
 -              if (extsize_fsb > mp->m_sb.sb_agblocks / 2)
 +      new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
 +
 +      /*
 +       * Inode verifiers on older kernels don't check that the extent size
 +       * hint is an integer multiple of the rt extent size on a directory
 +       * with both rtinherit and extszinherit flags set.  Don't let sysadmins
 +       * misconfigure directories.
 +       */
 +      if ((new_diflags & XFS_DIFLAG_RTINHERIT) &&
 +          (new_diflags & XFS_DIFLAG_EXTSZINHERIT)) {
 +              unsigned int    rtextsize_bytes;
 +
 +              rtextsize_bytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize);
 +              if (fa->fsx_extsize % rtextsize_bytes)
                        return -EINVAL;
        }
  
 -      if (fa->fsx_extsize % size)
 -              return -EINVAL;
 -
 -      return 0;
 +      failaddr = xfs_inode_validate_extsize(ip->i_mount,
 +                      XFS_B_TO_FSB(mp, fa->fsx_extsize),
 +                      VFS_I(ip)->i_mode, new_diflags);
 +      return failaddr != NULL ? -EINVAL : 0;
  }
  
 -/*
 - * CoW extent size hint validation rules are:
 - *
 - * 1. CoW extent size hint can only be set if reflink is enabled on the fs.
 - *    The inode does not have to have any shared blocks, but it must be a v3.
 - * 2. FS_XFLAG_COWEXTSIZE is only valid for directories and regular files;
 - *    for a directory, the hint is propagated to new files.
 - * 3. Can be changed on files & directories at any time.
 - * 4. CoW extsize hint of 0 turns off hints, clears inode flags.
 - * 5. Extent size must be a multiple of the appropriate block size.
 - * 6. The extent size hint must be limited to half the AG size to avoid
 - *    alignment extending the extent beyond the limits of the AG.
 - *
 - * Please keep this function in sync with xfs_scrub_inode_cowextsize.
 - */
  static int
  xfs_ioctl_setattr_check_cowextsize(
        struct xfs_inode        *ip,
        struct fileattr         *fa)
  {
        struct xfs_mount        *mp = ip->i_mount;
 -      xfs_extlen_t            size;
 -      xfs_fsblock_t           cowextsize_fsb;
 +      xfs_failaddr_t          failaddr;
 +      uint64_t                new_diflags2;
 +      uint16_t                new_diflags;
  
        if (!fa->fsx_valid)
                return 0;
  
 -      if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE))
 -              return 0;
 -
 -      if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb))
 +      if (fa->fsx_cowextsize & mp->m_blockmask)
                return -EINVAL;
  
 -      if (fa->fsx_cowextsize == 0)
 -              return 0;
 +      new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
 +      new_diflags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
  
 -      cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
 -      if (cowextsize_fsb > MAXEXTLEN)
 -              return -EINVAL;
 -
 -      size = mp->m_sb.sb_blocksize;
 -      if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2)
 -              return -EINVAL;
 -
 -      if (fa->fsx_cowextsize % size)
 -              return -EINVAL;
 -
 -      return 0;
 +      failaddr = xfs_inode_validate_cowextsize(ip->i_mount,
 +                      XFS_B_TO_FSB(mp, fa->fsx_cowextsize),
 +                      VFS_I(ip)->i_mode, new_diflags, new_diflags2);
 +      return failaddr != NULL ? -EINVAL : 0;
  }
  
  static int
@@@ -1511,7 -1544,7 +1511,7 @@@ xfs_ioc_getbmap
        switch (cmd) {
        case XFS_IOC_GETBMAPA:
                bmx.bmv_iflags = BMV_IF_ATTRFORK;
-               /*FALLTHRU*/
+               fallthrough;
        case XFS_IOC_GETBMAP:
                /* struct getbmap is a strict subset of struct getbmapx. */
                recsize = sizeof(struct getbmap);
diff --combined net/packet/af_packet.c
@@@ -422,8 -422,7 +422,8 @@@ static __u32 tpacket_get_timestamp(stru
            ktime_to_timespec64_cond(shhwtstamps->hwtstamp, ts))
                return TP_STATUS_TS_RAW_HARDWARE;
  
 -      if (ktime_to_timespec64_cond(skb->tstamp, ts))
 +      if ((flags & SOF_TIMESTAMPING_SOFTWARE) &&
 +          ktime_to_timespec64_cond(skb->tstamp, ts))
                return TP_STATUS_TS_SOFTWARE;
  
        return 0;
@@@ -1656,6 -1655,7 +1656,7 @@@ static int fanout_add(struct sock *sk, 
        case PACKET_FANOUT_ROLLOVER:
                if (type_flags & PACKET_FANOUT_FLAG_ROLLOVER)
                        return -EINVAL;
+               break;
        case PACKET_FANOUT_HASH:
        case PACKET_FANOUT_LB:
        case PACKET_FANOUT_CPU:
@@@ -2341,12 -2341,7 +2342,12 @@@ static int tpacket_rcv(struct sk_buff *
  
        skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
  
 -      if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
 +      /* Always timestamp; prefer an existing software timestamp taken
 +       * closer to the time of capture.
 +       */
 +      ts_status = tpacket_get_timestamp(skb, &ts,
 +                                        po->tp_tstamp | SOF_TIMESTAMPING_SOFTWARE);
 +      if (!ts_status)
                ktime_get_real_ts64(&ts);
  
        status |= ts_status;
@@@ -2683,7 -2678,7 +2684,7 @@@ static int tpacket_snd(struct packet_so
        }
        if (likely(saddr == NULL)) {
                dev     = packet_cached_dev_get(po);
 -              proto   = po->num;
 +              proto   = READ_ONCE(po->num);
        } else {
                err = -EINVAL;
                if (msg->msg_namelen < sizeof(struct sockaddr_ll))
@@@ -2896,7 -2891,7 +2897,7 @@@ static int packet_snd(struct socket *so
  
        if (likely(saddr == NULL)) {
                dev     = packet_cached_dev_get(po);
 -              proto   = po->num;
 +              proto   = READ_ONCE(po->num);
        } else {
                err = -EINVAL;
                if (msg->msg_namelen < sizeof(struct sockaddr_ll))
@@@ -3034,13 -3029,10 +3035,13 @@@ static int packet_sendmsg(struct socke
        struct sock *sk = sock->sk;
        struct packet_sock *po = pkt_sk(sk);
  
 -      if (po->tx_ring.pg_vec)
 +      /* Reading tx_ring.pg_vec without holding pg_vec_lock is racy.
 +       * tpacket_snd() will redo the check safely.
 +       */
 +      if (data_race(po->tx_ring.pg_vec))
                return tpacket_snd(po, msg);
 -      else
 -              return packet_snd(sock, msg, len);
 +
 +      return packet_snd(sock, msg, len);
  }
  
  /*
@@@ -3171,7 -3163,7 +3172,7 @@@ static int packet_do_bind(struct sock *
                        /* prevents packet_notifier() from calling
                         * register_prot_hook()
                         */
 -                      po->num = 0;
 +                      WRITE_ONCE(po->num, 0);
                        __unregister_prot_hook(sk, true);
                        rcu_read_lock();
                        dev_curr = po->prot_hook.dev;
                }
  
                BUG_ON(po->running);
 -              po->num = proto;
 +              WRITE_ONCE(po->num, proto);
                po->prot_hook.type = proto;
  
                if (unlikely(unlisted)) {
                        dev_put(dev);
                        po->prot_hook.dev = NULL;
 -                      po->ifindex = -1;
 +                      WRITE_ONCE(po->ifindex, -1);
                        packet_cached_dev_reset(po);
                } else {
                        po->prot_hook.dev = dev;
 -                      po->ifindex = dev ? dev->ifindex : 0;
 +                      WRITE_ONCE(po->ifindex, dev ? dev->ifindex : 0);
                        packet_cached_dev_assign(po, dev);
                }
        }
@@@ -3505,7 -3497,7 +3506,7 @@@ static int packet_getname_spkt(struct s
        uaddr->sa_family = AF_PACKET;
        memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data));
        rcu_read_lock();
 -      dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
 +      dev = dev_get_by_index_rcu(sock_net(sk), READ_ONCE(pkt_sk(sk)->ifindex));
        if (dev)
                strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data));
        rcu_read_unlock();
@@@ -3520,18 -3512,16 +3521,18 @@@ static int packet_getname(struct socke
        struct sock *sk = sock->sk;
        struct packet_sock *po = pkt_sk(sk);
        DECLARE_SOCKADDR(struct sockaddr_ll *, sll, uaddr);
 +      int ifindex;
  
        if (peer)
                return -EOPNOTSUPP;
  
 +      ifindex = READ_ONCE(po->ifindex);
        sll->sll_family = AF_PACKET;
 -      sll->sll_ifindex = po->ifindex;
 -      sll->sll_protocol = po->num;
 +      sll->sll_ifindex = ifindex;
 +      sll->sll_protocol = READ_ONCE(po->num);
        sll->sll_pkttype = 0;
        rcu_read_lock();
 -      dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex);
 +      dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
        if (dev) {
                sll->sll_hatype = dev->type;
                sll->sll_halen = dev->addr_len;
@@@ -4110,7 -4100,7 +4111,7 @@@ static int packet_notifier(struct notif
                                }
                                if (msg == NETDEV_UNREGISTER) {
                                        packet_cached_dev_reset(po);
 -                                      po->ifindex = -1;
 +                                      WRITE_ONCE(po->ifindex, -1);
                                        if (po->prot_hook.dev)
                                                dev_put(po->prot_hook.dev);
                                        po->prot_hook.dev = NULL;
@@@ -4416,7 -4406,7 +4417,7 @@@ static int packet_set_ring(struct sock 
        was_running = po->running;
        num = po->num;
        if (was_running) {
 -              po->num = 0;
 +              WRITE_ONCE(po->num, 0);
                __unregister_prot_hook(sk, false);
        }
        spin_unlock(&po->bind_lock);
  
        spin_lock(&po->bind_lock);
        if (was_running) {
 -              po->num = num;
 +              WRITE_ONCE(po->num, num);
                register_prot_hook(sk);
        }
        spin_unlock(&po->bind_lock);
@@@ -4621,8 -4611,8 +4622,8 @@@ static int packet_seq_show(struct seq_f
                           s,
                           refcount_read(&s->sk_refcnt),
                           s->sk_type,
 -                         ntohs(po->num),
 -                         po->ifindex,
 +                         ntohs(READ_ONCE(po->num)),
 +                         READ_ONCE(po->ifindex),
                           po->running,
                           atomic_read(&s->sk_rmem_alloc),
                           from_kuid_munged(seq_user_ns(seq), sock_i_uid(s)),
diff --combined net/tipc/link.c
@@@ -372,11 -372,6 +372,11 @@@ char tipc_link_plane(struct tipc_link *
        return l->net_plane;
  }
  
 +struct net *tipc_link_net(struct tipc_link *l)
 +{
 +      return l->net;
 +}
 +
  void tipc_link_update_caps(struct tipc_link *l, u16 capabilities)
  {
        l->peer_caps = capabilities;
@@@ -654,6 -649,7 +654,7 @@@ int tipc_link_fsm_evt(struct tipc_link 
                        break;
                case LINK_FAILOVER_BEGIN_EVT:
                        l->state = LINK_FAILINGOVER;
+                       break;
                case LINK_FAILURE_EVT:
                case LINK_RESET_EVT:
                case LINK_ESTABLISH_EVT: