case PACKET_TX_RING:
        {
                union tpacket_req_u req_u;
-               int len;
 
+               ret = -EINVAL;
                lock_sock(sk);
                switch (po->tp_version) {
                case TPACKET_V1:
                case TPACKET_V2:
-                       len = sizeof(req_u.req);
+                       if (optlen < sizeof(req_u.req))
+                               break;
+                       ret = copy_from_sockptr(&req_u.req, optval,
+                                               sizeof(req_u.req)) ?
+                                               -EINVAL : 0;
                        break;
                case TPACKET_V3:
                default:
-                       len = sizeof(req_u.req3);
+                       if (optlen < sizeof(req_u.req3))
+                               break;
+                       ret = copy_from_sockptr(&req_u.req3, optval,
+                                               sizeof(req_u.req3)) ?
+                                               -EINVAL : 0;
                        break;
                }
-               if (optlen < len) {
-                       ret = -EINVAL;
-               } else {
-                       if (copy_from_sockptr(&req_u.req, optval, len))
-                               ret = -EFAULT;
-                       else
-                               ret = packet_set_ring(sk, &req_u, 0,
-                                                   optname == PACKET_TX_RING);
-               }
+               if (!ret)
+                       ret = packet_set_ring(sk, &req_u, 0,
+                                             optname == PACKET_TX_RING);
                release_sock(sk);
                return ret;
        }