[bug report] smb: client: compress: LZ77 code improvements cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Enzo Matsumiya,

Commit 13b68d44990d ("smb: client: compress: LZ77 code improvements
cleanup") from Sep 6, 2024 (linux-next), leads to the following
Smatch static checker warning:

	fs/smb/client/compress.c:311 should_compress()
	warn: signedness bug returning '(-12)'

fs/smb/client/compress.c
    292 bool should_compress(const struct cifs_tcon *tcon, const struct smb_rqst *rq)
    293 {
    294         const struct smb2_hdr *shdr = rq->rq_iov->iov_base;
    295 
    296         if (unlikely(!tcon || !tcon->ses || !tcon->ses->server))
    297                 return false;
    298 
    299         if (!tcon->ses->server->compression.enabled)
    300                 return false;
    301 
    302         if (!(tcon->share_flags & SMB2_SHAREFLAG_COMPRESS_DATA))
    303                 return false;
    304 
    305         if (shdr->Command == SMB2_WRITE) {
    306                 const struct smb2_write_req *wreq = rq->rq_iov->iov_base;
    307 
    308                 if (wreq->Length < SMB_COMPRESS_MIN_LEN)
    309                         return false;
    310 
--> 311                 return is_compressible(&rq->rq_iter);

Was this patch ever sent to a public mailing list?  I don't see it on lore.

The is_compressible() function has some weird stuff going on.  It's an is_
function so it should return bool instead of negative error codes.  Here the
negative error codes are treated as "let's compress this".

check_repeated_data().  It's better to name boolean functions something like
is_repeated_data() so people will know it's boolean.  This function takes the
sample data and compares if the first half is a duplicate of the second half.
The only way I can imagine this happening in the real world is if the file is
all zeroes.

check_ascii_bytes().  Rename to is_mostly_ascii().  Get rid of the bucket struct
and instead just it make an array of unsigned int.  Then the checks are
simpler:

-		if (bkt[i].count > 0)
+		if (bkt[i])

The check_ascii_bytes() has some micro-optimizations going on.  I don't think
they're necessary.  I can't imagine how this could show up on a benchmark.  Just
do one loop instead of two.  On my computer I'm able to do that function 12
million times per second, but I micro optimized the function even more and now
I can go through it 20 million times per second using a single loop.

static bool check_ascii_bytes2(const unsigned int *p)
{
        int count = 0;
        int i;

        for (i = 0; i < 256; i++) {
                if (p[i]) {
                        if (++count > 64)
                                return false;
                }
        }

        return true;
}

The trick was I got rid of the threshold const used a literal instead.

The check at the end of is_compressible() should not treat negatives as success:

-	return !!ret;
+	if (ret == 1)
+		return true;
+	return false;

    312         }
    313 
    314         return (shdr->Command == SMB2_READ);
    315 }

regards,
dan carpenter




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux