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

TOMOYO Linux Cross Reference
Linux/fs/ubifs/tnc_misc.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/ubifs/tnc_misc.c (Version linux-6.12-rc7) and /fs/ubifs/tnc_misc.c (Version linux-2.6.0)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * This file is part of UBIFS.                    
  4  *                                                
  5  * Copyright (C) 2006-2008 Nokia Corporation.     
  6  *                                                
  7  * Authors: Adrian Hunter                         
  8  *          Artem Bityutskiy (Битюцкий    
  9  */                                               
 10                                                   
 11 /*                                                
 12  * This file contains miscelanious TNC-related    
 13  * different files. This file does not form an    
 14  * sub-system. The file was created because th    
 15  * putting it all in one file would make that     
 16  */                                               
 17                                                   
 18 #include "ubifs.h"                                
 19                                                   
 20 /**                                               
 21  * ubifs_tnc_levelorder_next - next TNC tree e    
 22  * @c: UBIFS file-system description object       
 23  * @zr: root of the subtree to traverse           
 24  * @znode: previous znode                         
 25  *                                                
 26  * This function implements levelorder TNC tra    
 27  * Returns the next element or %NULL if @znode    
 28  */                                               
 29 struct ubifs_znode *ubifs_tnc_levelorder_next(    
 30                                                   
 31                                                   
 32 {                                                 
 33         int level, iip, level_search = 0;         
 34         struct ubifs_znode *zn;                   
 35                                                   
 36         ubifs_assert(c, zr);                      
 37                                                   
 38         if (unlikely(!znode))                     
 39                 return zr;                        
 40                                                   
 41         if (unlikely(znode == zr)) {              
 42                 if (znode->level == 0)            
 43                         return NULL;              
 44                 return ubifs_tnc_find_child(zr    
 45         }                                         
 46                                                   
 47         level = znode->level;                     
 48                                                   
 49         iip = znode->iip;                         
 50         while (1) {                               
 51                 ubifs_assert(c, znode->level <    
 52                                                   
 53                 /*                                
 54                  * First walk up until there i    
 55                  * look at.                       
 56                  */                               
 57                 while (znode->parent != zr &&     
 58                         znode = znode->parent;    
 59                         iip = znode->iip;         
 60                 }                                 
 61                                                   
 62                 if (unlikely(znode->parent ==     
 63                              iip >= znode->par    
 64                         /* This level is done,    
 65                         level -= 1;               
 66                         if (level_search || le    
 67                                 /*                
 68                                  * We were alr    
 69                                  * level ('lev    
 70                                  * again, it j    
 71                                  * were finish    
 72                                  */               
 73                                 return NULL;      
 74                                                   
 75                         level_search = 1;         
 76                         iip = -1;                 
 77                         znode = ubifs_tnc_find    
 78                         ubifs_assert(c, znode)    
 79                 }                                 
 80                                                   
 81                 /* Switch to the next index */    
 82                 zn = ubifs_tnc_find_child(znod    
 83                 if (!zn) {                        
 84                         /* No more children to    
 85                         iip = znode->parent->c    
 86                         continue;                 
 87                 }                                 
 88                                                   
 89                 /* Walk back down to the level    
 90                 while (zn->level != level) {      
 91                         znode = zn;               
 92                         zn = ubifs_tnc_find_ch    
 93                         if (!zn) {                
 94                                 /*                
 95                                  * This path i    
 96                                  * reach 'leve    
 97                                  */               
 98                                 iip = znode->i    
 99                                 break;            
100                         }                         
101                 }                                 
102                                                   
103                 if (zn) {                         
104                         ubifs_assert(c, zn->le    
105                         return zn;                
106                 }                                 
107         }                                         
108 }                                                 
109                                                   
110 /**                                               
111  * ubifs_search_zbranch - search znode branch.    
112  * @c: UBIFS file-system description object       
113  * @znode: znode to search in                     
114  * @key: key to search for                        
115  * @n: znode branch slot number is returned he    
116  *                                                
117  * This is a helper function which search bran    
118  * binary search. The result of the search may    
119  *   o exact match, then %1 is returned, and t    
120  *     stored in @n;                              
121  *   o no exact match, then %0 is returned and    
122  *     closest branch is returned in @n; the s    
123  *     greater than @key, then %-1 is returned    
124  */                                               
125 int ubifs_search_zbranch(const struct ubifs_in    
126                          const struct ubifs_zn    
127                          const union ubifs_key    
128 {                                                 
129         int beg = 0, end = znode->child_cnt, m    
130         int cmp;                                  
131         const struct ubifs_zbranch *zbr = &zno    
132                                                   
133         ubifs_assert(c, end > beg);               
134                                                   
135         while (end > beg) {                       
136                 mid = (beg + end) >> 1;           
137                 cmp = keys_cmp(c, key, &zbr[mi    
138                 if (cmp > 0)                      
139                         beg = mid + 1;            
140                 else if (cmp < 0)                 
141                         end = mid;                
142                 else {                            
143                         *n = mid;                 
144                         return 1;                 
145                 }                                 
146         }                                         
147                                                   
148         *n = end - 1;                             
149                                                   
150         /* The insert point is after *n */        
151         ubifs_assert(c, *n >= -1 && *n < znode    
152         if (*n == -1)                             
153                 ubifs_assert(c, keys_cmp(c, ke    
154         else                                      
155                 ubifs_assert(c, keys_cmp(c, ke    
156         if (*n + 1 < znode->child_cnt)            
157                 ubifs_assert(c, keys_cmp(c, ke    
158                                                   
159         return 0;                                 
160 }                                                 
161                                                   
162 /**                                               
163  * ubifs_tnc_postorder_first - find first znod    
164  * @znode: znode to start at (root of the sub-    
165  *                                                
166  * Find the lowest leftmost znode in a subtree    
167  * ignored.                                       
168  */                                               
169 struct ubifs_znode *ubifs_tnc_postorder_first(    
170 {                                                 
171         if (unlikely(!znode))                     
172                 return NULL;                      
173                                                   
174         while (znode->level > 0) {                
175                 struct ubifs_znode *child;        
176                                                   
177                 child = ubifs_tnc_find_child(z    
178                 if (!child)                       
179                         return znode;             
180                 znode = child;                    
181         }                                         
182                                                   
183         return znode;                             
184 }                                                 
185                                                   
186 /**                                               
187  * ubifs_tnc_postorder_next - next TNC tree el    
188  * @c: UBIFS file-system description object       
189  * @znode: previous znode                         
190  *                                                
191  * This function implements postorder TNC trav    
192  * Returns the next element or %NULL if @znode    
193  */                                               
194 struct ubifs_znode *ubifs_tnc_postorder_next(c    
195                                              s    
196 {                                                 
197         struct ubifs_znode *zn;                   
198                                                   
199         ubifs_assert(c, znode);                   
200         if (unlikely(!znode->parent))             
201                 return NULL;                      
202                                                   
203         /* Switch to the next index in the par    
204         zn = ubifs_tnc_find_child(znode->paren    
205         if (!zn)                                  
206                 /* This is in fact the last ch    
207                 return znode->parent;             
208                                                   
209         /* Go to the first znode in this new s    
210         return ubifs_tnc_postorder_first(zn);     
211 }                                                 
212                                                   
213 /**                                               
214  * ubifs_destroy_tnc_subtree - destroy all zno    
215  * @c: UBIFS file-system description object       
216  * @znode: znode defining subtree to destroy      
217  *                                                
218  * This function destroys subtree of the TNC t    
219  * znodes in the subtree.                         
220  */                                               
221 long ubifs_destroy_tnc_subtree(const struct ub    
222                                struct ubifs_zn    
223 {                                                 
224         struct ubifs_znode *zn = ubifs_tnc_pos    
225         long clean_freed = 0;                     
226         int n;                                    
227                                                   
228         ubifs_assert(c, zn);                      
229         while (1) {                               
230                 for (n = 0; n < zn->child_cnt;    
231                         if (!zn->zbranch[n].zn    
232                                 continue;         
233                                                   
234                         if (zn->level > 0 &&      
235                             !ubifs_zn_dirty(zn    
236                                 clean_freed +=    
237                                                   
238                         cond_resched();           
239                         kfree(zn->zbranch[n].z    
240                 }                                 
241                                                   
242                 if (zn == znode) {                
243                         if (!ubifs_zn_dirty(zn    
244                                 clean_freed +=    
245                         kfree(zn);                
246                         return clean_freed;       
247                 }                                 
248                                                   
249                 zn = ubifs_tnc_postorder_next(    
250         }                                         
251 }                                                 
252                                                   
253 /**                                               
254  * ubifs_destroy_tnc_tree - destroy all znodes    
255  * @c: UBIFS file-system description object       
256  *                                                
257  * This function destroys the whole TNC tree a    
258  * count.                                         
259  */                                               
260 void ubifs_destroy_tnc_tree(struct ubifs_info     
261 {                                                 
262         long n, freed;                            
263                                                   
264         if (!c->zroot.znode)                      
265                 return;                           
266                                                   
267         n = atomic_long_read(&c->clean_zn_cnt)    
268         freed = ubifs_destroy_tnc_subtree(c, c    
269         ubifs_assert(c, freed == n);              
270         atomic_long_sub(n, &ubifs_clean_zn_cnt    
271                                                   
272         c->zroot.znode = NULL;                    
273 }                                                 
274                                                   
275 /**                                               
276  * read_znode - read an indexing node from fla    
277  * @c: UBIFS file-system description object       
278  * @zzbr: the zbranch describing the node to r    
279  * @znode: znode to read to                       
280  *                                                
281  * This function reads an indexing node from t    
282  * with the read data. Returns zero in case of    
283  * code in case of failure. The read indexing     
284  * is wrong with it, this function prints comp    
285  * %-EINVAL.                                      
286  */                                               
287 static int read_znode(struct ubifs_info *c, st    
288                       struct ubifs_znode *znod    
289 {                                                 
290         int lnum = zzbr->lnum;                    
291         int offs = zzbr->offs;                    
292         int len = zzbr->len;                      
293         int i, err, type, cmp;                    
294         struct ubifs_idx_node *idx;               
295                                                   
296         idx = kmalloc(c->max_idx_node_sz, GFP_    
297         if (!idx)                                 
298                 return -ENOMEM;                   
299                                                   
300         err = ubifs_read_node(c, idx, UBIFS_ID    
301         if (err < 0) {                            
302                 kfree(idx);                       
303                 return err;                       
304         }                                         
305                                                   
306         err = ubifs_node_check_hash(c, idx, zz    
307         if (err) {                                
308                 ubifs_bad_hash(c, idx, zzbr->h    
309                 kfree(idx);                       
310                 return err;                       
311         }                                         
312                                                   
313         znode->child_cnt = le16_to_cpu(idx->ch    
314         znode->level = le16_to_cpu(idx->level)    
315                                                   
316         dbg_tnc("LEB %d:%d, level %d, %d branc    
317                 lnum, offs, znode->level, znod    
318                                                   
319         if (znode->child_cnt > c->fanout || zn    
320                 ubifs_err(c, "current fanout %    
321                           c->fanout, znode->ch    
322                 ubifs_err(c, "max levels %d, z    
323                           UBIFS_MAX_LEVELS, zn    
324                 err = 1;                          
325                 goto out_dump;                    
326         }                                         
327                                                   
328         for (i = 0; i < znode->child_cnt; i++)    
329                 struct ubifs_branch *br = ubif    
330                 struct ubifs_zbranch *zbr = &z    
331                                                   
332                 key_read(c, &br->key, &zbr->ke    
333                 zbr->lnum = le32_to_cpu(br->ln    
334                 zbr->offs = le32_to_cpu(br->of    
335                 zbr->len  = le32_to_cpu(br->le    
336                 ubifs_copy_hash(c, ubifs_branc    
337                 zbr->znode = NULL;                
338                                                   
339                 /* Validate branch */             
340                                                   
341                 if (zbr->lnum < c->main_first     
342                     zbr->lnum >= c->leb_cnt ||    
343                     zbr->offs + zbr->len > c->    
344                         ubifs_err(c, "bad bran    
345                         err = 2;                  
346                         goto out_dump;            
347                 }                                 
348                                                   
349                 switch (key_type(c, &zbr->key)    
350                 case UBIFS_INO_KEY:               
351                 case UBIFS_DATA_KEY:              
352                 case UBIFS_DENT_KEY:              
353                 case UBIFS_XENT_KEY:              
354                         break;                    
355                 default:                          
356                         ubifs_err(c, "bad key     
357                                   i, key_type(    
358                         err = 3;                  
359                         goto out_dump;            
360                 }                                 
361                                                   
362                 if (znode->level)                 
363                         continue;                 
364                                                   
365                 type = key_type(c, &zbr->key);    
366                 if (c->ranges[type].max_len ==    
367                         if (zbr->len != c->ran    
368                                 ubifs_err(c, "    
369                                           type    
370                                 ubifs_err(c, "    
371                                 err = 4;          
372                                 goto out_dump;    
373                         }                         
374                 } else if (zbr->len < c->range    
375                            zbr->len > c->range    
376                         ubifs_err(c, "bad targ    
377                                   type, zbr->l    
378                         ubifs_err(c, "have to     
379                                   c->ranges[ty    
380                                   c->ranges[ty    
381                         err = 5;                  
382                         goto out_dump;            
383                 }                                 
384         }                                         
385                                                   
386         /*                                        
387          * Ensure that the next key is greater    
388          * previous one.                          
389          */                                       
390         for (i = 0; i < znode->child_cnt - 1;     
391                 const union ubifs_key *key1, *    
392                                                   
393                 key1 = &znode->zbranch[i].key;    
394                 key2 = &znode->zbranch[i + 1].    
395                                                   
396                 cmp = keys_cmp(c, key1, key2);    
397                 if (cmp > 0) {                    
398                         ubifs_err(c, "bad key     
399                         err = 6;                  
400                         goto out_dump;            
401                 } else if (cmp == 0 && !is_has    
402                         /* These can only be k    
403                         ubifs_err(c, "keys %d     
404                                   i, i + 1);      
405                         err = 7;                  
406                         goto out_dump;            
407                 }                                 
408         }                                         
409                                                   
410         kfree(idx);                               
411         return 0;                                 
412                                                   
413 out_dump:                                         
414         ubifs_err(c, "bad indexing node at LEB    
415         ubifs_dump_node(c, idx, c->max_idx_nod    
416         kfree(idx);                               
417         return -EINVAL;                           
418 }                                                 
419                                                   
420 /**                                               
421  * ubifs_load_znode - load znode to TNC cache.    
422  * @c: UBIFS file-system description object       
423  * @zbr: znode branch                             
424  * @parent: znode's parent                        
425  * @iip: index in parent                          
426  *                                                
427  * This function loads znode pointed to by @zb    
428  * returns pointer to it in case of success an    
429  * of failure.                                    
430  */                                               
431 struct ubifs_znode *ubifs_load_znode(struct ub    
432                                      struct ub    
433                                      struct ub    
434 {                                                 
435         int err;                                  
436         struct ubifs_znode *znode;                
437                                                   
438         ubifs_assert(c, !zbr->znode);             
439         /*                                        
440          * A slab cache is not presently used     
441          * depends on the fanout which is stor    
442          */                                       
443         znode = kzalloc(c->max_znode_sz, GFP_N    
444         if (!znode)                               
445                 return ERR_PTR(-ENOMEM);          
446                                                   
447         err = read_znode(c, zbr, znode);          
448         if (err)                                  
449                 goto out;                         
450                                                   
451         atomic_long_inc(&c->clean_zn_cnt);        
452                                                   
453         /*                                        
454          * Increment the global clean znode co    
455          * global and per-FS clean znode count    
456          * short time (because we might be pre    
457          * one is only used in shrinker.          
458          */                                       
459         atomic_long_inc(&ubifs_clean_zn_cnt);     
460                                                   
461         zbr->znode = znode;                       
462         znode->parent = parent;                   
463         znode->time = ktime_get_seconds();        
464         znode->iip = iip;                         
465                                                   
466         return znode;                             
467                                                   
468 out:                                              
469         kfree(znode);                             
470         return ERR_PTR(err);                      
471 }                                                 
472                                                   
473 /**                                               
474  * ubifs_tnc_read_node - read a leaf node from    
475  * @c: UBIFS file-system description object       
476  * @zbr: key and position of the node             
477  * @node: node is returned here                   
478  *                                                
479  * This function reads a node defined by @zbr     
480  * zero in case of success or a negative error    
481  */                                               
482 int ubifs_tnc_read_node(struct ubifs_info *c,     
483                         void *node)               
484 {                                                 
485         union ubifs_key key1, *key = &zbr->key    
486         int err, type = key_type(c, key);         
487         struct ubifs_wbuf *wbuf;                  
488                                                   
489         /*                                        
490          * 'zbr' has to point to on-flash node    
491          * may even be in a write buffer, so w    
492          */                                       
493         wbuf = ubifs_get_wbuf(c, zbr->lnum);      
494         if (wbuf)                                 
495                 err = ubifs_read_node_wbuf(wbu    
496                                            zbr    
497         else                                      
498                 err = ubifs_read_node(c, node,    
499                                       zbr->off    
500                                                   
501         if (err) {                                
502                 dbg_tnck(key, "key ");            
503                 return err;                       
504         }                                         
505                                                   
506         /* Make sure the key of the read node     
507         key_read(c, node + UBIFS_KEY_OFFSET, &    
508         if (!keys_eq(c, key, &key1)) {            
509                 ubifs_err(c, "bad key in node     
510                           zbr->lnum, zbr->offs    
511                 dbg_tnck(key, "looked for key     
512                 dbg_tnck(&key1, "but found nod    
513                 ubifs_dump_node(c, node, zbr->    
514                 return -EINVAL;                   
515         }                                         
516                                                   
517         err = ubifs_node_check_hash(c, node, z    
518         if (err) {                                
519                 ubifs_bad_hash(c, node, zbr->h    
520                 return err;                       
521         }                                         
522                                                   
523         return 0;                                 
524 }                                                 
525                                                   

~ [ 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