~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/smb/client/compress/lz77.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/smb/client/compress/lz77.c (Version linux-6.12-rc7) and /fs/smb/client/compress/lz77.c (Version unix-v6-master)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * Copyright (C) 2024, SUSE LLC                   
  4  *                                                
  5  * Authors: Enzo Matsumiya <ematsumiya@suse.de    
  6  *                                                
  7  * Implementation of the LZ77 "plain" compress    
  8  */                                               
  9 #include <linux/slab.h>                           
 10 #include <linux/sizes.h>                          
 11 #include <linux/count_zeros.h>                    
 12 #include <linux/unaligned.h>                      
 13                                                   
 14 #include "lz77.h"                                 
 15                                                   
 16 /*                                                
 17  * Compression parameters.                        
 18  */                                               
 19 #define LZ77_MATCH_MIN_LEN      4                 
 20 #define LZ77_MATCH_MIN_DIST     1                 
 21 #define LZ77_MATCH_MAX_DIST     SZ_1K             
 22 #define LZ77_HASH_LOG           15                
 23 #define LZ77_HASH_SIZE          (1 << LZ77_HAS    
 24 #define LZ77_STEP_SIZE          sizeof(u64)       
 25                                                   
 26 static __always_inline u8 lz77_read8(const u8     
 27 {                                                 
 28         return get_unaligned(ptr);                
 29 }                                                 
 30                                                   
 31 static __always_inline u64 lz77_read64(const u    
 32 {                                                 
 33         return get_unaligned(ptr);                
 34 }                                                 
 35                                                   
 36 static __always_inline void lz77_write8(u8 *pt    
 37 {                                                 
 38         put_unaligned(v, ptr);                    
 39 }                                                 
 40                                                   
 41 static __always_inline void lz77_write16(u16 *    
 42 {                                                 
 43         put_unaligned_le16(v, ptr);               
 44 }                                                 
 45                                                   
 46 static __always_inline void lz77_write32(u32 *    
 47 {                                                 
 48         put_unaligned_le32(v, ptr);               
 49 }                                                 
 50                                                   
 51 static __always_inline u32 lz77_match_len(cons    
 52 {                                                 
 53         const void *start = cur;                  
 54         u64 diff;                                 
 55                                                   
 56         /* Safe for a do/while because otherwi    
 57         do {                                      
 58                 diff = lz77_read64(cur) ^ lz77    
 59                 if (!diff) {                      
 60                         cur += LZ77_STEP_SIZE;    
 61                         wnd += LZ77_STEP_SIZE;    
 62                                                   
 63                         continue;                 
 64                 }                                 
 65                                                   
 66                 /* This computes the number of    
 67                 cur += count_trailing_zeros(di    
 68                                                   
 69                 return (cur - start);             
 70         } while (likely(cur + LZ77_STEP_SIZE <    
 71                                                   
 72         while (cur < end && lz77_read8(cur++)     
 73                 ;                                 
 74                                                   
 75         return (cur - start);                     
 76 }                                                 
 77                                                   
 78 static __always_inline void *lz77_write_match(    
 79 {                                                 
 80         len -= 3;                                 
 81         dist--;                                   
 82         dist <<= 3;                               
 83                                                   
 84         if (len < 7) {                            
 85                 lz77_write16(dst, dist + len);    
 86                                                   
 87                 return dst + 2;                   
 88         }                                         
 89                                                   
 90         dist |= 7;                                
 91         lz77_write16(dst, dist);                  
 92         dst += 2;                                 
 93         len -= 7;                                 
 94                                                   
 95         if (!*nib) {                              
 96                 lz77_write8(dst, umin(len, 15)    
 97                 *nib = dst;                       
 98                 dst++;                            
 99         } else {                                  
100                 u8 *b = *nib;                     
101                                                   
102                 lz77_write8(b, *b | umin(len,     
103                 *nib = NULL;                      
104         }                                         
105                                                   
106         if (len < 15)                             
107                 return dst;                       
108                                                   
109         len -= 15;                                
110         if (len < 255) {                          
111                 lz77_write8(dst, len);            
112                                                   
113                 return dst + 1;                   
114         }                                         
115                                                   
116         lz77_write8(dst, 0xff);                   
117         dst++;                                    
118         len += 7 + 15;                            
119         if (len <= 0xffff) {                      
120                 lz77_write16(dst, len);           
121                                                   
122                 return dst + 2;                   
123         }                                         
124                                                   
125         lz77_write16(dst, 0);                     
126         dst += 2;                                 
127         lz77_write32(dst, len);                   
128                                                   
129         return dst + 4;                           
130 }                                                 
131                                                   
132 noinline int lz77_compress(const void *src, u3    
133 {                                                 
134         const void *srcp, *end;                   
135         void *dstp, *nib, *flag_pos;              
136         u32 flag_count = 0;                       
137         long flag = 0;                            
138         u64 *htable;                              
139                                                   
140         srcp = src;                               
141         end = src + slen;                         
142         dstp = dst;                               
143         nib = NULL;                               
144         flag_pos = dstp;                          
145         dstp += 4;                                
146                                                   
147         htable = kvcalloc(LZ77_HASH_SIZE, size    
148         if (!htable)                              
149                 return -ENOMEM;                   
150                                                   
151         /* Main loop. */                          
152         do {                                      
153                 u32 dist, len = 0;                
154                 const void *wnd;                  
155                 u64 hash;                         
156                                                   
157                 hash = ((lz77_read64(srcp) <<     
158                 wnd = src + htable[hash];         
159                 htable[hash] = srcp - src;        
160                 dist = srcp - wnd;                
161                                                   
162                 if (dist && dist < LZ77_MATCH_    
163                         len = lz77_match_len(w    
164                                                   
165                 if (len < LZ77_MATCH_MIN_LEN)     
166                         lz77_write8(dstp, lz77    
167                                                   
168                         dstp++;                   
169                         srcp++;                   
170                                                   
171                         flag <<= 1;               
172                         flag_count++;             
173                         if (flag_count == 32)     
174                                 lz77_write32(f    
175                                 flag_count = 0    
176                                 flag_pos = dst    
177                                 dstp += 4;        
178                         }                         
179                                                   
180                         continue;                 
181                 }                                 
182                                                   
183                 /*                                
184                  * Bail out if @dstp reached >    
185                  * going further.                 
186                  */                               
187                 if (unlikely(dstp - dst >= sle    
188                         *dlen = slen;             
189                         goto out;                 
190                 }                                 
191                                                   
192                 dstp = lz77_write_match(dstp,     
193                 srcp += len;                      
194                                                   
195                 flag = (flag << 1) | 1;           
196                 flag_count++;                     
197                 if (flag_count == 32) {           
198                         lz77_write32(flag_pos,    
199                         flag_count = 0;           
200                         flag_pos = dstp;          
201                         dstp += 4;                
202                 }                                 
203         } while (likely(srcp + LZ77_STEP_SIZE     
204                                                   
205         while (srcp < end) {                      
206                 u32 c = umin(end - srcp, 32 -     
207                                                   
208                 memcpy(dstp, srcp, c);            
209                                                   
210                 dstp += c;                        
211                 srcp += c;                        
212                                                   
213                 flag <<= c;                       
214                 flag_count += c;                  
215                 if (flag_count == 32) {           
216                         lz77_write32(flag_pos,    
217                         flag_count = 0;           
218                         flag_pos = dstp;          
219                         dstp += 4;                
220                 }                                 
221         }                                         
222                                                   
223         flag <<= (32 - flag_count);               
224         flag |= (1 << (32 - flag_count)) - 1;     
225         lz77_write32(flag_pos, flag);             
226                                                   
227         *dlen = dstp - dst;                       
228 out:                                              
229         kvfree(htable);                           
230                                                   
231         if (*dlen < slen)                         
232                 return 0;                         
233                                                   
234         return -EMSGSIZE;                         
235 }                                                 
236                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php