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

TOMOYO Linux Cross Reference
Linux/fs/ext4/fsmap.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/ext4/fsmap.c (Version linux-6.12-rc7) and /fs/ext4/fsmap.c (Version linux-5.15.169)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0+                1 
  2 /*                                                
  3  * Copyright (C) 2017 Oracle.  All Rights Rese    
  4  *                                                
  5  * Author: Darrick J. Wong <darrick.wong@oracl    
  6  */                                               
  7 #include "ext4.h"                                 
  8 #include <linux/fsmap.h>                          
  9 #include "fsmap.h"                                
 10 #include "mballoc.h"                              
 11 #include <linux/sort.h>                           
 12 #include <linux/list_sort.h>                      
 13 #include <trace/events/ext4.h>                    
 14                                                   
 15 /* Convert an ext4_fsmap to an fsmap. */          
 16 void ext4_fsmap_from_internal(struct super_blo    
 17                               struct ext4_fsma    
 18 {                                                 
 19         dest->fmr_device = src->fmr_device;       
 20         dest->fmr_flags = src->fmr_flags;         
 21         dest->fmr_physical = src->fmr_physical    
 22         dest->fmr_owner = src->fmr_owner;         
 23         dest->fmr_offset = 0;                     
 24         dest->fmr_length = src->fmr_length <<     
 25         dest->fmr_reserved[0] = 0;                
 26         dest->fmr_reserved[1] = 0;                
 27         dest->fmr_reserved[2] = 0;                
 28 }                                                 
 29                                                   
 30 /* Convert an fsmap to an ext4_fsmap. */          
 31 void ext4_fsmap_to_internal(struct super_block    
 32                             struct fsmap *src)    
 33 {                                                 
 34         dest->fmr_device = src->fmr_device;       
 35         dest->fmr_flags = src->fmr_flags;         
 36         dest->fmr_physical = src->fmr_physical    
 37         dest->fmr_owner = src->fmr_owner;         
 38         dest->fmr_length = src->fmr_length >>     
 39 }                                                 
 40                                                   
 41 /* getfsmap query state */                        
 42 struct ext4_getfsmap_info {                       
 43         struct ext4_fsmap_head  *gfi_head;        
 44         ext4_fsmap_format_t     gfi_formatter;    
 45         void                    *gfi_format_ar    
 46         ext4_fsblk_t            gfi_next_fsblk    
 47         u32                     gfi_dev;          
 48         ext4_group_t            gfi_agno;         
 49         struct ext4_fsmap       gfi_low;          
 50         struct ext4_fsmap       gfi_high;         
 51         struct ext4_fsmap       gfi_lastfree;     
 52         struct list_head        gfi_meta_list;    
 53         bool                    gfi_last;         
 54 };                                                
 55                                                   
 56 /* Associate a device with a getfsmap handler.    
 57 struct ext4_getfsmap_dev {                        
 58         int                     (*gfd_fn)(stru    
 59                                       struct e    
 60                                       struct e    
 61         u32                     gfd_dev;          
 62 };                                                
 63                                                   
 64 /* Compare two getfsmap device handlers. */       
 65 static int ext4_getfsmap_dev_compare(const voi    
 66 {                                                 
 67         const struct ext4_getfsmap_dev *d1 = p    
 68         const struct ext4_getfsmap_dev *d2 = p    
 69                                                   
 70         return d1->gfd_dev - d2->gfd_dev;         
 71 }                                                 
 72                                                   
 73 /* Compare a record against our starting point    
 74 static bool ext4_getfsmap_rec_before_low_key(s    
 75                                              s    
 76 {                                                 
 77         return rec->fmr_physical < info->gfi_l    
 78 }                                                 
 79                                                   
 80 /*                                                
 81  * Format a reverse mapping for getfsmap, havi    
 82  * into the appropriate daddr units.              
 83  */                                               
 84 static int ext4_getfsmap_helper(struct super_b    
 85                                 struct ext4_ge    
 86                                 struct ext4_fs    
 87 {                                                 
 88         struct ext4_fsmap fmr;                    
 89         struct ext4_sb_info *sbi = EXT4_SB(sb)    
 90         ext4_fsblk_t rec_fsblk = rec->fmr_phys    
 91         ext4_group_t agno;                        
 92         ext4_grpblk_t cno;                        
 93         int error;                                
 94                                                   
 95         if (fatal_signal_pending(current))        
 96                 return -EINTR;                    
 97                                                   
 98         /*                                        
 99          * Filter out records that start befor    
100          * caller requested that.                 
101          */                                       
102         if (ext4_getfsmap_rec_before_low_key(i    
103                 rec_fsblk += rec->fmr_length;     
104                 if (info->gfi_next_fsblk < rec    
105                         info->gfi_next_fsblk =    
106                 return EXT4_QUERY_RANGE_CONTIN    
107         }                                         
108                                                   
109         /* Are we just counting mappings? */      
110         if (info->gfi_head->fmh_count == 0) {     
111                 if (info->gfi_head->fmh_entrie    
112                         return EXT4_QUERY_RANG    
113                                                   
114                 if (rec_fsblk > info->gfi_next    
115                         info->gfi_head->fmh_en    
116                                                   
117                 if (info->gfi_last)               
118                         return EXT4_QUERY_RANG    
119                                                   
120                 info->gfi_head->fmh_entries++;    
121                                                   
122                 rec_fsblk += rec->fmr_length;     
123                 if (info->gfi_next_fsblk < rec    
124                         info->gfi_next_fsblk =    
125                 return EXT4_QUERY_RANGE_CONTIN    
126         }                                         
127                                                   
128         /*                                        
129          * If the record starts past the last     
130          * then we've found a gap.  Report the    
131          * whatever the caller specified is th    
132          */                                       
133         if (rec_fsblk > info->gfi_next_fsblk)     
134                 if (info->gfi_head->fmh_entrie    
135                         return EXT4_QUERY_RANG    
136                                                   
137                 ext4_get_group_no_and_offset(s    
138                                 &agno, &cno);     
139                 trace_ext4_fsmap_mapping(sb, i    
140                                 EXT4_C2B(sbi,     
141                                 rec_fsblk - in    
142                                 EXT4_FMR_OWN_U    
143                                                   
144                 fmr.fmr_device = info->gfi_dev    
145                 fmr.fmr_physical = info->gfi_n    
146                 fmr.fmr_owner = EXT4_FMR_OWN_U    
147                 fmr.fmr_length = rec_fsblk - i    
148                 fmr.fmr_flags = FMR_OF_SPECIAL    
149                 error = info->gfi_formatter(&f    
150                 if (error)                        
151                         return error;             
152                 info->gfi_head->fmh_entries++;    
153         }                                         
154                                                   
155         if (info->gfi_last)                       
156                 goto out;                         
157                                                   
158         /* Fill out the extent we found */        
159         if (info->gfi_head->fmh_entries >= inf    
160                 return EXT4_QUERY_RANGE_ABORT;    
161                                                   
162         ext4_get_group_no_and_offset(sb, rec_f    
163         trace_ext4_fsmap_mapping(sb, info->gfi    
164                         rec->fmr_length, rec->    
165                                                   
166         fmr.fmr_device = info->gfi_dev;           
167         fmr.fmr_physical = rec_fsblk;             
168         fmr.fmr_owner = rec->fmr_owner;           
169         fmr.fmr_flags = FMR_OF_SPECIAL_OWNER;     
170         fmr.fmr_length = rec->fmr_length;         
171         error = info->gfi_formatter(&fmr, info    
172         if (error)                                
173                 return error;                     
174         info->gfi_head->fmh_entries++;            
175                                                   
176 out:                                              
177         rec_fsblk += rec->fmr_length;             
178         if (info->gfi_next_fsblk < rec_fsblk)     
179                 info->gfi_next_fsblk = rec_fsb    
180         return EXT4_QUERY_RANGE_CONTINUE;         
181 }                                                 
182                                                   
183 static inline ext4_fsblk_t ext4_fsmap_next_pbl    
184 {                                                 
185         return fmr->fmr_physical + fmr->fmr_le    
186 }                                                 
187                                                   
188 /* Transform a blockgroup's free record into a    
189 static int ext4_getfsmap_datadev_helper(struct    
190                                         ext4_g    
191                                         ext4_g    
192 {                                                 
193         struct ext4_fsmap irec;                   
194         struct ext4_getfsmap_info *info = priv    
195         struct ext4_fsmap *p;                     
196         struct ext4_fsmap *tmp;                   
197         struct ext4_sb_info *sbi = EXT4_SB(sb)    
198         ext4_fsblk_t fsb;                         
199         ext4_fsblk_t fslen;                       
200         int error;                                
201                                                   
202         fsb = (EXT4_C2B(sbi, start) + ext4_gro    
203         fslen = EXT4_C2B(sbi, len);               
204                                                   
205         /* If the retained free extent record     
206         if (info->gfi_lastfree.fmr_owner) {       
207                 /* ...and abuts this one, leng    
208                 if (ext4_fsmap_next_pblk(&info    
209                         info->gfi_lastfree.fmr    
210                         return 0;                 
211                 }                                 
212                                                   
213                 /*                                
214                  * There's a gap between the t    
215                  * retained extent prior to me    
216                  */                               
217                 error = ext4_getfsmap_helper(s    
218                 if (error)                        
219                         return error;             
220                 info->gfi_lastfree.fmr_owner =    
221         }                                         
222                                                   
223         /* Merge in any relevant extents from     
224         list_for_each_entry_safe(p, tmp, &info    
225                 if (p->fmr_physical + p->fmr_l    
226                         list_del(&p->fmr_list)    
227                         kfree(p);                 
228                 } else if (p->fmr_physical < f    
229                         error = ext4_getfsmap_    
230                         if (error)                
231                                 return error;     
232                                                   
233                         list_del(&p->fmr_list)    
234                         kfree(p);                 
235                 }                                 
236         }                                         
237                                                   
238         irec.fmr_device = 0;                      
239         irec.fmr_physical = fsb;                  
240         irec.fmr_length = fslen;                  
241         irec.fmr_owner = EXT4_FMR_OWN_FREE;       
242         irec.fmr_flags = 0;                       
243                                                   
244         /* If this is a free extent at the end    
245         if (ext4_fsmap_next_pblk(&irec) ==        
246                         ext4_group_first_block    
247                 info->gfi_lastfree = irec;        
248                 return 0;                         
249         }                                         
250                                                   
251         /* Otherwise, emit it */                  
252         return ext4_getfsmap_helper(sb, info,     
253 }                                                 
254                                                   
255 /* Execute a getfsmap query against the log de    
256 static int ext4_getfsmap_logdev(struct super_b    
257                                 struct ext4_ge    
258 {                                                 
259         journal_t *journal = EXT4_SB(sb)->s_jo    
260         struct ext4_fsmap irec;                   
261                                                   
262         /* Set up search keys */                  
263         info->gfi_low = keys[0];                  
264         info->gfi_low.fmr_length = 0;             
265                                                   
266         memset(&info->gfi_high, 0xFF, sizeof(i    
267                                                   
268         trace_ext4_fsmap_low_key(sb, info->gfi    
269                         info->gfi_low.fmr_phys    
270                         info->gfi_low.fmr_leng    
271                         info->gfi_low.fmr_owne    
272                                                   
273         trace_ext4_fsmap_high_key(sb, info->gf    
274                         info->gfi_high.fmr_phy    
275                         info->gfi_high.fmr_len    
276                         info->gfi_high.fmr_own    
277                                                   
278         if (keys[0].fmr_physical > 0)             
279                 return 0;                         
280                                                   
281         /* Fabricate an rmap entry for the ext    
282         irec.fmr_physical = journal->j_blk_off    
283         irec.fmr_length = journal->j_total_len    
284         irec.fmr_owner = EXT4_FMR_OWN_LOG;        
285         irec.fmr_flags = 0;                       
286                                                   
287         return ext4_getfsmap_helper(sb, info,     
288 }                                                 
289                                                   
290 /* Helper to fill out an ext4_fsmap. */           
291 static inline int ext4_getfsmap_fill(struct li    
292                                      ext4_fsbl    
293                                      uint64_t     
294 {                                                 
295         struct ext4_fsmap *fsm;                   
296                                                   
297         fsm = kmalloc(sizeof(*fsm), GFP_NOFS);    
298         if (!fsm)                                 
299                 return -ENOMEM;                   
300         fsm->fmr_device = 0;                      
301         fsm->fmr_flags = 0;                       
302         fsm->fmr_physical = fsb;                  
303         fsm->fmr_owner = owner;                   
304         fsm->fmr_length = len;                    
305         list_add_tail(&fsm->fmr_list, meta_lis    
306                                                   
307         return 0;                                 
308 }                                                 
309                                                   
310 /*                                                
311  * This function returns the number of file sy    
312  * the beginning of a block group, including t    
313  */                                               
314 static unsigned int ext4_getfsmap_find_sb(stru    
315                                           ext4    
316                                           stru    
317 {                                                 
318         struct ext4_sb_info *sbi = EXT4_SB(sb)    
319         ext4_fsblk_t fsb = ext4_group_first_bl    
320         ext4_fsblk_t len;                         
321         unsigned long first_meta_bg = le32_to_    
322         unsigned long metagroup = agno / EXT4_    
323         int error;                                
324                                                   
325         /* Record the superblock. */              
326         if (ext4_bg_has_super(sb, agno)) {        
327                 error = ext4_getfsmap_fill(met    
328                 if (error)                        
329                         return error;             
330                 fsb++;                            
331         }                                         
332                                                   
333         /* Record the group descriptors. */       
334         len = ext4_bg_num_gdb(sb, agno);          
335         if (!len)                                 
336                 return 0;                         
337         error = ext4_getfsmap_fill(meta_list,     
338                                    EXT4_FMR_OW    
339         if (error)                                
340                 return error;                     
341         fsb += len;                               
342                                                   
343         /* Reserved GDT blocks */                 
344         if (!ext4_has_feature_meta_bg(sb) || m    
345                 len = le16_to_cpu(sbi->s_es->s    
346                 error = ext4_getfsmap_fill(met    
347                                            EXT    
348                 if (error)                        
349                         return error;             
350         }                                         
351                                                   
352         return 0;                                 
353 }                                                 
354                                                   
355 /* Compare two fsmap items. */                    
356 static int ext4_getfsmap_compare(void *priv,      
357                                  const struct     
358                                  const struct     
359 {                                                 
360         struct ext4_fsmap *fa;                    
361         struct ext4_fsmap *fb;                    
362                                                   
363         fa = container_of(a, struct ext4_fsmap    
364         fb = container_of(b, struct ext4_fsmap    
365         if (fa->fmr_physical < fb->fmr_physica    
366                 return -1;                        
367         else if (fa->fmr_physical > fb->fmr_ph    
368                 return 1;                         
369         return 0;                                 
370 }                                                 
371                                                   
372 /* Merge adjacent extents of fixed metadata. *    
373 static void ext4_getfsmap_merge_fixed_metadata    
374 {                                                 
375         struct ext4_fsmap *p;                     
376         struct ext4_fsmap *prev = NULL;           
377         struct ext4_fsmap *tmp;                   
378                                                   
379         list_for_each_entry_safe(p, tmp, meta_    
380                 if (!prev) {                      
381                         prev = p;                 
382                         continue;                 
383                 }                                 
384                                                   
385                 if (prev->fmr_owner == p->fmr_    
386                     prev->fmr_physical + prev-    
387                         prev->fmr_length += p-    
388                         list_del(&p->fmr_list)    
389                         kfree(p);                 
390                 } else                            
391                         prev = p;                 
392         }                                         
393 }                                                 
394                                                   
395 /* Free a list of fixed metadata. */              
396 static void ext4_getfsmap_free_fixed_metadata(    
397 {                                                 
398         struct ext4_fsmap *p;                     
399         struct ext4_fsmap *tmp;                   
400                                                   
401         list_for_each_entry_safe(p, tmp, meta_    
402                 list_del(&p->fmr_list);           
403                 kfree(p);                         
404         }                                         
405 }                                                 
406                                                   
407 /* Find all the fixed metadata in the filesyst    
408 static int ext4_getfsmap_find_fixed_metadata(s    
409                                              s    
410 {                                                 
411         struct ext4_group_desc *gdp;              
412         ext4_group_t agno;                        
413         int error;                                
414                                                   
415         INIT_LIST_HEAD(meta_list);                
416                                                   
417         /* Collect everything. */                 
418         for (agno = 0; agno < EXT4_SB(sb)->s_g    
419                 gdp = ext4_get_group_desc(sb,     
420                 if (!gdp) {                       
421                         error = -EFSCORRUPTED;    
422                         goto err;                 
423                 }                                 
424                                                   
425                 /* Superblock & GDT */            
426                 error = ext4_getfsmap_find_sb(    
427                 if (error)                        
428                         goto err;                 
429                                                   
430                 /* Block bitmap */                
431                 error = ext4_getfsmap_fill(met    
432                                            ext    
433                                            EXT    
434                 if (error)                        
435                         goto err;                 
436                                                   
437                 /* Inode bitmap */                
438                 error = ext4_getfsmap_fill(met    
439                                            ext    
440                                            EXT    
441                 if (error)                        
442                         goto err;                 
443                                                   
444                 /* Inodes */                      
445                 error = ext4_getfsmap_fill(met    
446                                            ext    
447                                            EXT    
448                                            EXT    
449                 if (error)                        
450                         goto err;                 
451         }                                         
452                                                   
453         /* Sort the list */                       
454         list_sort(NULL, meta_list, ext4_getfsm    
455                                                   
456         /* Merge adjacent extents */              
457         ext4_getfsmap_merge_fixed_metadata(met    
458                                                   
459         return 0;                                 
460 err:                                              
461         ext4_getfsmap_free_fixed_metadata(meta    
462         return error;                             
463 }                                                 
464                                                   
465 /* Execute a getfsmap query against the buddy     
466 static int ext4_getfsmap_datadev(struct super_    
467                                  struct ext4_f    
468                                  struct ext4_g    
469 {                                                 
470         struct ext4_sb_info *sbi = EXT4_SB(sb)    
471         ext4_fsblk_t start_fsb;                   
472         ext4_fsblk_t end_fsb;                     
473         ext4_fsblk_t bofs;                        
474         ext4_fsblk_t eofs;                        
475         ext4_group_t start_ag;                    
476         ext4_group_t end_ag;                      
477         ext4_grpblk_t first_cluster;              
478         ext4_grpblk_t last_cluster;               
479         int error = 0;                            
480                                                   
481         bofs = le32_to_cpu(sbi->s_es->s_first_    
482         eofs = ext4_blocks_count(sbi->s_es);      
483         if (keys[0].fmr_physical >= eofs)         
484                 return 0;                         
485         else if (keys[0].fmr_physical < bofs)     
486                 keys[0].fmr_physical = bofs;      
487         if (keys[1].fmr_physical >= eofs)         
488                 keys[1].fmr_physical = eofs -     
489         if (keys[1].fmr_physical < keys[0].fmr    
490                 return 0;                         
491         start_fsb = keys[0].fmr_physical;         
492         end_fsb = keys[1].fmr_physical;           
493                                                   
494         /* Determine first and last group to e    
495         ext4_get_group_no_and_offset(sb, start    
496         ext4_get_group_no_and_offset(sb, end_f    
497                                                   
498         /*                                        
499          * Convert the fsmap low/high keys to     
500          * low to the fsmap low key and max ou    
501          * of the bg.                             
502          */                                       
503         info->gfi_low = keys[0];                  
504         info->gfi_low.fmr_physical = EXT4_C2B(    
505         info->gfi_low.fmr_length = 0;             
506                                                   
507         memset(&info->gfi_high, 0xFF, sizeof(i    
508                                                   
509         /* Assemble a list of all the fixed-lo    
510         error = ext4_getfsmap_find_fixed_metad    
511         if (error)                                
512                 goto err;                         
513                                                   
514         /* Query each bg */                       
515         for (info->gfi_agno = start_ag;           
516              info->gfi_agno <= end_ag;            
517              info->gfi_agno++) {                  
518                 /*                                
519                  * Set the bg high key from th    
520                  * is the last bg that we're q    
521                  */                               
522                 if (info->gfi_agno == end_ag)     
523                         info->gfi_high = keys[    
524                         info->gfi_high.fmr_phy    
525                                         last_c    
526                         info->gfi_high.fmr_len    
527                 }                                 
528                                                   
529                 trace_ext4_fsmap_low_key(sb, i    
530                                 info->gfi_low.    
531                                 info->gfi_low.    
532                                 info->gfi_low.    
533                                                   
534                 trace_ext4_fsmap_high_key(sb,     
535                                 info->gfi_high    
536                                 info->gfi_high    
537                                 info->gfi_high    
538                                                   
539                 error = ext4_mballoc_query_ran    
540                                 EXT4_B2C(sbi,     
541                                 EXT4_B2C(sbi,     
542                                 ext4_getfsmap_    
543                 if (error)                        
544                         goto err;                 
545                                                   
546                 /*                                
547                  * Set the bg low key to the s    
548                  * moving on to the next bg.      
549                  */                               
550                 if (info->gfi_agno == start_ag    
551                         memset(&info->gfi_low,    
552         }                                         
553                                                   
554         /* Do we have a retained free extent?     
555         if (info->gfi_lastfree.fmr_owner) {       
556                 error = ext4_getfsmap_helper(s    
557                 if (error)                        
558                         goto err;                 
559         }                                         
560                                                   
561         /* Report any gaps at the end of the b    
562         info->gfi_last = true;                    
563         error = ext4_getfsmap_datadev_helper(s    
564         if (error)                                
565                 goto err;                         
566                                                   
567 err:                                              
568         ext4_getfsmap_free_fixed_metadata(&inf    
569         return error;                             
570 }                                                 
571                                                   
572 /* Do we recognize the device? */                 
573 static bool ext4_getfsmap_is_valid_device(stru    
574                                           stru    
575 {                                                 
576         if (fm->fmr_device == 0 || fm->fmr_dev    
577             fm->fmr_device == new_encode_dev(s    
578                 return true;                      
579         if (EXT4_SB(sb)->s_journal_bdev_file &    
580             fm->fmr_device ==                     
581             new_encode_dev(file_bdev(EXT4_SB(s    
582                 return true;                      
583         return false;                             
584 }                                                 
585                                                   
586 /* Ensure that the low key is less than the hi    
587 static bool ext4_getfsmap_check_keys(struct ex    
588                                      struct ex    
589 {                                                 
590         if (low_key->fmr_device > high_key->fm    
591                 return false;                     
592         if (low_key->fmr_device < high_key->fm    
593                 return true;                      
594                                                   
595         if (low_key->fmr_physical > high_key->    
596                 return false;                     
597         if (low_key->fmr_physical < high_key->    
598                 return true;                      
599                                                   
600         if (low_key->fmr_owner > high_key->fmr    
601                 return false;                     
602         if (low_key->fmr_owner < high_key->fmr    
603                 return true;                      
604                                                   
605         return false;                             
606 }                                                 
607                                                   
608 #define EXT4_GETFSMAP_DEVS      2                 
609 /*                                                
610  * Get filesystem's extents as described in he    
611  * output.  Calls formatter to fill the user's    
612  * extents are mapped, until the passed-in hea    
613  * been filled, or until the formatter short-c    
614  * is tracking filled-in extents on its own.      
615  *                                                
616  * Key to Confusion                               
617  * ----------------                               
618  * There are multiple levels of keys and count    
619  * _fsmap_head.fmh_keys         -- low and hig    
620  *                                 these refle    
621  * dkeys                        -- fmh_keys us    
622  *                                 these are f    
623  *                                 bumped up b    
624  * _getfsmap_info.gfi_next_fsblk-- next fs blo    
625  *                                 is how we d    
626  *                                 records and    
627  * _getfsmap_info.gfi_low/high  -- per-bg low/    
628  *                                 dkeys; used    
629  */                                               
630 int ext4_getfsmap(struct super_block *sb, stru    
631                   ext4_fsmap_format_t formatte    
632 {                                                 
633         struct ext4_fsmap dkeys[2];     /* per    
634         struct ext4_getfsmap_dev handlers[EXT4    
635         struct ext4_getfsmap_info info = { NUL    
636         int i;                                    
637         int error = 0;                            
638                                                   
639         if (head->fmh_iflags & ~FMH_IF_VALID)     
640                 return -EINVAL;                   
641         if (!ext4_getfsmap_is_valid_device(sb,    
642             !ext4_getfsmap_is_valid_device(sb,    
643                 return -EINVAL;                   
644                                                   
645         head->fmh_entries = 0;                    
646                                                   
647         /* Set up our device handlers. */         
648         memset(handlers, 0, sizeof(handlers));    
649         handlers[0].gfd_dev = new_encode_dev(s    
650         handlers[0].gfd_fn = ext4_getfsmap_dat    
651         if (EXT4_SB(sb)->s_journal_bdev_file)     
652                 handlers[1].gfd_dev = new_enco    
653                         file_bdev(EXT4_SB(sb)-    
654                 handlers[1].gfd_fn = ext4_getf    
655         }                                         
656                                                   
657         sort(handlers, EXT4_GETFSMAP_DEVS, siz    
658                         ext4_getfsmap_dev_comp    
659                                                   
660         /*                                        
661          * To continue where we left off, we a    
662          * last mapping from a previous call a    
663          * This is identified by a non-zero le    
664          * have to increment the low key in th    
665          * don't return the same mapping again    
666          * very next mapping.                     
667          *                                        
668          * Bump the physical offset as there c    
669          * the same physical block range.         
670          */                                       
671         dkeys[0] = head->fmh_keys[0];             
672         dkeys[0].fmr_physical += dkeys[0].fmr_    
673         dkeys[0].fmr_owner = 0;                   
674         dkeys[0].fmr_length = 0;                  
675         memset(&dkeys[1], 0xFF, sizeof(struct     
676                                                   
677         if (!ext4_getfsmap_check_keys(dkeys, &    
678                 return -EINVAL;                   
679                                                   
680         info.gfi_next_fsblk = head->fmh_keys[0    
681                           head->fmh_keys[0].fm    
682         info.gfi_formatter = formatter;           
683         info.gfi_format_arg = arg;                
684         info.gfi_head = head;                     
685                                                   
686         /* For each device we support... */       
687         for (i = 0; i < EXT4_GETFSMAP_DEVS; i+    
688                 /* Is this device within the r    
689                 if (!handlers[i].gfd_fn)          
690                         continue;                 
691                 if (head->fmh_keys[0].fmr_devi    
692                         continue;                 
693                 if (head->fmh_keys[1].fmr_devi    
694                         break;                    
695                                                   
696                 /*                                
697                  * If this device number match    
698                  * to pass the high key to the    
699                  * query results.  If the devi    
700                  * low key, zero out the low k    
701                  * everything from the beginni    
702                  */                               
703                 if (handlers[i].gfd_dev == hea    
704                         dkeys[1] = head->fmh_k    
705                 if (handlers[i].gfd_dev > head    
706                         memset(&dkeys[0], 0, s    
707                                                   
708                 info.gfi_dev = handlers[i].gfd    
709                 info.gfi_last = false;            
710                 info.gfi_agno = -1;               
711                 error = handlers[i].gfd_fn(sb,    
712                 if (error)                        
713                         break;                    
714                 info.gfi_next_fsblk = 0;          
715         }                                         
716                                                   
717         head->fmh_oflags = FMH_OF_DEV_T;          
718         return error;                             
719 }                                                 
720                                                   

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